chore: 格式化代码,inula-core ut更换路径
This commit is contained in:
parent
0ac8ab0b6c
commit
6dc8d0fcfa
|
@ -140,8 +140,7 @@ class BasicGenerator extends Generator {
|
|||
if (fs.lstatSync(fullpath).isDirectory()) {
|
||||
this.traverseDirBubble(fullpath, dirCallback, fileCallback);
|
||||
dirCallback(fullpath);
|
||||
}
|
||||
else{
|
||||
} else {
|
||||
fileCallback(fullpath);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,7 +34,9 @@ function App() {
|
|||
<h2>了解更多</h2>
|
||||
<p>
|
||||
要了解 Inula,查看{' '}
|
||||
<a href="https://openinula.com/" target="_blank">Inula 官网</a>
|
||||
<a href="https://openinula.com/" target="_blank">
|
||||
Inula 官网
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -33,10 +33,12 @@ class App extends Inula.Component {
|
|||
</div>
|
||||
<div class="card animate__animated animate__zoomIn">
|
||||
<h2>了解更多</h2>
|
||||
<p>
|
||||
要了解 Inula,查看{' '}
|
||||
<a href="https://openinula.org" target="_blank">Inula 官网</a>
|
||||
</p>
|
||||
<p>
|
||||
要了解 Inula,查看{' '}
|
||||
<a href="https://openinula.org" target="_blank">
|
||||
Inula 官网
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -26,7 +26,7 @@ function App() {
|
|||
</div>
|
||||
<div className="content">
|
||||
<div className="card animate__animated animate__zoomIn">
|
||||
<ReactiveComponent/>
|
||||
<ReactiveComponent />
|
||||
</div>
|
||||
</div>
|
||||
<div class="content">
|
||||
|
@ -34,7 +34,9 @@ function App() {
|
|||
<h2>了解更多</h2>
|
||||
<p>
|
||||
要了解 Inula,查看{' '}
|
||||
<a href="https://openinula.com/" target="_blank">Inula 官网</a>
|
||||
<a href="https://openinula.com/" target="_blank">
|
||||
Inula 官网
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -27,16 +27,18 @@ class App extends Inula.Component {
|
|||
</div>
|
||||
<div className="content">
|
||||
<div className="card animate__animated animate__zoomIn">
|
||||
<ReactiveComponent/>
|
||||
<ReactiveComponent />
|
||||
</div>
|
||||
</div>
|
||||
<div class="content">
|
||||
<div class="card animate__animated animate__zoomIn">
|
||||
<h2>了解更多</h2>
|
||||
<p>
|
||||
要了解 Inula,查看{' '}
|
||||
<a href="https://openinula.org" target="_blank">Inula 官网</a>
|
||||
</p>
|
||||
<p>
|
||||
要了解 Inula,查看{' '}
|
||||
<a href="https://openinula.org" target="_blank">
|
||||
Inula 官网
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -68,10 +68,10 @@ const run = async config => {
|
|||
{
|
||||
name: 'projectName',
|
||||
message: 'Project name',
|
||||
type: 'input'
|
||||
type: 'input',
|
||||
},
|
||||
]);
|
||||
config.name = answers.projectName;
|
||||
config.name = answers.projectName;
|
||||
}
|
||||
if (!type) {
|
||||
const answers = await inquirer.prompt([
|
||||
|
|
|
@ -17,4 +17,4 @@
|
|||
|
||||
import run from '../lib/cli/cli.js';
|
||||
|
||||
run();
|
||||
run();
|
||||
|
|
|
@ -19,7 +19,6 @@ import { createServer } from 'vite';
|
|||
import { API } from '../../../types/types';
|
||||
import setupProxy from '../../../utils/setupProxy.js';
|
||||
|
||||
|
||||
export default (api: API) => {
|
||||
api.registerCommand({
|
||||
name: 'dev',
|
||||
|
@ -46,7 +45,7 @@ export default (api: API) => {
|
|||
if (api.userConfig.devBuildConfig.devProxy) {
|
||||
devServerOptions.onBeforeSetupMiddleware = (devServer: WebpackDevServer) => {
|
||||
setupProxy(devServer.app, api);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
api.applyHook({
|
||||
|
@ -58,7 +57,7 @@ export default (api: API) => {
|
|||
api.applyHook({ name: 'afterStartDevServer' });
|
||||
});
|
||||
} else {
|
||||
api.logger.error('Can\'t find config');
|
||||
api.logger.error("Can't find config");
|
||||
}
|
||||
break;
|
||||
case 'vite':
|
||||
|
@ -71,7 +70,7 @@ export default (api: API) => {
|
|||
server.printUrls();
|
||||
});
|
||||
} else {
|
||||
api.logger.error('Can\'t find config');
|
||||
api.logger.error("Can't find config");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -46,7 +46,7 @@ export default async function run() {
|
|||
initializeEnv();
|
||||
|
||||
if (command === 'version' || command === 'help') {
|
||||
process.env.INNER_COMMAND = "true"
|
||||
process.env.INNER_COMMAND = 'true';
|
||||
}
|
||||
|
||||
switch (command) {
|
||||
|
@ -63,7 +63,7 @@ export default async function run() {
|
|||
|
||||
let enableDebug: boolean = false;
|
||||
|
||||
if (process.env.DEBUG === "true") {
|
||||
if (process.env.DEBUG === 'true') {
|
||||
enableDebug = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -46,7 +46,7 @@ export default class Hub {
|
|||
userConfig: UserConfig = {};
|
||||
packageJson: PackageJSON;
|
||||
stage: ServiceStage = ServiceStage.uninitialized;
|
||||
buildConfig: {name:string, config: object}[] = [];
|
||||
buildConfig: { name: string; config: object }[] = [];
|
||||
pluginManager: Plugin;
|
||||
buildConfigPath: BuildConfig[] = [];
|
||||
devBuildConfig: object = {};
|
||||
|
@ -95,7 +95,7 @@ export default class Hub {
|
|||
this.userConfig = await this.configManager.getUserConfig();
|
||||
|
||||
// 设置编译模式
|
||||
this.setCompileMode()
|
||||
this.setCompileMode();
|
||||
|
||||
// 获取编译配置
|
||||
await this.analyzeBuildConfig();
|
||||
|
@ -135,8 +135,8 @@ export default class Hub {
|
|||
: this.pluginManager.commands[command];
|
||||
|
||||
if (commands === undefined) {
|
||||
this.logger.error(`Invalid command ${command}`)
|
||||
return
|
||||
this.logger.error(`Invalid command ${command}`);
|
||||
return;
|
||||
}
|
||||
const { fn } = commands as ICommand;
|
||||
|
||||
|
@ -164,7 +164,7 @@ export default class Hub {
|
|||
|
||||
let finalBc = {};
|
||||
if (typeof bc === 'function') {
|
||||
finalBc = bc(env)
|
||||
finalBc = bc(env);
|
||||
this.devBuildConfig = finalBc;
|
||||
return;
|
||||
}
|
||||
|
@ -175,55 +175,53 @@ export default class Hub {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (!this.userConfig.buildConfig) {
|
||||
switch (this.compileMode) {
|
||||
case 'webpack':
|
||||
this.buildConfigPath.push({name:'default', path:'./webpack.config.js'})
|
||||
this.buildConfigPath.push({ name: 'default', path: './webpack.config.js' });
|
||||
break;
|
||||
case 'vite':
|
||||
this.buildConfigPath.push({name:'default', path:'./vite.config.js'})
|
||||
this.buildConfigPath.push({ name: 'default', path: './vite.config.js' });
|
||||
break;
|
||||
default:
|
||||
this.logger.warn(`Unknown compile mode ${this.compileMode}`);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
this.userConfig.buildConfig.forEach((userBuildConfig) => {
|
||||
this.userConfig.buildConfig.forEach(userBuildConfig => {
|
||||
if (typeof userBuildConfig === 'object') {
|
||||
this.buildConfigPath.push(userBuildConfig);
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
this.buildConfigPath.forEach(async (config) => {
|
||||
let {name, path} = config;
|
||||
this.buildConfigPath.forEach(async config => {
|
||||
let { name, path } = config;
|
||||
path = isAbsolute(path) ? path : join(process.cwd(), path);
|
||||
if (!existsSync(path)) {
|
||||
this.logger.debug(`Cant't find build config. Path is ${path}`);
|
||||
return;
|
||||
}
|
||||
this.logger.debug(`Find build config. Path is ${path}`);
|
||||
let bc = await loadModule<object | Function >(path);
|
||||
let bc = await loadModule<object | Function>(path);
|
||||
if (bc == undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
let finalBc = {};
|
||||
if (typeof bc === 'function') {
|
||||
finalBc = bc(config.env)
|
||||
this.buildConfig.push({name: name, config: finalBc});
|
||||
finalBc = bc(config.env);
|
||||
this.buildConfig.push({ name: name, config: finalBc });
|
||||
return;
|
||||
}
|
||||
this.buildConfig.push({name: name, config: bc});
|
||||
})
|
||||
this.buildConfig.push({ name: name, config: bc });
|
||||
});
|
||||
}
|
||||
|
||||
getConfigName(name: string): string {
|
||||
name = name.replace('webpack.', '');
|
||||
name = name.replace('.js', '');
|
||||
name = name.replace('.ts', '');
|
||||
return name
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -135,15 +135,11 @@ export default class Plugin {
|
|||
return new Proxy(pluginAPI, {
|
||||
get: (target: PluginAPI, prop: string) => {
|
||||
if (['userConfig', 'devBuildConfig', 'buildConfig', 'compileMode', 'packageJson', 'cwd'].includes(prop)) {
|
||||
return typeof this.hub[prop] === 'function'
|
||||
? this.hub[prop].bind(this.hub)
|
||||
: this.hub[prop];
|
||||
return typeof this.hub[prop] === 'function' ? this.hub[prop].bind(this.hub) : this.hub[prop];
|
||||
}
|
||||
|
||||
if (['setStore', 'logger', 'commands'].includes(prop)) {
|
||||
return typeof this[prop] === 'function'
|
||||
? this[prop].bind(this)
|
||||
: this[prop];
|
||||
return typeof this[prop] === 'function' ? this[prop].bind(this) : this[prop];
|
||||
}
|
||||
|
||||
return target[prop];
|
||||
|
|
|
@ -59,7 +59,7 @@ export default class PluginAPI {
|
|||
this.manager.registerFunction.push(fn);
|
||||
}
|
||||
|
||||
async applyHook(name: string, args?: any ) {
|
||||
async applyHook(name: string, args?: any) {
|
||||
const hooks: IHook[] = this.manager.hooks[name] || [];
|
||||
let config: any = undefined;
|
||||
for (const hook of hooks) {
|
||||
|
|
|
@ -19,11 +19,8 @@ import { Logger } from '../utils/logger.js';
|
|||
import type * as http from 'http';
|
||||
import type * as express from 'express';
|
||||
|
||||
|
||||
interface Request extends express.Request {
|
||||
}
|
||||
interface Response extends express.Response {
|
||||
}
|
||||
interface Request extends express.Request {}
|
||||
interface Response extends express.Response {}
|
||||
|
||||
export interface IDep {
|
||||
[name: string]: string;
|
||||
|
@ -98,7 +95,7 @@ export interface API {
|
|||
};
|
||||
registerMethod: {
|
||||
(method: Function): void;
|
||||
}
|
||||
};
|
||||
applyHook: {
|
||||
(opts: applyHookConfig): void;
|
||||
};
|
||||
|
@ -143,7 +140,7 @@ export interface DevBuildConfig {
|
|||
|
||||
export interface DevProxy {
|
||||
target: string;
|
||||
matcher: ((pathname: string, req: Request) => boolean);
|
||||
matcher: (pathname: string, req: Request) => boolean;
|
||||
onProxyRes: (proxyRes: http.IncomingMessage, req: Request, res: Response) => void;
|
||||
}
|
||||
|
||||
|
|
|
@ -52,7 +52,7 @@ const buildConfig = async (fileName: string, format: 'esm' | 'cjs' = 'esm'): Pro
|
|||
|
||||
return {
|
||||
loader: args.path.endsWith('.ts') ? 'ts' : 'js',
|
||||
contents: contents
|
||||
contents: contents,
|
||||
};
|
||||
});
|
||||
},
|
||||
|
|
|
@ -27,7 +27,6 @@ export async function loadModule<T>(filePath: string): Promise<T | undefined> {
|
|||
const isTsFile: boolean = filePath.endsWith('ts');
|
||||
const isJsFile: boolean = filePath.endsWith('js');
|
||||
|
||||
|
||||
let content: T | undefined;
|
||||
|
||||
// js文件,可以直接通过import引用
|
||||
|
|
|
@ -15,8 +15,8 @@
|
|||
|
||||
export enum LogLevel {
|
||||
DEBUG = 0,
|
||||
INFO = 1,
|
||||
WARN = 2,
|
||||
INFO = 1,
|
||||
WARN = 2,
|
||||
ERROR = 3,
|
||||
}
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
import chokidar from 'chokidar';
|
||||
import bodyParser from 'body-parser';
|
||||
import {globSync} from 'glob';
|
||||
import { globSync } from 'glob';
|
||||
import { join } from 'path';
|
||||
|
||||
import { createRequire } from 'module';
|
||||
|
@ -93,8 +93,8 @@ function generateRoutes(app: any) {
|
|||
respond instanceof Function
|
||||
? respond
|
||||
: (_req: any, res: { send: (arg0: any) => void }) => {
|
||||
res.send(respond);
|
||||
}
|
||||
res.send(respond);
|
||||
}
|
||||
);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
|
|
|
@ -17,12 +17,14 @@ import { createProxyMiddleware } from 'http-proxy-middleware';
|
|||
import { API } from '../types/types';
|
||||
|
||||
export default (app: any, api: API) => {
|
||||
const { devProxy } = api.userConfig.devBuildConfig;
|
||||
app.use(createProxyMiddleware(devProxy.matcher, {
|
||||
target: devProxy.target,
|
||||
secure: false,
|
||||
changeOrigin: true,
|
||||
ws: false,
|
||||
onProxyRes: devProxy.onProxyRes
|
||||
}));
|
||||
}
|
||||
const { devProxy } = api.userConfig.devBuildConfig;
|
||||
app.use(
|
||||
createProxyMiddleware(devProxy.matcher, {
|
||||
target: devProxy.target,
|
||||
secure: false,
|
||||
changeOrigin: true,
|
||||
ws: false,
|
||||
onProxyRes: devProxy.onProxyRes,
|
||||
})
|
||||
);
|
||||
};
|
||||
|
|
|
@ -17,7 +17,7 @@ import { dirname } from 'path';
|
|||
import { readFileSync, writeFileSync } from 'fs';
|
||||
import resolve from 'resolve';
|
||||
// @ts-ignore
|
||||
import crequire from 'crequire'
|
||||
import crequire from 'crequire';
|
||||
import { createRequire } from 'module';
|
||||
const require = createRequire(import.meta.url);
|
||||
|
||||
|
|
|
@ -17,9 +17,7 @@ module.exports = api => {
|
|||
const isTest = api.env('test');
|
||||
console.log('isTest', isTest);
|
||||
|
||||
const plugins = [
|
||||
['@babel/plugin-proposal-class-properties', { loose: false }],
|
||||
];
|
||||
const plugins = [['@babel/plugin-proposal-class-properties', { loose: false }]];
|
||||
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
plugins.push(['@babel/plugin-transform-react-jsx-source']);
|
||||
|
@ -30,11 +28,13 @@ module.exports = api => {
|
|||
'@babel/preset-env',
|
||||
'@babel/preset-typescript',
|
||||
[
|
||||
'@babel/preset-react', {
|
||||
runtime: 'classic',
|
||||
'pragma': 'Inula.createElement',
|
||||
'pragmaFrag': 'Inula.Fragment',
|
||||
}]
|
||||
'@babel/preset-react',
|
||||
{
|
||||
runtime: 'classic',
|
||||
pragma: 'Inula.createElement',
|
||||
pragmaFrag: 'Inula.Fragment',
|
||||
},
|
||||
],
|
||||
],
|
||||
plugins,
|
||||
};
|
||||
|
|
|
@ -14,6 +14,6 @@
|
|||
*/
|
||||
|
||||
declare module '*.less' {
|
||||
const resource: {[key: string]: string};
|
||||
const resource: { [key: string]: string };
|
||||
export = resource;
|
||||
}
|
||||
|
|
|
@ -13,9 +13,9 @@
|
|||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
import { checkMessage, packagePayload, changeSource } from "../utils/transferUtils";
|
||||
import { RequestAllVNodeTreeInfos, InitDevToolPageConnection, DevToolBackground } from "../utils/constants";
|
||||
import { DevToolPanel, DevToolContentScript } from "../utils/constants";
|
||||
import { checkMessage, packagePayload, changeSource } from '../utils/transferUtils';
|
||||
import { RequestAllVNodeTreeInfos, InitDevToolPageConnection, DevToolBackground } from '../utils/constants';
|
||||
import { DevToolPanel, DevToolContentScript } from '../utils/constants';
|
||||
|
||||
// 多个页面 tab 页共享一个 background,需要建立连接池,给每个 tab 建立连接
|
||||
export const connections = {};
|
||||
|
|
|
@ -47,7 +47,7 @@ function requestObservedComponents(tabId) {
|
|||
packagePayload(
|
||||
{
|
||||
type: 'inulax request observed components',
|
||||
data: {}
|
||||
data: {},
|
||||
},
|
||||
'dev tool background'
|
||||
)
|
||||
|
@ -65,7 +65,7 @@ function executeAction(tabId, storeId, action, params) {
|
|||
action,
|
||||
storeId,
|
||||
params,
|
||||
}
|
||||
},
|
||||
},
|
||||
'dev tool background'
|
||||
)
|
||||
|
@ -82,7 +82,7 @@ function queueAction(tabId, storeId, action, params) {
|
|||
action,
|
||||
storeId,
|
||||
params,
|
||||
}
|
||||
},
|
||||
},
|
||||
'sev tool background'
|
||||
)
|
||||
|
@ -167,12 +167,13 @@ chrome.runtime.onMessage.addListener(function (message, sender) {
|
|||
type: 'INULA_DEV_TOOLS',
|
||||
payload: {
|
||||
type: 'inulax stores',
|
||||
stores: storesPerTab[tabId]?.map(store => {
|
||||
// 连接被监测的组件
|
||||
requestObservedComponents(tabId);
|
||||
const observedComponents = getObservedComponents(store, tabId);
|
||||
return { ...store, observedComponents };
|
||||
}) || [],
|
||||
stores:
|
||||
storesPerTab[tabId]?.map(store => {
|
||||
// 连接被监测的组件
|
||||
requestObservedComponents(tabId);
|
||||
const observedComponents = getObservedComponents(store, tabId);
|
||||
return { ...store, observedComponents };
|
||||
}) || [],
|
||||
newStore: message.payload.data.store.id,
|
||||
},
|
||||
from: DevToolBackground,
|
||||
|
@ -184,11 +185,12 @@ chrome.runtime.onMessage.addListener(function (message, sender) {
|
|||
type: 'INULA_DEV_TOOLS',
|
||||
payload: {
|
||||
type: 'inulax stores',
|
||||
stores: storesPerTab[sender.tab.id]?.map(store => {
|
||||
// 连接被监测的组件
|
||||
const observedComponents = getObservedComponents(store, sender.tab?.id);
|
||||
return { ...store, observedComponents };
|
||||
}) || [],
|
||||
stores:
|
||||
storesPerTab[sender.tab.id]?.map(store => {
|
||||
// 连接被监测的组件
|
||||
const observedComponents = getObservedComponents(store, sender.tab?.id);
|
||||
return { ...store, observedComponents };
|
||||
}) || [],
|
||||
updated: message.payload.data.store.id,
|
||||
},
|
||||
from: DevToolBackground,
|
||||
|
@ -200,30 +202,17 @@ chrome.runtime.onMessage.addListener(function (message, sender) {
|
|||
if (message.from === DevToolPanel) {
|
||||
// panel -> inulaXHandler
|
||||
if (message.payload.type === 'inulax run action') {
|
||||
executeAction(
|
||||
message.payload.tabId,
|
||||
message.payload.storeId,
|
||||
message.payload.action,
|
||||
message.payload.args
|
||||
);
|
||||
executeAction(message.payload.tabId, message.payload.storeId, message.payload.action, message.payload.args);
|
||||
return;
|
||||
}
|
||||
|
||||
if (message.payload.type === 'inulax change state') {
|
||||
chrome.tabs.sendMessage(
|
||||
message.payload.tabId,
|
||||
packagePayload(message.payload, 'dev tool background')
|
||||
);
|
||||
chrome.tabs.sendMessage(message.payload.tabId, packagePayload(message.payload, 'dev tool background'));
|
||||
return;
|
||||
}
|
||||
|
||||
if (message.payload.type === 'inulax queue action') {
|
||||
queueAction(
|
||||
message.payload.tabId,
|
||||
message.payload.storeId,
|
||||
message.payload.action,
|
||||
message.payload.args
|
||||
);
|
||||
queueAction(message.payload.tabId, message.payload.storeId, message.payload.action, message.payload.args);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -240,7 +229,7 @@ chrome.runtime.onMessage.addListener(function (message, sender) {
|
|||
return;
|
||||
}
|
||||
|
||||
if (message.payload.type === 'inula setPersistent'){
|
||||
if (message.payload.type === 'inula setPersistent') {
|
||||
const { tabId, persistent } = message.payload;
|
||||
eventPersistencePerTab[tabId] = persistent;
|
||||
return;
|
||||
|
@ -278,14 +267,12 @@ chrome.runtime.onMessage.addListener(function (message, sender) {
|
|||
type: 'INULA_DEV_TOOLS',
|
||||
payload: {
|
||||
type: 'inulax stores',
|
||||
stores: storesPerTab[message.payload.tabId]?.map(store => {
|
||||
requestObservedComponents(message.payload.tabId);
|
||||
const observedComponents = getObservedComponents(
|
||||
store.id,
|
||||
message.payload.tabId
|
||||
);
|
||||
return { ...store, observedComponents };
|
||||
}) || [],
|
||||
stores:
|
||||
storesPerTab[message.payload.tabId]?.map(store => {
|
||||
requestObservedComponents(message.payload.tabId);
|
||||
const observedComponents = getObservedComponents(store.id, message.payload.tabId);
|
||||
return { ...store, observedComponents };
|
||||
}) || [],
|
||||
},
|
||||
from: DevToolBackground,
|
||||
});
|
||||
|
|
|
@ -47,7 +47,7 @@ const ComponentAttr = memo(function ComponentAttr({
|
|||
attrs,
|
||||
id,
|
||||
dropdownRef,
|
||||
}: {
|
||||
}: {
|
||||
attrsName: string;
|
||||
attrsType: string;
|
||||
attrs: IAttr[];
|
||||
|
@ -421,7 +421,12 @@ function ComponentInfo({ name, attrs, parents, id, source, onClickParent }: ICom
|
|||
<b>Copy value to console</b>
|
||||
</li>
|
||||
<li
|
||||
onClick={() => storeVariable((dropdownRef.current as any).attrInfo.attrsName, (dropdownRef.current as any).attrInfo.path)}
|
||||
onClick={() =>
|
||||
storeVariable(
|
||||
(dropdownRef.current as any).attrInfo.attrsName,
|
||||
(dropdownRef.current as any).attrInfo.path
|
||||
)
|
||||
}
|
||||
>
|
||||
<b>Store as global variable</b>
|
||||
</li>
|
||||
|
|
|
@ -38,7 +38,7 @@ export default function Search(props: SearchProps) {
|
|||
onchange={handleChange}
|
||||
className={styles.search}
|
||||
value={value}
|
||||
placeholder='Search Component'
|
||||
placeholder="Search Component"
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ export function SizeObserver(props) {
|
|||
const { children, ...rest } = props;
|
||||
const containerRef = useRef<HTMLDivElement>();
|
||||
const [size, setSize] = useState<{ width: number; height: number }>();
|
||||
const notifyChild = (element) => {
|
||||
const notifyChild = element => {
|
||||
setSize({
|
||||
width: element.offsetWidth,
|
||||
height: element.offsetHeight,
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
* 确保继续渲染项在新渲染数组中的位置和旧渲染数组中的位置不发生改变
|
||||
*/
|
||||
export default class ItemMap<T> {
|
||||
|
||||
// 不要用 indexOf 进行位置计算,它会遍历数组
|
||||
private lastRenderItemToIndexMap: Map<T | undefined, number>;
|
||||
|
||||
|
@ -26,7 +25,7 @@ export default class ItemMap<T> {
|
|||
this.lastRenderItemToIndexMap = new Map();
|
||||
}
|
||||
|
||||
public calculateReSortedItems(nextItems: T[]): (T|undefined)[] {
|
||||
public calculateReSortedItems(nextItems: T[]): (T | undefined)[] {
|
||||
if (this.lastRenderItemToIndexMap.size === 0) {
|
||||
nextItems.forEach((item, index) => {
|
||||
this.lastRenderItemToIndexMap.set(item, index);
|
||||
|
|
|
@ -36,13 +36,13 @@ interface IProps<T extends { id: number | string }> {
|
|||
|
||||
export type RenderInfoType<T> = {
|
||||
visibleItems: T[];
|
||||
}
|
||||
};
|
||||
|
||||
function parseTranslate<T>(data: T[], itemHeight: number) {
|
||||
const map = new Map<T, number>();
|
||||
data.forEach((item, index) => {
|
||||
map.set(item, index * itemHeight);
|
||||
})
|
||||
});
|
||||
return map;
|
||||
}
|
||||
|
||||
|
@ -121,7 +121,7 @@ export function VList<T extends { id: number | string }>(props: IProps<T>) {
|
|||
className={styles.item}
|
||||
style={{ transform: `translateY(${itemToTranslateYMap.get(item)}px)` }}
|
||||
>
|
||||
{children(item,indentationLength)}
|
||||
{children(item, indentationLength)}
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
|
|
@ -152,7 +152,7 @@ function Item(props: IItem) {
|
|||
return (
|
||||
<div {...itemAttr}>
|
||||
<div
|
||||
style={{marginLeft: indentation * indentationLength}}
|
||||
style={{ marginLeft: indentation * indentationLength }}
|
||||
className={styles.treeIcon}
|
||||
onclick={handleClickCollapse}
|
||||
>
|
||||
|
@ -182,15 +182,7 @@ function VTree(props: {
|
|||
selectItem: IData;
|
||||
onSelectItem: (item: IData) => void;
|
||||
}) {
|
||||
const {
|
||||
data,
|
||||
maxDeep,
|
||||
highlightValue,
|
||||
scrollToItem,
|
||||
onRendered,
|
||||
onCollapseNode,
|
||||
onSelectItem
|
||||
} = props;
|
||||
const { data, maxDeep, highlightValue, scrollToItem, onRendered, onCollapseNode, onSelectItem } = props;
|
||||
const [collapseNode, setCollapseNode] = useState(props.collapsedNodes || []);
|
||||
const [selectItem, setSelectItem] = useState(props.selectItem);
|
||||
const [childItems, setChildItems] = useState<Array<IData>>([]);
|
||||
|
@ -251,12 +243,9 @@ function VTree(props: {
|
|||
[onSelectItem]
|
||||
);
|
||||
|
||||
const handleMouseEnterItem = useCallback(
|
||||
item => {
|
||||
postMessageToBackground(Highlight, item);
|
||||
},
|
||||
null
|
||||
);
|
||||
const handleMouseEnterItem = useCallback(item => {
|
||||
postMessageToBackground(Highlight, item);
|
||||
}, null);
|
||||
|
||||
const handleMouseLeaveItem = () => {
|
||||
postMessageToBackground(RemoveHighlight);
|
||||
|
|
|
@ -20,7 +20,7 @@ const overlayStyles = {
|
|||
background: 'rgba(120, 170, 210, 0.7)',
|
||||
padding: 'rgba(77, 200, 0, 0.3)',
|
||||
margin: 'rgba(255, 155, 0, 0.3)',
|
||||
border: 'rgba(255, 200, 50, 0.3)'
|
||||
border: 'rgba(255, 200, 50, 0.3)',
|
||||
};
|
||||
|
||||
type Rect = {
|
||||
|
@ -58,7 +58,7 @@ function getOwnerIframe(node: Element): Element | null {
|
|||
|
||||
function getElementStyle(domElement: Element) {
|
||||
const style = window.getComputedStyle(domElement);
|
||||
return{
|
||||
return {
|
||||
marginLeft: parseInt(style.marginLeft, 10),
|
||||
marginRight: parseInt(style.marginRight, 10),
|
||||
marginTop: parseInt(style.marginTop, 10),
|
||||
|
@ -70,7 +70,7 @@ function getElementStyle(domElement: Element) {
|
|||
paddingLeft: parseInt(style.paddingLeft, 10),
|
||||
paddingRight: parseInt(style.paddingRight, 10),
|
||||
paddingTop: parseInt(style.paddingTop, 10),
|
||||
paddingBottom: parseInt(style.paddingBottom, 10)
|
||||
paddingBottom: parseInt(style.paddingBottom, 10),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -86,7 +86,7 @@ function mergeRectOffsets(rects: Array<Rect>): Rect {
|
|||
width: previousRect.width + rect.width,
|
||||
height: previousRect.height + rect.height,
|
||||
bottom: previousRect.bottom + rect.bottom,
|
||||
right: previousRect.right + rect.right
|
||||
right: previousRect.right + rect.right,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
@ -99,18 +99,15 @@ function getBoundingClientRectWithBorderOffset(node: Element) {
|
|||
top: dimensions.borderTop,
|
||||
left: dimensions.borderLeft,
|
||||
bottom: dimensions.borderBottom,
|
||||
right:dimensions.borderRight,
|
||||
right: dimensions.borderRight,
|
||||
// 高度和宽度不会被使用
|
||||
width: 0,
|
||||
height: 0
|
||||
}
|
||||
height: 0,
|
||||
},
|
||||
]);
|
||||
}
|
||||
|
||||
function getNestedBoundingClientRect(
|
||||
node: HTMLElement,
|
||||
boundaryWindow
|
||||
): Rect {
|
||||
function getNestedBoundingClientRect(node: HTMLElement, boundaryWindow): Rect {
|
||||
const ownerIframe = getOwnerIframe(node);
|
||||
if (ownerIframe && ownerIframe !== boundaryWindow) {
|
||||
const rects = [node.getBoundingClientRect()] as Rect[];
|
||||
|
@ -125,7 +122,7 @@ function getNestedBoundingClientRect(
|
|||
break;
|
||||
}
|
||||
|
||||
if (currentIframe &&getOwnerWindow(currentIframe) === boundaryWindow) {
|
||||
if (currentIframe && getOwnerWindow(currentIframe) === boundaryWindow) {
|
||||
onlyOneMore = true;
|
||||
}
|
||||
}
|
||||
|
@ -156,7 +153,7 @@ class OverlayRect {
|
|||
assign(this.node.style, {
|
||||
borderColor: overlayStyles.margin,
|
||||
pointerEvents: 'none',
|
||||
position: 'fixed'
|
||||
position: 'fixed',
|
||||
});
|
||||
|
||||
this.node.style.zIndex = '10000000';
|
||||
|
@ -179,13 +176,25 @@ class OverlayRect {
|
|||
setBoxStyle(eleStyle, 'padding', this.padding);
|
||||
|
||||
assign(this.content.style, {
|
||||
height: boxRect.height - eleStyle.borderTop - eleStyle.borderBottom - eleStyle.paddingTop - eleStyle.paddingBottom + 'px',
|
||||
width: boxRect.width - eleStyle.borderLeft - eleStyle.borderRight - eleStyle.paddingLeft - eleStyle.paddingRight + 'px'
|
||||
height:
|
||||
boxRect.height -
|
||||
eleStyle.borderTop -
|
||||
eleStyle.borderBottom -
|
||||
eleStyle.paddingTop -
|
||||
eleStyle.paddingBottom +
|
||||
'px',
|
||||
width:
|
||||
boxRect.width -
|
||||
eleStyle.borderLeft -
|
||||
eleStyle.borderRight -
|
||||
eleStyle.paddingLeft -
|
||||
eleStyle.paddingRight +
|
||||
'px',
|
||||
});
|
||||
|
||||
assign(this.node.style, {
|
||||
top: boxRect.top - eleStyle.marginTop + 'px',
|
||||
left: boxRect.left - eleStyle.marginLeft + 'px'
|
||||
left: boxRect.left - eleStyle.marginLeft + 'px',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -235,7 +244,7 @@ class ElementOverlay {
|
|||
top: Number.POSITIVE_INFINITY,
|
||||
right: Number.NEGATIVE_INFINITY,
|
||||
bottom: Number.NEGATIVE_INFINITY,
|
||||
left: Number.POSITIVE_INFINITY
|
||||
left: Number.POSITIVE_INFINITY,
|
||||
};
|
||||
|
||||
elements.forEach((element, index) => {
|
||||
|
|
|
@ -44,7 +44,7 @@ import {
|
|||
ClassComponent,
|
||||
IncompleteClassComponent,
|
||||
ForwardRef,
|
||||
MemoComponent
|
||||
MemoComponent,
|
||||
} from '../../../inula/src/renderer/vnode/VNodeTags';
|
||||
import { pickElement } from './pickElement';
|
||||
|
||||
|
@ -101,11 +101,7 @@ function parseCompAttrs(id: number) {
|
|||
function calculateNextValue(editValue, value, attrPath) {
|
||||
let nextState;
|
||||
const editValueType = typeof editValue;
|
||||
if (
|
||||
editValueType === 'string' ||
|
||||
editValueType === 'undefined' ||
|
||||
editValueType === 'boolean'
|
||||
) {
|
||||
if (editValueType === 'string' || editValueType === 'undefined' || editValueType === 'boolean') {
|
||||
nextState = value;
|
||||
} else if (editValueType === 'number') {
|
||||
const numValue = Number(value);
|
||||
|
@ -125,10 +121,7 @@ function calculateNextValue(editValue, value, attrPath) {
|
|||
nextState = newValue;
|
||||
}
|
||||
} else {
|
||||
console.error(
|
||||
'The dev tools tried to edit a non-editable value, this is a bug, please report.',
|
||||
editValue
|
||||
);
|
||||
console.error('The dev tools tried to edit a non-editable value, this is a bug, please report.', editValue);
|
||||
}
|
||||
return nextState;
|
||||
}
|
||||
|
@ -153,10 +146,7 @@ function modifyVNodeAttrs(data) {
|
|||
const nextState = calculateNextValue(editValue, value, path.slice(1));
|
||||
helper.updateHooks(vNode, path[0], nextState);
|
||||
} else {
|
||||
console.error(
|
||||
'The dev tools tried to edit a non-editable hook, this is a bug, please report.',
|
||||
hooks
|
||||
);
|
||||
console.error('The dev tools tried to edit a non-editable hook, this is a bug, please report.', hooks);
|
||||
}
|
||||
} else if (type === ModifyState) {
|
||||
const oldState = vNode.state || {};
|
||||
|
@ -190,11 +180,7 @@ function logComponentData(id: number) {
|
|||
* @param {Array<string | number>} path 路径
|
||||
* @param {string} attrsName 值的类型(props 或者 hooks)
|
||||
*/
|
||||
const getValueByPath = (
|
||||
vNode: VNode,
|
||||
path: Array<string | number>,
|
||||
attrsName: string
|
||||
) => {
|
||||
const getValueByPath = (vNode: VNode, path: Array<string | number>, attrsName: string) => {
|
||||
if (attrsName === 'Props') {
|
||||
return path.reduce((previousValue, currentValue) => {
|
||||
return previousValue[currentValue];
|
||||
|
@ -218,12 +204,7 @@ const getValueByPath = (
|
|||
* @param {Array<string | number>} path 值的路径
|
||||
* @param {string} attrsName 值的类型
|
||||
*/
|
||||
function logDataWithPath(
|
||||
id: number,
|
||||
itemName: string,
|
||||
path: Array<string | number>,
|
||||
attrsName: string
|
||||
) {
|
||||
function logDataWithPath(id: number, itemName: string, path: Array<string | number>, attrsName: string) {
|
||||
const vNode = queryVNode(id);
|
||||
if (vNode === null) {
|
||||
console.warn(`Could not find vNode with id "${id}"`);
|
||||
|
@ -246,11 +227,7 @@ function logDataWithPath(
|
|||
* @param {Array<string |number>} path 值的路径
|
||||
* @param {string} attrsName 值的类型
|
||||
*/
|
||||
function storeDataWithPath(
|
||||
id: number,
|
||||
path: Array<string | number>,
|
||||
attrsName: string
|
||||
) {
|
||||
function storeDataWithPath(id: number, path: Array<string | number>, attrsName: string) {
|
||||
const vNode = queryVNode(id);
|
||||
if (vNode === null) {
|
||||
console.warn(`Could not find vNode with id "${id}"`);
|
||||
|
@ -284,9 +261,7 @@ export function getElement(travelVNodeTree, treeRoot: VNode) {
|
|||
}
|
||||
}
|
||||
},
|
||||
(node: VNode) =>
|
||||
node.realNode != null &&
|
||||
(Object.keys(node.realNode).length > 0 || node.realNode.size > 0)
|
||||
(node: VNode) => node.realNode != null && (Object.keys(node.realNode).length > 0 || node.realNode.size > 0)
|
||||
);
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -56,46 +56,33 @@ const inspectVNode = () => {
|
|||
|
||||
let currentPanel = null;
|
||||
|
||||
chrome.devtools.inspectedWindow.eval(
|
||||
'window.__INULA_DEV_HOOK__',
|
||||
function (isInula, error) {
|
||||
if (!isInula || panelCreated) {
|
||||
return;
|
||||
}
|
||||
|
||||
panelCreated = true;
|
||||
chrome.devtools.panels.create(
|
||||
'Inula',
|
||||
'',
|
||||
'panel.html',
|
||||
(extensionPanel) => {
|
||||
extensionPanel.onShown.addListener((panel) => {
|
||||
if (currentPanel === panel) {
|
||||
return;
|
||||
}
|
||||
currentPanel = panel;
|
||||
const container = panel.document.getElementById('root');
|
||||
const element = createElement(Panel, { viewSource, inspectVNode });
|
||||
render(element, container);
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
chrome.devtools.panels.create(
|
||||
'InulaX',
|
||||
'',
|
||||
'panelX.html',
|
||||
(extensionPanel) => {
|
||||
extensionPanel.onShown.addListener((panel) => {
|
||||
if (currentPanel === panel) {
|
||||
return;
|
||||
}
|
||||
currentPanel = panel;
|
||||
const container = panel.document.getElementById('root');
|
||||
const element = createElement(PanelX, {});
|
||||
render(element, container);
|
||||
});
|
||||
}
|
||||
);
|
||||
chrome.devtools.inspectedWindow.eval('window.__INULA_DEV_HOOK__', function (isInula, error) {
|
||||
if (!isInula || panelCreated) {
|
||||
return;
|
||||
}
|
||||
);
|
||||
|
||||
panelCreated = true;
|
||||
chrome.devtools.panels.create('Inula', '', 'panel.html', extensionPanel => {
|
||||
extensionPanel.onShown.addListener(panel => {
|
||||
if (currentPanel === panel) {
|
||||
return;
|
||||
}
|
||||
currentPanel = panel;
|
||||
const container = panel.document.getElementById('root');
|
||||
const element = createElement(Panel, { viewSource, inspectVNode });
|
||||
render(element, container);
|
||||
});
|
||||
});
|
||||
|
||||
chrome.devtools.panels.create('InulaX', '', 'panelX.html', extensionPanel => {
|
||||
extensionPanel.onShown.addListener(panel => {
|
||||
if (currentPanel === panel) {
|
||||
return;
|
||||
}
|
||||
currentPanel = panel;
|
||||
const container = panel.document.getElementById('root');
|
||||
const element = createElement(PanelX, {});
|
||||
render(element, container);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -13,15 +13,7 @@
|
|||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
import {
|
||||
useState,
|
||||
useEffect,
|
||||
useRef,
|
||||
memo,
|
||||
useMemo,
|
||||
useCallback,
|
||||
useReducer,
|
||||
} from 'openinula';
|
||||
import { useState, useEffect, useRef, memo, useMemo, useCallback, useReducer } from 'openinula';
|
||||
import VTree, { IData } from '../components/VTree';
|
||||
import Search from '../components/Search';
|
||||
import ComponentInfo from '../components/ComponentInfo';
|
||||
|
@ -134,26 +126,20 @@ interface IIdToNodeMap {
|
|||
* @param {null | HTMLElement} resizeElement 要改变宽度的页面元素
|
||||
* @param {number} percentage 宽度占比
|
||||
*/
|
||||
const setResizePCTForElement = (
|
||||
resizeElement: null | HTMLElement,
|
||||
percentage: number
|
||||
): void => {
|
||||
const setResizePCTForElement = (resizeElement: null | HTMLElement, percentage: number): void => {
|
||||
if (resizeElement !== null) {
|
||||
resizeElement.style.setProperty(
|
||||
'--horizontal-percentage',
|
||||
`${percentage}`
|
||||
);
|
||||
resizeElement.style.setProperty('--horizontal-percentage', `${percentage}`);
|
||||
}
|
||||
};
|
||||
|
||||
function resizeReducer(state: ResizeState, action: ResizeAction): ResizeState {
|
||||
switch (action.type) {
|
||||
case "START_RESIZE":
|
||||
case 'START_RESIZE':
|
||||
return {
|
||||
...state,
|
||||
isResizing: action.payload,
|
||||
};
|
||||
case "SET_HORIZONTAL_PERCENTAGE":
|
||||
case 'SET_HORIZONTAL_PERCENTAGE':
|
||||
return {
|
||||
...state,
|
||||
horizontalPercentage: action.payload,
|
||||
|
@ -183,11 +169,7 @@ function Panel({ viewSource, inspectVNode }) {
|
|||
const [isPicking, setPicking] = useState(false);
|
||||
const [source, setSource] = useState<Source>(null);
|
||||
const idToTreeNodeMapref = useRef<IIdToNodeMap>({});
|
||||
const [state, dispatch] = useReducer(
|
||||
resizeReducer,
|
||||
null,
|
||||
initResizeState
|
||||
);
|
||||
const [state, dispatch] = useReducer(resizeReducer, null, initResizeState);
|
||||
const pageRef = useRef<null | HTMLElement>(null);
|
||||
const treeRef = useRef<null | HTMLElement>(null);
|
||||
|
||||
|
@ -214,16 +196,12 @@ function Panel({ viewSource, inspectVNode }) {
|
|||
// 对象数据只是记录了引用,内容可能在后续被修改,打印字符串可以获取当前真正内容,不被后续修改影响
|
||||
logger.info(JSON.stringify(payload));
|
||||
if (payload) {
|
||||
const {type, data} = payload;
|
||||
const { type, data } = payload;
|
||||
if (type === AllVNodeTreeInfos) {
|
||||
const idToTreeNodeMap = idToTreeNodeMapref.current;
|
||||
const nextIdToTreeNodeMap: IIdToNodeMap = {};
|
||||
const allTreeData = data.reduce((pre, current) => {
|
||||
const parsedTreeData = parseVNodeData(
|
||||
current,
|
||||
idToTreeNodeMap,
|
||||
nextIdToTreeNodeMap
|
||||
);
|
||||
const parsedTreeData = parseVNodeData(current, idToTreeNodeMap, nextIdToTreeNodeMap);
|
||||
return pre.concat(parsedTreeData);
|
||||
}, []);
|
||||
idToTreeNodeMapref.current = nextIdToTreeNodeMap;
|
||||
|
@ -284,10 +262,7 @@ function Panel({ viewSource, inspectVNode }) {
|
|||
setShowItems(info.visibleItems);
|
||||
};
|
||||
|
||||
const parents = useMemo(
|
||||
() => getParents(selectComp, parsedVNodeData),
|
||||
[selectComp, parsedVNodeData]
|
||||
);
|
||||
const parents = useMemo(() => getParents(selectComp, parsedVNodeData), [selectComp, parsedVNodeData]);
|
||||
|
||||
const viewSourceFunction = useMemo(
|
||||
() => ({
|
||||
|
@ -338,7 +313,7 @@ function Panel({ viewSource, inspectVNode }) {
|
|||
const mouseAbscissa = event.clientX - left;
|
||||
|
||||
const pageSizeMin = MINIMUM_SIZE;
|
||||
const pageSizeMax = width-MINIMUM_SIZE;
|
||||
const pageSizeMax = width - MINIMUM_SIZE;
|
||||
|
||||
const isMouseInPage = mouseAbscissa > pageSizeMin && mouseAbscissa < pageSizeMax;
|
||||
|
||||
|
@ -394,16 +369,10 @@ function Panel({ viewSource, inspectVNode }) {
|
|||
{`${matchItems.indexOf(currentItem) + 1}/${matchItems.length}`}
|
||||
</span>
|
||||
<div className={styles.divider} />
|
||||
<button
|
||||
className={styles.searchAction}
|
||||
onClick={onSelectLast}
|
||||
>
|
||||
<button className={styles.searchAction} onClick={onSelectLast}>
|
||||
<Arrow direction={'up'} />
|
||||
</button>
|
||||
<button
|
||||
className={styles.searchAction}
|
||||
onClick={onSelectNext}
|
||||
>
|
||||
<button className={styles.searchAction} onClick={onSelectNext}>
|
||||
<Arrow direction={'down'} />
|
||||
</button>
|
||||
<button className={styles.searchAction} onClick={onClear}>
|
||||
|
|
|
@ -51,11 +51,7 @@ export function initBackgroundConnection(type) {
|
|||
}
|
||||
|
||||
let reconnectionTimes = 0;
|
||||
export function postMessageToBackground(
|
||||
type: string,
|
||||
data?: any,
|
||||
inulaX?: boolean
|
||||
) {
|
||||
export function postMessageToBackground(type: string, data?: any, inulaX?: boolean) {
|
||||
try {
|
||||
const payload = data
|
||||
? { type, tabId: chrome.devtools.inspectedWindow.tabId, data }
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
import { useState } from 'openinula';
|
||||
import styles from './PanelX.less';
|
||||
import { Tree } from './Tree';
|
||||
import {displayValue, omit} from './utils';
|
||||
import { displayValue, omit } from './utils';
|
||||
|
||||
type Mutation = {
|
||||
mutation: boolean;
|
||||
|
@ -118,11 +118,7 @@ export function DiffTree({
|
|||
fontFamily: 'monospace',
|
||||
}}
|
||||
className={`${
|
||||
expanded
|
||||
? 'expanded'
|
||||
: `not-expanded ${
|
||||
mutated && !isPrimitive && !expanded ? styles.changed : ''
|
||||
}`
|
||||
expanded ? 'expanded' : `not-expanded ${mutated && !isPrimitive && !expanded ? styles.changed : ''}`
|
||||
}`}
|
||||
onClick={e => {
|
||||
e.stopPropagation();
|
||||
|
@ -165,11 +161,7 @@ export function DiffTree({
|
|||
// 如果至少有一个是复杂变量,则需要展开按钮
|
||||
<>
|
||||
{forcedExpand ? '' : expanded ? <span>▼</span> : <span>▶</span>}
|
||||
{index === 0 || index ? (
|
||||
<b className={styles.purple}>{displayValue(index, search)}: </b>
|
||||
) : (
|
||||
''
|
||||
)}
|
||||
{index === 0 || index ? <b className={styles.purple}>{displayValue(index, search)}: </b> : ''}
|
||||
{isArray ? (
|
||||
// 如果都是数组进行比较
|
||||
expanded ? (
|
||||
|
@ -210,17 +202,10 @@ export function DiffTree({
|
|||
) : isSet ? (
|
||||
expanded ? (
|
||||
<div>
|
||||
<div>
|
||||
{forcedLabel || `Set(${mutation.to?.values.length})`}
|
||||
</div>
|
||||
{Array(
|
||||
Math.max(
|
||||
mutation.from?.values.length,
|
||||
mutation.to?.values.length
|
||||
)
|
||||
)
|
||||
<div>{forcedLabel || `Set(${mutation.to?.values.length})`}</div>
|
||||
{Array(Math.max(mutation.from?.values.length, mutation.to?.values.length))
|
||||
.fill(true)
|
||||
.map((i ,index) => (
|
||||
.map((i, index) => (
|
||||
<div>
|
||||
{mutation.values[index].mutation ? (
|
||||
<DiffTree
|
||||
|
@ -244,22 +229,13 @@ export function DiffTree({
|
|||
))}
|
||||
</div>
|
||||
) : (
|
||||
<span>
|
||||
{forcedLabel || `Set(${mutation.to?.values.length})`}
|
||||
</span>
|
||||
<span>{forcedLabel || `Set(${mutation.to?.values.length})`}</span>
|
||||
)
|
||||
) : isMap ? (
|
||||
expanded ? (
|
||||
<>
|
||||
<span>
|
||||
{forcedLabel || `Map(${mutation.to?.entries.length})`}
|
||||
</span>
|
||||
{Array(
|
||||
Math.max(
|
||||
mutation.from?.entries.length,
|
||||
mutation.to?.entries.length
|
||||
)
|
||||
)
|
||||
<span>{forcedLabel || `Map(${mutation.to?.entries.length})`}</span>
|
||||
{Array(Math.max(mutation.from?.entries.length, mutation.to?.entries.length))
|
||||
.fill(true)
|
||||
.map((i, index) =>
|
||||
mutation.entries[index].mutation ? (
|
||||
|
@ -289,9 +265,7 @@ export function DiffTree({
|
|||
)}
|
||||
</>
|
||||
) : (
|
||||
<span>
|
||||
{forcedLabel || `Map(${mutation.to?.entries.length})`}
|
||||
</span>
|
||||
<span>{forcedLabel || `Map(${mutation.to?.entries.length})`}</span>
|
||||
)
|
||||
) : expanded ? (
|
||||
// 如果都是 object 进行比较
|
||||
|
|
|
@ -22,7 +22,7 @@ import {
|
|||
} from '../panelConnection';
|
||||
import { Table } from './Table';
|
||||
import { Tree } from './Tree';
|
||||
import {fullTextSearch, omit} from './utils';
|
||||
import { fullTextSearch, omit } from './utils';
|
||||
import styles from './PanelX.less';
|
||||
import { Checkbox } from '../utils/Checkbox';
|
||||
import { DiffTree } from './DiffTree';
|
||||
|
@ -57,9 +57,7 @@ function extractDataByType(message, search) {
|
|||
>
|
||||
<Tree
|
||||
data={{
|
||||
Action: `${message.data.action.action}${
|
||||
message.data.fromQueue ? ' (queued)' : ''
|
||||
}`
|
||||
Action: `${message.data.action.action}${message.data.fromQueue ? ' (queued)' : ''}`,
|
||||
}}
|
||||
expand={true}
|
||||
indent={-4}
|
||||
|
@ -92,7 +90,7 @@ function extractDataByType(message, search) {
|
|||
);
|
||||
}
|
||||
|
||||
return <span className={styles.grey}>N/A</span>
|
||||
return <span className={styles.grey}>N/A</span>;
|
||||
}
|
||||
|
||||
export default function EventLog({ setNextStore, setEventFilter, eventFilter }) {
|
||||
|
@ -204,26 +202,27 @@ export default function EventLog({ setNextStore, setEventFilter, eventFilter })
|
|||
timestamp: event.timestamp,
|
||||
type: event.message.type,
|
||||
time: `${date.toLocaleTimeString()} - ${date.toLocaleDateString()}`,
|
||||
state: event.message.type === eventTypes.STATE_CHANGE ? (
|
||||
<DiffTree
|
||||
mutation={event.message.data.change.mutation}
|
||||
expand={true}
|
||||
forcedExpand={true}
|
||||
indent={0}
|
||||
search={eventFilter['fulltext']}
|
||||
omitAttrs={['_inulaObserver']}
|
||||
doNotDisplayIcon={true}
|
||||
/>
|
||||
) : (
|
||||
<Tree
|
||||
data={event.message.data.store.$s}
|
||||
expand={true}
|
||||
search={eventFilter['fulltext']}
|
||||
forcedExpand={true}
|
||||
indent={-4}
|
||||
omitAttrs={['_inulaObserver']}
|
||||
/>
|
||||
),
|
||||
state:
|
||||
event.message.type === eventTypes.STATE_CHANGE ? (
|
||||
<DiffTree
|
||||
mutation={event.message.data.change.mutation}
|
||||
expand={true}
|
||||
forcedExpand={true}
|
||||
indent={0}
|
||||
search={eventFilter['fulltext']}
|
||||
omitAttrs={['_inulaObserver']}
|
||||
doNotDisplayIcon={true}
|
||||
/>
|
||||
) : (
|
||||
<Tree
|
||||
data={event.message.data.store.$s}
|
||||
expand={true}
|
||||
search={eventFilter['fulltext']}
|
||||
forcedExpand={true}
|
||||
indent={-4}
|
||||
omitAttrs={['_inulaObserver']}
|
||||
/>
|
||||
),
|
||||
storeClick: (
|
||||
<span
|
||||
className={styles.link}
|
||||
|
@ -235,10 +234,7 @@ export default function EventLog({ setNextStore, setEventFilter, eventFilter })
|
|||
{event.message.data.store.id}
|
||||
</span>
|
||||
),
|
||||
additionalData: extractDataByType(
|
||||
event.message,
|
||||
eventFilter['fulltext']
|
||||
),
|
||||
additionalData: extractDataByType(event.message, eventFilter['fulltext']),
|
||||
storeId: event.message.data.store.id,
|
||||
event,
|
||||
};
|
||||
|
@ -271,7 +267,7 @@ export default function EventLog({ setNextStore, setEventFilter, eventFilter })
|
|||
<span className={styles.grey}>{' | '}</span>
|
||||
<span
|
||||
style={{
|
||||
cursor: 'pointer'
|
||||
cursor: 'pointer',
|
||||
}}
|
||||
onClick={e => {
|
||||
e.stopPropagation();
|
||||
|
@ -342,18 +338,14 @@ export default function EventLog({ setNextStore, setEventFilter, eventFilter })
|
|||
{Object.values(eventTypes).map(eventType => {
|
||||
return (
|
||||
<button
|
||||
className={`${styles.filterButton} ${
|
||||
usedTypes[eventType] ? '' : styles.grey
|
||||
} ${
|
||||
className={`${styles.filterButton} ${usedTypes[eventType] ? '' : styles.grey} ${
|
||||
eventFilter['message.type'] === eventType ? styles.active : ''
|
||||
}`}
|
||||
onClick={() => {
|
||||
addFilter('message.type', eventType);
|
||||
}}
|
||||
>
|
||||
{`${eventType.replace('inulax ', '')}(${
|
||||
usedTypes[eventType] || 0
|
||||
})`}
|
||||
{`${eventType.replace('inulax ', '')}(${usedTypes[eventType] || 0})`}
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
|
@ -374,20 +366,12 @@ export default function EventLog({ setNextStore, setEventFilter, eventFilter })
|
|||
type: data.type,
|
||||
store: {
|
||||
actions: Object.fromEntries(
|
||||
Object.entries(message.data.store.$config.actions).map(
|
||||
([id, action]) => {
|
||||
return [
|
||||
id,
|
||||
(action as string).replace(/\{.*}/gms, '{...}').replace('function ', ''),
|
||||
];
|
||||
}
|
||||
)
|
||||
Object.entries(message.data.store.$config.actions).map(([id, action]) => {
|
||||
return [id, (action as string).replace(/\{.*}/gms, '{...}').replace('function ', '')];
|
||||
})
|
||||
),
|
||||
computed: Object.fromEntries(
|
||||
Object.keys(message.data.store.$c).map(key => [
|
||||
key,
|
||||
message.data.store.expanded[key],
|
||||
])
|
||||
Object.keys(message.data.store.$c).map(key => [key, message.data.store.expanded[key]])
|
||||
),
|
||||
state: message.data.store.$s,
|
||||
id: message.data.store.id,
|
||||
|
|
|
@ -73,7 +73,7 @@ export function Modal({
|
|||
<input
|
||||
ref={inputRef}
|
||||
type={'text'}
|
||||
onKeyPress={({key}) => {
|
||||
onKeyPress={({ key }) => {
|
||||
if (key === 'Enter') {
|
||||
tryGatherData();
|
||||
}
|
||||
|
|
|
@ -32,12 +32,7 @@ export default function PanelX() {
|
|||
{
|
||||
id: 'stores',
|
||||
title: 'Stores',
|
||||
getComponent: () => (
|
||||
<Stores
|
||||
nextStoreId={nextStoreId}
|
||||
showFilteredEvents={showFilterEvents}
|
||||
/>
|
||||
),
|
||||
getComponent: () => <Stores nextStoreId={nextStoreId} showFilteredEvents={showFilterEvents} />,
|
||||
},
|
||||
{
|
||||
id: 'events',
|
||||
|
@ -60,10 +55,7 @@ export default function PanelX() {
|
|||
<div style={{ marginBottom: '10px' }}>
|
||||
{tabs.map(tab =>
|
||||
tab.id === active ? (
|
||||
<button
|
||||
className={`${styles.tab} ${styles.active}`}
|
||||
disabled={true}
|
||||
>
|
||||
<button className={`${styles.tab} ${styles.active}`} disabled={true}>
|
||||
{tab.title}
|
||||
</button>
|
||||
) : (
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
*/
|
||||
|
||||
import { useState } from 'openinula';
|
||||
import {Tree} from './Tree';
|
||||
import { Tree } from './Tree';
|
||||
import styles from './PanelX.less';
|
||||
|
||||
type displayKeysType = [string, string][];
|
||||
|
@ -84,14 +84,10 @@ export function Table({
|
|||
<span></span>
|
||||
{data.map(row => (
|
||||
<div
|
||||
className={`${styles.row} ${
|
||||
keyToDisplay === row[dataKey] ? styles.active : ''
|
||||
}`}
|
||||
className={`${styles.row} ${keyToDisplay === row[dataKey] ? styles.active : ''}`}
|
||||
onClick={() => {
|
||||
setManualOverride(true);
|
||||
setKeyToDisplay(
|
||||
keyToDisplay === row[dataKey] ? null : row[dataKey]
|
||||
);
|
||||
setKeyToDisplay(keyToDisplay === row[dataKey] ? null : row[dataKey]);
|
||||
}}
|
||||
>
|
||||
<div className={styles.cell}>{row?.[attr] || ''}</div>
|
||||
|
@ -119,11 +115,7 @@ export function Table({
|
|||
<div className={styles.row}>
|
||||
<div className={styles.cell}>
|
||||
<Tree
|
||||
data={
|
||||
displayDataProcessor
|
||||
? displayDataProcessor(displayRow)
|
||||
: displayRow
|
||||
}
|
||||
data={displayDataProcessor ? displayDataProcessor(displayRow) : displayRow}
|
||||
indent={displayRow[displayKeys[0][0]]}
|
||||
expand={true}
|
||||
search={search}
|
||||
|
@ -142,7 +134,7 @@ export function Table({
|
|||
<div className={`${styles.row} ${styles.header}`}>
|
||||
{displayKeys.map(([key, title]) => (
|
||||
<div className={styles.cell}>{title}</div>
|
||||
))}
|
||||
))}
|
||||
</div>
|
||||
{data.map(item => (
|
||||
<div
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
import { useState } from 'openinula';
|
||||
import styles from './PanelX.less';
|
||||
import {Modal} from './Modal';
|
||||
import { Modal } from './Modal';
|
||||
import { displayValue, omit } from './utils';
|
||||
|
||||
export function Tree({
|
||||
|
@ -36,7 +36,7 @@ export function Tree({
|
|||
expand?: boolean;
|
||||
search?: string;
|
||||
forcedExpand?: boolean;
|
||||
className?: string | undefined
|
||||
className?: string | undefined;
|
||||
omitAttrs?: string[];
|
||||
onEdit?: (path: any[], value: any) => void | null;
|
||||
forcedLabel?: string | number | null;
|
||||
|
@ -71,11 +71,7 @@ export function Tree({
|
|||
}}
|
||||
>
|
||||
{new Array(Math.max(indent, 0)).fill(<span> </span>)}
|
||||
{forcedExpand || isVNode ? null : expanded ? (
|
||||
<span>▼</span>
|
||||
) : (
|
||||
<span>▶</span>
|
||||
)}
|
||||
{forcedExpand || isVNode ? null : expanded ? <span>▼</span> : <span>▶</span>}
|
||||
{index === 0 || index ? (
|
||||
<>
|
||||
<b className={styles.purple}>{displayValue(index, search)}: </b>
|
||||
|
@ -84,28 +80,28 @@ export function Tree({
|
|||
''
|
||||
)}
|
||||
{forcedLabel
|
||||
? forcedLabel
|
||||
: expanded
|
||||
? isVNode
|
||||
? null
|
||||
: Array.isArray(data)
|
||||
? `Array(${data.length})`
|
||||
: isMap
|
||||
? `Map(${data.entries.length})`
|
||||
: isSet
|
||||
? `Set(${data.values.length})`
|
||||
: '{ ... }'
|
||||
: isWeakMap
|
||||
? 'WeakMap()'
|
||||
: isWeakSet
|
||||
? 'WeakSet()'
|
||||
: isMap
|
||||
? `Map(${data.entries.length})`
|
||||
: isSet
|
||||
? `Set(${data.values.length})`
|
||||
: Array.isArray(data)
|
||||
? `Array(${data.length})`
|
||||
: '{ ... }'}
|
||||
? forcedLabel
|
||||
: expanded
|
||||
? isVNode
|
||||
? null
|
||||
: Array.isArray(data)
|
||||
? `Array(${data.length})`
|
||||
: isMap
|
||||
? `Map(${data.entries.length})`
|
||||
: isSet
|
||||
? `Set(${data.values.length})`
|
||||
: '{ ... }'
|
||||
: isWeakMap
|
||||
? 'WeakMap()'
|
||||
: isWeakSet
|
||||
? 'WeakSet()'
|
||||
: isMap
|
||||
? `Map(${data.entries.length})`
|
||||
: isSet
|
||||
? `Set(${data.values.length})`
|
||||
: Array.isArray(data)
|
||||
? `Array(${data.length})`
|
||||
: '{ ... }'}
|
||||
</span>
|
||||
{expanded || isVNode ? (
|
||||
isArray ? (
|
||||
|
@ -122,8 +118,8 @@ export function Tree({
|
|||
onEdit={
|
||||
onEdit
|
||||
? (path, val) => {
|
||||
onEdit(path.concat([index]), val);
|
||||
}
|
||||
onEdit(path.concat([index]), val);
|
||||
}
|
||||
: null
|
||||
}
|
||||
/>
|
||||
|
@ -138,7 +134,7 @@ export function Tree({
|
|||
{data.entries.map(([key, value]) => {
|
||||
return (
|
||||
<Tree
|
||||
data={{key, value}}
|
||||
data={{ key, value }}
|
||||
indent={indent + 4}
|
||||
search={search}
|
||||
className={className}
|
||||
|
@ -174,8 +170,8 @@ export function Tree({
|
|||
onEdit={
|
||||
onEdit
|
||||
? (path, val) => {
|
||||
onEdit(path.concat([key]), val);
|
||||
}
|
||||
onEdit(path.concat([key]), val);
|
||||
}
|
||||
: null
|
||||
}
|
||||
/>
|
||||
|
|
|
@ -25,7 +25,7 @@ export function highlight(source, search) {
|
|||
const parts = source.split(search);
|
||||
const result = [];
|
||||
|
||||
for (let i= 0; i < parts.length * 2 - 1; i++) {
|
||||
for (let i = 0; i < parts.length * 2 - 1; i++) {
|
||||
if (i % 2) {
|
||||
result.push(<span className={styles.highlighted}>{search}</span>);
|
||||
} else {
|
||||
|
@ -38,11 +38,7 @@ export function highlight(source, search) {
|
|||
|
||||
export function displayValue(val: any, search = '') {
|
||||
if (typeof val === 'boolean') {
|
||||
return (
|
||||
<span>
|
||||
{highlight(val ? 'true' : 'false', search)}
|
||||
</span>
|
||||
);
|
||||
return <span>{highlight(val ? 'true' : 'false', search)}</span>;
|
||||
}
|
||||
|
||||
if (val === '') {
|
||||
|
@ -62,10 +58,7 @@ export function displayValue(val: any, search = '') {
|
|||
return (
|
||||
<span>
|
||||
<i>ƒ</i>
|
||||
{highlight(
|
||||
val.match(/^function\s?\([\w,]*\)/g)[0].replace(/^function\s?/, ''),
|
||||
search
|
||||
)}
|
||||
{highlight(val.match(/^function\s?\([\w,]*\)/g)[0].replace(/^function\s?/, ''), search)}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
@ -75,7 +68,10 @@ export function displayValue(val: any, search = '') {
|
|||
return <span className={styles.blue}>{highlight('' + val, search)}</span>;
|
||||
}
|
||||
if (typeof val === 'function') {
|
||||
const args = val.toString().match(/^function\s?\([\w,]*\)/g)[0].replace(/^function\s?/, '');
|
||||
const args = val
|
||||
.toString()
|
||||
.match(/^function\s?\([\w,]*\)/g)[0]
|
||||
.replace(/^function\s?/, '');
|
||||
return (
|
||||
<span>
|
||||
<i>ƒ</i>
|
||||
|
@ -108,9 +104,7 @@ export function fullTextSearch(value, search) {
|
|||
return value.values.some(val => fullTextSearch(val, search));
|
||||
}
|
||||
if (value?._type === 'Map') {
|
||||
return value.entries.some(
|
||||
(key, val) => fullTextSearch(key, search) || fullTextSearch(val, search)
|
||||
);
|
||||
return value.entries.some((key, val) => fullTextSearch(key, search) || fullTextSearch(val, search));
|
||||
}
|
||||
return Object.values(value).some(val => fullTextSearch(val, search));
|
||||
}
|
||||
|
@ -165,8 +159,7 @@ export function stringify(data) {
|
|||
if (Array.isArray(value)) {
|
||||
return (
|
||||
<span>
|
||||
<span className={styles.purple}>{key}</span>:{' '}
|
||||
{`Array(${value.length})`}
|
||||
<span className={styles.purple}>{key}</span>: {`Array(${value.length})`}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
@ -188,16 +181,14 @@ export function stringify(data) {
|
|||
if ((value as any)?._type === 'Set') {
|
||||
return (
|
||||
<span>
|
||||
<span className={styles.purple}>{key}</span>:{' '}
|
||||
{`Set(${(value as Set<any>).size})`}
|
||||
<span className={styles.purple}>{key}</span>: {`Set(${(value as Set<any>).size})`}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
if ((value as any)?._type === 'Map') {
|
||||
return (
|
||||
<span>
|
||||
<span className={styles.purple}>{key}</span>:{' '}
|
||||
{`Map(${(value as Map<any, any>).size})`}
|
||||
<span className={styles.purple}>{key}</span>: {`Map(${(value as Map<any, any>).size})`}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -50,14 +50,14 @@ export type IAttr = {
|
|||
hIndex?: number; // 用于记录 hook 的 hIndex 值
|
||||
} & (
|
||||
| {
|
||||
type: ShowAsStringType;
|
||||
value: string;
|
||||
}
|
||||
type: ShowAsStringType;
|
||||
value: string;
|
||||
}
|
||||
| {
|
||||
type: 'boolean';
|
||||
value: boolean;
|
||||
}
|
||||
);
|
||||
type: 'boolean';
|
||||
value: boolean;
|
||||
}
|
||||
);
|
||||
|
||||
type ShowType = ShowAsStringType | 'boolean';
|
||||
|
||||
|
@ -79,10 +79,7 @@ const getObjectKeys = (attr: Record<string, any>): Array<string | number | symbo
|
|||
let current = attr;
|
||||
try {
|
||||
while (current != null) {
|
||||
const currentKeys = [
|
||||
...Object.keys(current),
|
||||
...Object.getOwnPropertySymbols(current)
|
||||
];
|
||||
const currentKeys = [...Object.keys(current), ...Object.getOwnPropertySymbols(current)];
|
||||
const descriptors = Object.getOwnPropertyDescriptors(current);
|
||||
currentKeys.forEach(key => {
|
||||
// @ts-ignore key 可以为 symbol 类型
|
||||
|
@ -99,10 +96,7 @@ const getObjectKeys = (attr: Record<string, any>): Array<string | number | symbo
|
|||
};
|
||||
|
||||
// 用于比较两个 key 值的顺序
|
||||
export function sortKeys(
|
||||
firstKey: string | number | symbol,
|
||||
secondKey: string | number | symbol
|
||||
): number {
|
||||
export function sortKeys(firstKey: string | number | symbol, secondKey: string | number | symbol): number {
|
||||
if (firstKey.toString() > secondKey.toString()) {
|
||||
return 1;
|
||||
} else if (secondKey.toString() > firstKey.toString()) {
|
||||
|
@ -137,11 +131,7 @@ const parseSubTitle = <T>(attr: T) => {
|
|||
} else if (AttrType === 'function') {
|
||||
const funcName = attr['name'];
|
||||
return `ƒ ${funcName}() {}`;
|
||||
} else if (
|
||||
AttrType === 'boolean' ||
|
||||
AttrType === 'number' ||
|
||||
AttrType === 'undefined'
|
||||
) {
|
||||
} else if (AttrType === 'boolean' || AttrType === 'number' || AttrType === 'undefined') {
|
||||
return `${attr}`;
|
||||
} else if (AttrType === 'object') {
|
||||
if (attr === null) {
|
||||
|
@ -179,24 +169,13 @@ const parseSubTitle = <T>(attr: T) => {
|
|||
}
|
||||
};
|
||||
|
||||
const parseSubAttr = (
|
||||
attr: any,
|
||||
parentIndentation: number,
|
||||
attrName: string,
|
||||
result: IAttr[],
|
||||
hIndex?: number
|
||||
) => {
|
||||
const parseSubAttr = (attr: any, parentIndentation: number, attrName: string, result: IAttr[], hIndex?: number) => {
|
||||
const AttrType = typeof attr;
|
||||
let value: any;
|
||||
let showType: any;
|
||||
let addSubState;
|
||||
|
||||
if (
|
||||
AttrType === 'boolean' ||
|
||||
AttrType === 'number' ||
|
||||
AttrType === 'undefined' ||
|
||||
AttrType === 'string'
|
||||
) {
|
||||
if (AttrType === 'boolean' || AttrType === 'number' || AttrType === 'undefined' || AttrType === 'string') {
|
||||
value = attr;
|
||||
showType = AttrType;
|
||||
} else if (AttrType === 'function') {
|
||||
|
@ -308,11 +287,7 @@ export function parseAttr(rootAttr: any) {
|
|||
return result;
|
||||
}
|
||||
|
||||
export function parseHooks(
|
||||
hooks: Hook<any, any>[] | null,
|
||||
depContexts: Array<ContextType<any>> | null,
|
||||
getHookInfo
|
||||
) {
|
||||
export function parseHooks(hooks: Hook<any, any>[] | null, depContexts: Array<ContextType<any>> | null, getHookInfo) {
|
||||
const result: IAttr[] = [];
|
||||
const indentation = 0;
|
||||
if (depContexts !== null && depContexts?.length > 0) {
|
||||
|
@ -343,7 +318,7 @@ export function parseVNodeAttrs(vNode: VNode, getHookInfo) {
|
|||
src,
|
||||
};
|
||||
} else if (propsAndHooksTag.includes(tag)) {
|
||||
const { props, hooks, depContexts, src } = vNode;
|
||||
const { props, hooks, depContexts, src } = vNode;
|
||||
const parsedProps = parseAttr(props);
|
||||
const parsedHooks = parseHooks(hooks, depContexts, getHookInfo);
|
||||
return {
|
||||
|
|
|
@ -21,7 +21,7 @@ import {
|
|||
ForwardRef,
|
||||
FunctionComponent,
|
||||
MemoComponent,
|
||||
SuspenseComponent
|
||||
SuspenseComponent,
|
||||
} from '../../../inula/src/renderer/vnode/VNodeTags';
|
||||
|
||||
export type NameObj = {
|
||||
|
@ -61,13 +61,7 @@ const componentType = [
|
|||
MemoComponent,
|
||||
];
|
||||
|
||||
const badgeNameArr: Array<string> = [
|
||||
'withRouter(',
|
||||
'SideEffect(',
|
||||
'Connect(',
|
||||
'injectIntl(',
|
||||
'Pure(',
|
||||
];
|
||||
const badgeNameArr: Array<string> = ['withRouter(', 'SideEffect(', 'Connect(', 'injectIntl(', 'Pure('];
|
||||
|
||||
export function isUserComponent(tag: string) {
|
||||
return componentType.includes(tag);
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
*/
|
||||
|
||||
interface IArrow {
|
||||
direction: 'up' | 'down'
|
||||
direction: 'up' | 'down';
|
||||
}
|
||||
|
||||
export default function Arrow({ direction: director }: IArrow) {
|
||||
|
@ -26,8 +26,8 @@ export default function Arrow({ direction: director }: IArrow) {
|
|||
}
|
||||
|
||||
return (
|
||||
<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' width='1rem' height='1rem'>
|
||||
<path d={d} fill='currentColor' />
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="1rem" height="1rem">
|
||||
<path d={d} fill="currentColor" />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -15,8 +15,8 @@
|
|||
|
||||
export default function Close() {
|
||||
return (
|
||||
<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' width='1rem' height='1rem'>
|
||||
<path d='M4 3 L3 4 L7 8 L3 12 L4 13 L8 9 L12 13 L13 12 L9 8 L13 4 L12 3 L8 7z' fill='currentColor' />
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="1rem" height="1rem">
|
||||
<path d="M4 3 L3 4 L7 8 L3 12 L4 13 L8 9 L12 13 L13 12 L9 8 L13 4 L12 3 L8 7z" fill="currentColor" />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -15,13 +15,15 @@
|
|||
|
||||
export default function Debug() {
|
||||
return (
|
||||
<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='1.3rem' height='1.3rem' margin-top='0.4rem'>
|
||||
<path d='M0 0h24v24H0z' fill='none'/>
|
||||
<path d='M20 8h-2.81c-.45-.78-1.07-1.45-1.82-1.96L17 4 41 15.59 3l-2.17 2.17c12 96 5.06 12.49 5 12 5c-.49 0-.96.06-1.41.17L8.41
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="1.3rem" height="1.3rem" margin-top="0.4rem">
|
||||
<path d="M0 0h24v24H0z" fill="none" />
|
||||
<path
|
||||
d="M20 8h-2.81c-.45-.78-1.07-1.45-1.82-1.96L17 4 41 15.59 3l-2.17 2.17c12 96 5.06 12.49 5 12 5c-.49 0-.96.06-1.41.17L8.41
|
||||
3 7 4.41l1.62 1.63C7.88 6.55 7.26 7.22 6.81 8H4v2h2.09c-.05.33-.09.66-.09 1v1H4v2h2v1c0 .34 04.67 09 1H4v2h2.81c1.04
|
||||
1.79 2.97 3 5.19 3s4.15-1.21 5.19-3H20v-2h-2.09c.05-.33.09-.66.09-1v-1h2v-2h-2v-1c0-.34-.04-.67-.09-1H20V8zm-6
|
||||
8h-4v-2h4v2zm0-4h-4v-2h4v2z'
|
||||
fill='currentColor' />
|
||||
8h-4v-2h4v2zm0-4h-4v-2h4v2z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -15,12 +15,15 @@
|
|||
|
||||
export default function Discover() {
|
||||
return (
|
||||
<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='1.3rem' height='1.3rem'>
|
||||
<path d='M0 0h24v24H0z' fill='none' />
|
||||
<path d='M15.5 14h-.79l-.28-.27C15 41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="1.3rem" height="1.3rem">
|
||||
<path d="M0 0h24v24H0z" fill="none" />
|
||||
<path
|
||||
d="M15.5 14h-.79l-.28-.27C15 41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91
|
||||
16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99
|
||||
5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z'
|
||||
fill='#343231' p-id='4151' />
|
||||
5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"
|
||||
fill="#343231"
|
||||
p-id="4151"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -15,12 +15,14 @@
|
|||
|
||||
export default function Eye() {
|
||||
return (
|
||||
<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='1.3rem' height='1.3rem'>
|
||||
<path d='M0 0h24v24H0z' fill='none'/>
|
||||
<path d='M12 4.5C7 4.5 2.73 7.61 1 12c1.73 4.39 6 7.5 11 7.5s9.27-3.11 11-7.5c-1.73-4.39-6-7.5-11-7.5zM12
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="1.3rem" height="1.3rem">
|
||||
<path d="M0 0h24v24H0z" fill="none" />
|
||||
<path
|
||||
d="M12 4.5C7 4.5 2.73 7.61 1 12c1.73 4.39 6 7.5 11 7.5s9.27-3.11 11-7.5c-1.73-4.39-6-7.5-11-7.5zM12
|
||||
17c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5zm0-8c-1.66 0-3 1.34-3 3s1.34 3 3 3
|
||||
3-1.34 3-3-1.34-3-3-3z'
|
||||
fill='currentColor' />
|
||||
3-1.34 3-3-1.34-3-3-3z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -15,10 +15,12 @@
|
|||
|
||||
export default function Location() {
|
||||
return (
|
||||
<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='1.3rem' height='1.3rem'>
|
||||
<path d='M0 0h24v24H0z' fill='none' />
|
||||
<path d='M9.4 16.6L4.8 12l4.6-4.6L8 6l-6 6 6 6 1.4-1.4zm5.2 0l4.6-4.6-4.6-4.6L16 6l6 6-6 6-1.4-1.4z'
|
||||
fill='currentColor' />
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="1.3rem" height="1.3rem">
|
||||
<path d="M0 0h24v24H0z" fill="none" />
|
||||
<path
|
||||
d="M9.4 16.6L4.8 12l4.6-4.6L8 6l-6 6 6 6 1.4-1.4zm5.2 0l4.6-4.6-4.6-4.6L16 6l6 6-6 6-1.4-1.4z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -15,8 +15,20 @@
|
|||
|
||||
export default function Operation() {
|
||||
return (
|
||||
<svg t="1669105013009" className="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2821" width="1rem" height="1rem">
|
||||
<path d="M177.23392 943.96416c25.93792 0 50.3296-10.13248 68.70528-28.50816l208.18432-208.18944 29.36832-29.36832 38.90688 14.51008a323.70688 323.70688 0 0 0 112.85504 20.18304c86.48704 0 167.90528-33.664 229.05344-94.90432 83.4816-83.39456 113.4592-203.37152 83.99872-312.96512L795.60704 457.4208l-45.77792 45.77792-45.85984-45.77792-137.41568-137.41056-45.77792-45.87008 45.77792-45.7728 152.61696-152.61696a327.44448 327.44448 0 0 0-83.90656-10.99264c-86.48704 0-167.81824 33.66912-228.9664 94.90944C316.96896 248.89856 287.68256 383.13472 331.5712 501.57056l14.42816 38.90688-29.37344 29.36832-208.09728 208.19456c-18.37568 18.37568-28.51328 42.76736-28.51328 68.70528 0 25.93792 10.13248 50.3296 28.51328 68.7104a96.41472 96.41472 0 0 0 68.70528 28.50816m0 64.76288a161.67936 161.67936 0 0 1-114.57024-47.41632c-63.21152-63.29856-63.21152-165.84704 0-229.05344L270.848 524.07296c-51.18976-138.01984-21.30432-299.31008 89.57952-410.27072C436.352 37.9648 535.808 0 635.25888 0c68.4544 0 136.81664 17.95072 197.53472 53.77024l-220.38016 220.37504 137.41568 137.41568 220.38528-220.38016c88.02816 149.0944 68.0192 344.30976-60.12416 472.3712-75.83744 75.83232-175.37536 113.79712-274.83136 113.79712a389.6064 389.6064 0 0 1-135.35232-24.2176l-208.18944 208.18432c-31.60576 31.60064-73.088 47.4112-114.4832 47.4112z" p-id="2822"/>
|
||||
<svg
|
||||
t="1669105013009"
|
||||
className="icon"
|
||||
viewBox="0 0 1024 1024"
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
p-id="2821"
|
||||
width="1rem"
|
||||
height="1rem"
|
||||
>
|
||||
<path
|
||||
d="M177.23392 943.96416c25.93792 0 50.3296-10.13248 68.70528-28.50816l208.18432-208.18944 29.36832-29.36832 38.90688 14.51008a323.70688 323.70688 0 0 0 112.85504 20.18304c86.48704 0 167.90528-33.664 229.05344-94.90432 83.4816-83.39456 113.4592-203.37152 83.99872-312.96512L795.60704 457.4208l-45.77792 45.77792-45.85984-45.77792-137.41568-137.41056-45.77792-45.87008 45.77792-45.7728 152.61696-152.61696a327.44448 327.44448 0 0 0-83.90656-10.99264c-86.48704 0-167.81824 33.66912-228.9664 94.90944C316.96896 248.89856 287.68256 383.13472 331.5712 501.57056l14.42816 38.90688-29.37344 29.36832-208.09728 208.19456c-18.37568 18.37568-28.51328 42.76736-28.51328 68.70528 0 25.93792 10.13248 50.3296 28.51328 68.7104a96.41472 96.41472 0 0 0 68.70528 28.50816m0 64.76288a161.67936 161.67936 0 0 1-114.57024-47.41632c-63.21152-63.29856-63.21152-165.84704 0-229.05344L270.848 524.07296c-51.18976-138.01984-21.30432-299.31008 89.57952-410.27072C436.352 37.9648 535.808 0 635.25888 0c68.4544 0 136.81664 17.95072 197.53472 53.77024l-220.38016 220.37504 137.41568 137.41568 220.38528-220.38016c88.02816 149.0944 68.0192 344.30976-60.12416 472.3712-75.83744 75.83232-175.37536 113.79712-274.83136 113.79712a389.6064 389.6064 0 0 1-135.35232-24.2176l-208.18944 208.18432c-31.60576 31.60064-73.088 47.4112-114.4832 47.4112z"
|
||||
p-id="2822"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -15,23 +15,23 @@
|
|||
|
||||
export default function Select() {
|
||||
return (
|
||||
<svg width='1rem' height='1rem' viewBox='0 0 16 16' xmlns='http://www.w3.org/2000/svg'>
|
||||
<g fill='none' fill-rule='evenodd'>
|
||||
<g stroke='currentColor'>
|
||||
<svg width="1rem" height="1rem" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
|
||||
<g fill="none" fill-rule="evenodd">
|
||||
<g stroke="currentColor">
|
||||
<path
|
||||
stroke-width='.291'
|
||||
fill='currentColor'
|
||||
fill-rule='nonzero'
|
||||
stroke-linecap='round'
|
||||
stroke-linejoin='round'
|
||||
d='M6 6l3.014 9 2.508-3.533L15 8.791z'
|
||||
stroke-width=".291"
|
||||
fill="currentColor"
|
||||
fill-rule="nonzero"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="M6 6l3.014 9 2.508-3.533L15 8.791z"
|
||||
></path>
|
||||
<path stroke-width='2' d='M10.417 10.417l2.87 2.87L15 15'></path>
|
||||
<path stroke-width="2" d="M10.417 10.417l2.87 2.87L15 15"></path>
|
||||
</g>
|
||||
<path
|
||||
d='M12.188 0A2.812 2.812 0 0 1 15 2.813V5h-1V2.857A1.857 1.857 0 0 0 12.143 1H2.857A1.857 1.857 0 0 0 1 2.857v9.286C1 13.169 1.831 14 2.857 14H5v1H2.812A2.812 2.812 0 0 1 0 12.187V2.813A2.812 2.812 0 0 1 2.813 0h9.374z'
|
||||
fill='currentColor'
|
||||
fill-rule='nonzero'
|
||||
d="M12.188 0A2.812 2.812 0 0 1 15 2.813V5h-1V2.857A1.857 1.857 0 0 0 12.143 1H2.857A1.857 1.857 0 0 0 1 2.857v9.286C1 13.169 1.831 14 2.857 14H5v1H2.812A2.812 2.812 0 0 1 0 12.187V2.813A2.812 2.812 0 0 1 2.813 0h9.374z"
|
||||
fill="currentColor"
|
||||
fill-rule="nonzero"
|
||||
></path>
|
||||
</g>
|
||||
</svg>
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
*/
|
||||
|
||||
interface IArrow {
|
||||
director: 'right' | 'down'
|
||||
director: 'right' | 'down';
|
||||
}
|
||||
|
||||
export default function Triangle({ director }: IArrow) {
|
||||
|
@ -25,8 +25,8 @@ export default function Triangle({ director }: IArrow) {
|
|||
d = 'm0 2h16 l-8 12 z';
|
||||
}
|
||||
return (
|
||||
<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' width='8px' height='8px'>
|
||||
<path d={d} fill='currentColor' />
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="8px" height="8px">
|
||||
<path d={d} fill="currentColor" />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -16,26 +16,26 @@
|
|||
export function Checkbox({ value }) {
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
border: '1px solid black',
|
||||
borderRadius: '2px',
|
||||
width: '0.75rem',
|
||||
height: '0.75rem',
|
||||
padding: '1px',
|
||||
backgroundColor: 'white',
|
||||
display: 'inline-block',
|
||||
position: 'relative',
|
||||
cursor: 'pointer',
|
||||
verticalAlign: 'sub',
|
||||
marginBottom: '0.1rem'
|
||||
}}
|
||||
style={{
|
||||
border: '1px solid black',
|
||||
borderRadius: '2px',
|
||||
width: '0.75rem',
|
||||
height: '0.75rem',
|
||||
padding: '1px',
|
||||
backgroundColor: 'white',
|
||||
display: 'inline-block',
|
||||
position: 'relative',
|
||||
cursor: 'pointer',
|
||||
verticalAlign: 'sub',
|
||||
marginBottom: '0.1rem',
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
backgroundColor: value? 'black' : 'white',
|
||||
position: 'relative'
|
||||
backgroundColor: value ? 'black' : 'white',
|
||||
position: 'relative',
|
||||
}}
|
||||
></div>
|
||||
</div>
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
import { createContext } from "openinula";
|
||||
import { createContext } from 'openinula';
|
||||
|
||||
const PickElementContext = createContext(null);
|
||||
PickElementContext.displayName = 'PickElementContext';
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
import {createContext} from 'openinula';
|
||||
import { createContext } from 'openinula';
|
||||
|
||||
const ViewSourceContext = createContext(null);
|
||||
ViewSourceContext.displayName = 'ViewSourceContext';
|
||||
|
|
|
@ -31,11 +31,7 @@ export function injectSrc(src) {
|
|||
script.remove();
|
||||
};
|
||||
|
||||
ifNullThrows(
|
||||
document.head
|
||||
|| document.getElementsByName('head')[0]
|
||||
|| document.documentElement
|
||||
).appendChild(script);
|
||||
ifNullThrows(document.head || document.getElementsByName('head')[0] || document.documentElement).appendChild(script);
|
||||
}
|
||||
|
||||
export function injectCode(code) {
|
||||
|
|
|
@ -18,10 +18,10 @@
|
|||
* 同时也无法在运行时打断点,需要适当的日志辅助开发和定位问题
|
||||
*/
|
||||
interface LoggerType {
|
||||
error: typeof console.error,
|
||||
info: typeof console.info,
|
||||
log: typeof console.log,
|
||||
warn: typeof console.warn
|
||||
error: typeof console.error;
|
||||
info: typeof console.info;
|
||||
log: typeof console.log;
|
||||
warn: typeof console.warn;
|
||||
}
|
||||
|
||||
export function createLogger(id: string): LoggerType {
|
||||
|
|
|
@ -34,7 +34,7 @@ export function packagePayload(payload: PayloadType, from: string, inulaX?: bool
|
|||
return {
|
||||
type: devTools,
|
||||
payload,
|
||||
from
|
||||
from,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -26,28 +26,12 @@ function handleBuildDir() {
|
|||
if (!isBuildExist) {
|
||||
fs.mkdirSync(staticDir);
|
||||
}
|
||||
fs.copyFileSync(path.join(__dirname, 'src', 'panel', 'panel.html'), path.join(staticDir, 'panel.html'));
|
||||
fs.copyFileSync(path.join(__dirname, 'src', 'panelX', 'panel.html'), path.join(staticDir, 'panelX.html'));
|
||||
fs.copyFileSync(path.join(__dirname, 'src', 'main', 'main.html'), path.join(staticDir, 'main.html'));
|
||||
fs.copyFileSync(path.join(__dirname, 'src', 'manifest.json'), path.join(staticDir, 'manifest.json'));
|
||||
fs.copyFileSync(
|
||||
path.join(__dirname, 'src', 'panel', 'panel.html'),
|
||||
path.join(staticDir, 'panel.html')
|
||||
);
|
||||
fs.copyFileSync(
|
||||
path.join(__dirname, 'src', 'panelX', 'panel.html'),
|
||||
path.join(staticDir, 'panelX.html')
|
||||
);
|
||||
fs.copyFileSync(
|
||||
path.join(__dirname, 'src', 'main', 'main.html'),
|
||||
path.join(staticDir, 'main.html')
|
||||
);
|
||||
fs.copyFileSync(
|
||||
path.join(__dirname, 'src', 'manifest.json'),
|
||||
path.join(staticDir, 'manifest.json')
|
||||
);
|
||||
fs.copyFileSync(
|
||||
path.join(
|
||||
__dirname,
|
||||
'../inula/build/umd',
|
||||
'inula.development.js'
|
||||
),
|
||||
path.join(__dirname, '../inula/build/umd', 'inula.development.js'),
|
||||
path.join(staticDir, 'inula.development.js')
|
||||
);
|
||||
}
|
||||
|
@ -65,7 +49,7 @@ const config = {
|
|||
},
|
||||
output: {
|
||||
path: path.resolve(__dirname, './build'),
|
||||
filename: '[name].js'
|
||||
filename: '[name].js',
|
||||
},
|
||||
mode: 'development',
|
||||
devtool: 'inline-source-map',
|
||||
|
|
|
@ -24,7 +24,7 @@ module.exports = {
|
|||
},
|
||||
output: {
|
||||
path: path.resolve(__dirname, './dist'),
|
||||
filename: '[name].js'
|
||||
filename: '[name].js',
|
||||
},
|
||||
mode: 'development',
|
||||
devtool: 'source-map',
|
||||
|
@ -73,5 +73,5 @@ module.exports = {
|
|||
open: 'panel.html',
|
||||
port: 9000,
|
||||
magicHtml: true,
|
||||
}
|
||||
},
|
||||
};
|
||||
|
|
|
@ -14,43 +14,42 @@
|
|||
*/
|
||||
|
||||
import Inula, { useState } from 'openinula';
|
||||
import { IntlProvider } from "../index";
|
||||
import zh from "./locale/zh";
|
||||
import en from "./locale/en";
|
||||
import Example1 from "./components/Example1";
|
||||
import Example2 from "./components/Example2";
|
||||
import Example3 from "./components/Example3";
|
||||
import Example4 from "./components/Example4";
|
||||
import Example5 from "./components/Example5";
|
||||
import Example6 from "./components/Example6";
|
||||
import { IntlProvider } from '../index';
|
||||
import zh from './locale/zh';
|
||||
import en from './locale/en';
|
||||
import Example1 from './components/Example1';
|
||||
import Example2 from './components/Example2';
|
||||
import Example3 from './components/Example3';
|
||||
import Example4 from './components/Example4';
|
||||
import Example5 from './components/Example5';
|
||||
import Example6 from './components/Example6';
|
||||
|
||||
const App = () => {
|
||||
const [locale, setLocale] = useState('zh');
|
||||
const handleChange = () => {
|
||||
locale === 'zh' ? setLocale('en') : setLocale('zh');
|
||||
};
|
||||
const message = locale === 'zh' ? zh : en
|
||||
|
||||
const message = locale === 'zh' ? zh : en;
|
||||
|
||||
return (
|
||||
<IntlProvider locale={locale} messages={locale === 'zh' ? zh : en}>
|
||||
<header>Inula-Intl API Test Demo</header>
|
||||
|
||||
<div className='container'>
|
||||
<Example1/>
|
||||
<Example2/>
|
||||
<Example3 locale={locale} setLocale={setLocale}/>
|
||||
<div className="container">
|
||||
<Example1 />
|
||||
<Example2 />
|
||||
<Example3 locale={locale} setLocale={setLocale} />
|
||||
</div>
|
||||
<div className='container'>
|
||||
<Example4 locale={locale} messages={message}/>
|
||||
<Example5/>
|
||||
<Example6 locale={{ locale }} messages={message}/>
|
||||
<div className="container">
|
||||
<Example4 locale={locale} messages={message} />
|
||||
<Example5 />
|
||||
<Example6 locale={{ locale }} messages={message} />
|
||||
</div>
|
||||
<div className='button'>
|
||||
<div className="button">
|
||||
<button onClick={handleChange}>切换语言</button>
|
||||
</div>
|
||||
</IntlProvider>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export default App
|
||||
export default App;
|
||||
|
|
|
@ -13,8 +13,8 @@
|
|||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
import Inula from "openinula";
|
||||
import { useIntl } from "../../index";
|
||||
import Inula from 'openinula';
|
||||
import { useIntl } from '../../index';
|
||||
|
||||
const Example1 = () => {
|
||||
const { i18n } = useIntl();
|
||||
|
|
|
@ -12,16 +12,15 @@
|
|||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
import Inula from "openinula";
|
||||
import { FormattedMessage } from "../../index";
|
||||
|
||||
const Example2= () => {
|
||||
import Inula from 'openinula';
|
||||
import { FormattedMessage } from '../../index';
|
||||
|
||||
const Example2 = () => {
|
||||
return (
|
||||
<div className="card">
|
||||
<h2>FormattedMessage方式测试Demo</h2>
|
||||
<pre>
|
||||
<FormattedMessage id='text2'/>
|
||||
<FormattedMessage id="text2" />
|
||||
</pre>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -14,23 +14,26 @@
|
|||
*/
|
||||
|
||||
import Inula from 'openinula';
|
||||
import { FormattedMessage } from "../../index";
|
||||
import { FormattedMessage } from '../../index';
|
||||
|
||||
const Example3 = (props) => {
|
||||
const Example3 = props => {
|
||||
const { locale, setLocale } = props;
|
||||
return (
|
||||
<div className="card">
|
||||
<h2>FormattedMessage方式测试Demo</h2>
|
||||
<pre>
|
||||
<button className="testButton" onClick={() => {
|
||||
setLocale(locale === 'zh' ? 'en' : 'zh')
|
||||
}}>
|
||||
<FormattedMessage id={'button'}/>
|
||||
<button
|
||||
className="testButton"
|
||||
onClick={() => {
|
||||
setLocale(locale === 'zh' ? 'en' : 'zh');
|
||||
}}
|
||||
>
|
||||
<FormattedMessage id={'button'} />
|
||||
</button>
|
||||
<br/>
|
||||
</pre>
|
||||
<br />
|
||||
</pre>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export default Example3;
|
||||
|
|
|
@ -13,10 +13,10 @@
|
|||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
import Inula from "openinula";
|
||||
import { createIntl } from "../../index";
|
||||
import Inula from 'openinula';
|
||||
import { createIntl } from '../../index';
|
||||
|
||||
const Example4 = (props) => {
|
||||
const Example4 = props => {
|
||||
// 受渲染时机影响,createIntl方式需控制时序,否则慢一拍
|
||||
const intl = createIntl({ ...props });
|
||||
const msg = intl.formatMessage({ id: 'text3' });
|
||||
|
|
|
@ -13,25 +13,21 @@
|
|||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
import Inula from "openinula";
|
||||
import { createIntl, createIntlCache, RawIntlProvider } from "../../index";
|
||||
import Example6Child from "./Example6Child";
|
||||
import Inula from 'openinula';
|
||||
import { createIntl, createIntlCache, RawIntlProvider } from '../../index';
|
||||
import Example6Child from './Example6Child';
|
||||
|
||||
const Example6 = (props: any) => {
|
||||
|
||||
const { locale, messages } = props;
|
||||
|
||||
const cache = createIntlCache();
|
||||
let i18n = createIntl(
|
||||
{ locale: locale, messages: messages },
|
||||
cache
|
||||
);
|
||||
let i18n = createIntl({ locale: locale, messages: messages }, cache);
|
||||
|
||||
return (
|
||||
<RawIntlProvider value={i18n}>
|
||||
<Example6Child/>
|
||||
<Example6Child />
|
||||
</RawIntlProvider>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export default Example6;
|
||||
|
|
|
@ -13,11 +13,10 @@
|
|||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
import { useIntl } from "../../index";
|
||||
import { useIntl } from '../../index';
|
||||
|
||||
const Example6Child = (props: any) => {
|
||||
|
||||
const {formatMessage} = useIntl();
|
||||
const { formatMessage } = useIntl();
|
||||
|
||||
return (
|
||||
<div className="card">
|
||||
|
@ -25,6 +24,6 @@ const Example6Child = (props: any) => {
|
|||
<pre>{formatMessage({ id: 'text4' })}</pre>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export default Example6Child;
|
||||
|
|
|
@ -13,12 +13,9 @@
|
|||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
import * as Inula from 'openinula';
|
||||
import App from './App'
|
||||
import App from './App';
|
||||
|
||||
function render() {
|
||||
Inula.render(
|
||||
<App/>,
|
||||
document.querySelector('#root') as any
|
||||
)
|
||||
Inula.render(<App />, document.querySelector('#root') as any);
|
||||
}
|
||||
render();
|
||||
|
|
|
@ -19,4 +19,4 @@ export default {
|
|||
text2: 'Welcome to the Inula-Intl component!',
|
||||
text3: 'Welcome to the Inula-Intl component!',
|
||||
text4: 'Welcome to the Inula-Intl component!',
|
||||
}
|
||||
};
|
||||
|
|
|
@ -14,26 +14,24 @@
|
|||
*/
|
||||
|
||||
module.exports = {
|
||||
coverageDirectory: 'coverage',
|
||||
resetModules: true,
|
||||
preset: 'ts-jest/presets/js-with-ts',
|
||||
rootDir: process.cwd(),
|
||||
testMatch: [
|
||||
'<rootDir>/tests/**/*.test.[jt]s?(x)'
|
||||
],
|
||||
moduleFileExtensions: ['ts', 'js', 'jsx', 'tsx'],
|
||||
moduleDirectories: ['node_modules', 'src'],
|
||||
moduleNameMapper: {
|
||||
'^@/(.*)$': '<rootDir>/tests/$1',
|
||||
},
|
||||
transform: {
|
||||
"^.+\\.(ts|js|jsx|tsx)$": "babel-jest"
|
||||
},
|
||||
globals: {
|
||||
"ts-jest": {
|
||||
"tsconfig": "tsconfig.json"
|
||||
}
|
||||
coverageDirectory: 'coverage',
|
||||
resetModules: true,
|
||||
preset: 'ts-jest/presets/js-with-ts',
|
||||
rootDir: process.cwd(),
|
||||
testMatch: ['<rootDir>/tests/**/*.test.[jt]s?(x)'],
|
||||
moduleFileExtensions: ['ts', 'js', 'jsx', 'tsx'],
|
||||
moduleDirectories: ['node_modules', 'src'],
|
||||
moduleNameMapper: {
|
||||
'^@/(.*)$': '<rootDir>/tests/$1',
|
||||
},
|
||||
transform: {
|
||||
'^.+\\.(ts|js|jsx|tsx)$': 'babel-jest',
|
||||
},
|
||||
globals: {
|
||||
'ts-jest': {
|
||||
tsconfig: 'tsconfig.json',
|
||||
},
|
||||
},
|
||||
|
||||
testEnvironment: 'jsdom',
|
||||
testEnvironment: 'jsdom',
|
||||
};
|
||||
|
|
|
@ -20,7 +20,6 @@ import nodeResolve from '@rollup/plugin-node-resolve';
|
|||
import typescript from '@rollup/plugin-typescript';
|
||||
import { terser } from 'rollup-plugin-terser';
|
||||
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = path.dirname(__filename);
|
||||
|
||||
|
@ -31,35 +30,29 @@ const output = path.join(__dirname, '/build');
|
|||
const extensions = ['.js', '.ts', '.tsx'];
|
||||
|
||||
export default {
|
||||
input: entry,
|
||||
output: [
|
||||
{
|
||||
file: path.resolve(output, 'intl.umd.js'),
|
||||
name: 'InulaI18n',
|
||||
format: 'umd',
|
||||
},
|
||||
],
|
||||
plugins: [
|
||||
nodeResolve({
|
||||
extensions,
|
||||
modulesOnly: true,
|
||||
}),
|
||||
babel({
|
||||
exclude: 'node_modules/**',
|
||||
configFile: path.join(__dirname, '/babel.config.js'),
|
||||
extensions,
|
||||
}),
|
||||
typescript(
|
||||
{
|
||||
tsconfig: 'tsconfig.json',
|
||||
include: ['./**/*.ts', './**/*.tsx'],
|
||||
}
|
||||
),
|
||||
terser(),
|
||||
],
|
||||
external:[
|
||||
'openinula',
|
||||
'react',
|
||||
'react-dom'
|
||||
]
|
||||
input: entry,
|
||||
output: [
|
||||
{
|
||||
file: path.resolve(output, 'intl.umd.js'),
|
||||
name: 'InulaI18n',
|
||||
format: 'umd',
|
||||
},
|
||||
],
|
||||
plugins: [
|
||||
nodeResolve({
|
||||
extensions,
|
||||
modulesOnly: true,
|
||||
}),
|
||||
babel({
|
||||
exclude: 'node_modules/**',
|
||||
configFile: path.join(__dirname, '/babel.config.js'),
|
||||
extensions,
|
||||
}),
|
||||
typescript({
|
||||
tsconfig: 'tsconfig.json',
|
||||
include: ['./**/*.ts', './**/*.tsx'],
|
||||
}),
|
||||
terser(),
|
||||
],
|
||||
external: ['openinula', 'react', 'react-dom'],
|
||||
};
|
||||
|
|
|
@ -64,7 +64,7 @@ export const REACT_FORWARD_REF_STATICS = {
|
|||
propTypes: true, // type: type,
|
||||
};
|
||||
|
||||
export const FORWARD_REF_STATICS = {...INULA_FORWARD_REF_STATICS, ...REACT_FORWARD_REF_STATICS};
|
||||
export const FORWARD_REF_STATICS = { ...INULA_FORWARD_REF_STATICS, ...REACT_FORWARD_REF_STATICS };
|
||||
|
||||
// Inula Memo 组件的静态属性需要被保留
|
||||
export const INULA_MEMO_STATICS = {
|
||||
|
@ -76,4 +76,3 @@ export const INULA_MEMO_STATICS = {
|
|||
|
||||
// 默认复数规则
|
||||
export const DEFAULT_PLURAL_KEYS = ['zero', 'one', 'two', 'few', 'many', 'other'];
|
||||
|
||||
|
|
|
@ -14,12 +14,12 @@
|
|||
*/
|
||||
|
||||
import EventDispatcher from '../utils/eventListener';
|
||||
import DateTimeFormatter from "../format/fomatters/DateTimeFormatter";
|
||||
import NumberFormatter from "../format/fomatters/NumberFormatter";
|
||||
import DateTimeFormatter from '../format/fomatters/DateTimeFormatter';
|
||||
import NumberFormatter from '../format/fomatters/NumberFormatter';
|
||||
import { getFormatMessage } from '../format/getFormatMessage';
|
||||
import {I18nCache, I18nProps, MessageDescriptor, MessageOptions} from '../types/interfaces';
|
||||
import { I18nCache, I18nProps, MessageDescriptor, MessageOptions } from '../types/interfaces';
|
||||
import { Locale, Locales, Messages, AllLocaleConfig, AllMessages, LocaleConfig, Error, Events } from '../types/types';
|
||||
import creatI18nCache from "../format/cache/cache";
|
||||
import creatI18nCache from '../format/cache/cache';
|
||||
|
||||
export class I18n extends EventDispatcher<Events> {
|
||||
public locale: Locale;
|
||||
|
@ -101,7 +101,7 @@ export class I18n extends EventDispatcher<Events> {
|
|||
} else {
|
||||
// 加载多对locale-message信息
|
||||
localeOrMessages &&
|
||||
Object.keys(localeOrMessages!).forEach(locale => this.setMessage(locale, localeOrMessages![locale]));
|
||||
Object.keys(localeOrMessages!).forEach(locale => this.setMessage(locale, localeOrMessages![locale]));
|
||||
}
|
||||
this.emit('change');
|
||||
}
|
||||
|
@ -118,9 +118,9 @@ export class I18n extends EventDispatcher<Events> {
|
|||
formatMessage(
|
||||
id: MessageDescriptor | string,
|
||||
values: Object | undefined = {},
|
||||
{ message, context, formatOptions}: MessageOptions = {},
|
||||
{ message, context, formatOptions }: MessageOptions = {}
|
||||
) {
|
||||
return getFormatMessage(this, id, values, { message, context, formatOptions});
|
||||
return getFormatMessage(this, id, values, { message, context, formatOptions });
|
||||
}
|
||||
|
||||
formatDate(value: string | Date, formatOptions?: Intl.DateTimeFormatOptions): string {
|
||||
|
|
|
@ -23,7 +23,17 @@ import useI18n from '../hook/useI18n';
|
|||
*/
|
||||
function FormattedMessage(props: FormattedMessageProps) {
|
||||
const { i18n } = useI18n();
|
||||
const { id, values, messages, formatOptions, context, tagName: TagName = Fragment, children, comment, useMemorize }: any = props;
|
||||
const {
|
||||
id,
|
||||
values,
|
||||
messages,
|
||||
formatOptions,
|
||||
context,
|
||||
tagName: TagName = Fragment,
|
||||
children,
|
||||
comment,
|
||||
useMemorize,
|
||||
}: any = props;
|
||||
|
||||
const formatMessageOptions = {
|
||||
comment,
|
||||
|
@ -41,14 +51,10 @@ function FormattedMessage(props: FormattedMessageProps) {
|
|||
}
|
||||
|
||||
if (TagName) {
|
||||
return (
|
||||
<TagName>{Children.toArray(formattedMessage)}</TagName>
|
||||
);
|
||||
return <TagName>{Children.toArray(formattedMessage)}</TagName>;
|
||||
}
|
||||
|
||||
return (
|
||||
<>{formattedMessage}</>
|
||||
);
|
||||
return <>{formattedMessage}</>;
|
||||
}
|
||||
|
||||
export default FormattedMessage;
|
||||
|
|
|
@ -12,14 +12,14 @@
|
|||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
import Inula , { createContext, forwardRef } from 'openinula';
|
||||
import Inula, { createContext, forwardRef } from 'openinula';
|
||||
import { isVariantI18n } from '../../utils/utils';
|
||||
import copyStaticProps from '../../utils/copyStaticProps';
|
||||
import { InjectOptions } from '../../types/interfaces';
|
||||
import I18n from "../I18n";
|
||||
import I18n from '../I18n';
|
||||
|
||||
// 创建国际化组件对象上下文
|
||||
export const I18nContext : any = createContext<I18n>(null as any);
|
||||
export const I18nContext: any = createContext<I18n>(null as any);
|
||||
const { Consumer, Provider } = I18nContext;
|
||||
export const InjectProvider = Provider;
|
||||
|
||||
|
@ -54,9 +54,7 @@ function injectI18n(Component, options?: InjectOptions): any {
|
|||
|
||||
// 通过copyStatics方法,复制组件中的静态属性
|
||||
return copyStaticProps(
|
||||
isUsingForwardRef ?
|
||||
forwardRef((props, ref) => <WrappedI18n {...props} forwardedRef={ref} />) :
|
||||
WrappedI18n,
|
||||
isUsingForwardRef ? forwardRef((props, ref) => <WrappedI18n {...props} forwardedRef={ref} />) : WrappedI18n,
|
||||
Component
|
||||
);
|
||||
}
|
||||
|
|
|
@ -15,8 +15,8 @@
|
|||
|
||||
import { CompiledMessage, Locale, LocaleConfig, Locales } from '../types/types';
|
||||
import generateFormatters from './generateFormatters';
|
||||
import {FormatOptions, I18nCache} from '../types/interfaces';
|
||||
import {createIntlCache} from "../../index";
|
||||
import { FormatOptions, I18nCache } from '../types/interfaces';
|
||||
import { createIntlCache } from '../../index';
|
||||
|
||||
/**
|
||||
* 获取翻译结果
|
||||
|
@ -46,7 +46,7 @@ class Translation {
|
|||
locales: Locales,
|
||||
values: object,
|
||||
formatOptions: FormatOptions,
|
||||
localeConfig: LocaleConfig,
|
||||
localeConfig: LocaleConfig
|
||||
) => {
|
||||
const textFormatter = (name: string, type: string, format: any) => {
|
||||
const formatters = generateFormatters(locale, locales, localeConfig, formatOptions, this.cache);
|
||||
|
@ -66,13 +66,7 @@ class Translation {
|
|||
return textFormatter;
|
||||
};
|
||||
|
||||
let textFormatter = createTextFormatter(
|
||||
this.locale,
|
||||
this.locales,
|
||||
values,
|
||||
formatOptions,
|
||||
this.localeConfig,
|
||||
);
|
||||
let textFormatter = createTextFormatter(this.locale, this.locales, values, formatOptions, this.localeConfig);
|
||||
// 通过递归方法formatCore进行格式化处理
|
||||
const result = this.formatMessage(this.compiledMessage, textFormatter);
|
||||
return result; // 返回要格式化的结果
|
||||
|
@ -83,28 +77,29 @@ class Translation {
|
|||
return compiledMessage;
|
||||
}
|
||||
|
||||
return compiledMessage.map(token => {
|
||||
if (typeof token === 'string') {
|
||||
return token;
|
||||
}
|
||||
return compiledMessage
|
||||
.map(token => {
|
||||
if (typeof token === 'string') {
|
||||
return token;
|
||||
}
|
||||
|
||||
const [name, type, format] = token;
|
||||
const [name, type, format] = token;
|
||||
|
||||
let replaceValueFormat = format;
|
||||
|
||||
let replaceValueFormat = format;
|
||||
|
||||
// 如果 format 是对象,函数将递归地对它的每个值调用 formatMessage 后保存,否则直接保存
|
||||
if (format && typeof format !== 'string') {
|
||||
replaceValueFormat = Object.keys(replaceValueFormat).reduce((text, key) => {
|
||||
text[key] = this.formatMessage(format[key], textFormatter);
|
||||
return text;
|
||||
}, {});
|
||||
}
|
||||
//调用 getContent 函数来获取给定 name、type 和 interpolateFormat 的值
|
||||
const value = textFormatter(name, type, replaceValueFormat);
|
||||
return value ?? `{${name}}`;
|
||||
}).join('');
|
||||
};
|
||||
// 如果 format 是对象,函数将递归地对它的每个值调用 formatMessage 后保存,否则直接保存
|
||||
if (format && typeof format !== 'string') {
|
||||
replaceValueFormat = Object.keys(replaceValueFormat).reduce((text, key) => {
|
||||
text[key] = this.formatMessage(format[key], textFormatter);
|
||||
return text;
|
||||
}, {});
|
||||
}
|
||||
//调用 getContent 函数来获取给定 name、type 和 interpolateFormat 的值
|
||||
const value = textFormatter(name, type, replaceValueFormat);
|
||||
return value ?? `{${name}}`;
|
||||
})
|
||||
.join('');
|
||||
}
|
||||
}
|
||||
|
||||
export default Translation;
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
import creatI18nCache from '../cache/cache';
|
||||
import utils from '../../utils/utils';
|
||||
import { DatePool, Locales } from '../../types/types';
|
||||
import {I18nCache} from "../../types/interfaces";
|
||||
import { I18nCache } from '../../types/interfaces';
|
||||
|
||||
/**
|
||||
* 时间格式化
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
import creatI18nCache from '../cache/cache';
|
||||
import { Locales } from '../../types/types';
|
||||
import utils from '../../utils/utils';
|
||||
import {I18nCache} from "../../types/interfaces";
|
||||
import { I18nCache } from '../../types/interfaces';
|
||||
|
||||
/**
|
||||
* 数字格式化
|
||||
|
|
|
@ -16,8 +16,8 @@
|
|||
import utils from '../../utils/utils';
|
||||
import NumberFormatter from './NumberFormatter';
|
||||
import { Locale, Locales } from '../../types/types';
|
||||
import {I18nCache} from "../../types/interfaces";
|
||||
import {createIntlCache} from "../../../index";
|
||||
import { I18nCache } from '../../types/interfaces';
|
||||
import { createIntlCache } from '../../../index';
|
||||
|
||||
/**
|
||||
* 复数格式化
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
import utils from '../../utils/utils';
|
||||
import { Locale } from '../../types/types';
|
||||
import {I18nCache} from "../../types/interfaces";
|
||||
import { I18nCache } from '../../types/interfaces';
|
||||
|
||||
/**
|
||||
* 规则选择器
|
||||
|
|
|
@ -18,8 +18,8 @@ import NumberFormatter from './fomatters/NumberFormatter';
|
|||
import { DatePool, Locale, Locales, SelectPool } from '../types/types';
|
||||
import PluralFormatter from './fomatters/PluralFormatter';
|
||||
import SelectFormatter from './fomatters/SelectFormatter';
|
||||
import {FormatOptions, I18nCache, IntlMessageFormat} from '../types/interfaces';
|
||||
import cache from "./cache/cache";
|
||||
import { FormatOptions, I18nCache, IntlMessageFormat } from '../types/interfaces';
|
||||
import cache from './cache/cache';
|
||||
|
||||
/**
|
||||
* 默认格式化接口
|
||||
|
@ -86,10 +86,7 @@ const generateFormatters = (
|
|||
* @param useMemorize
|
||||
*/
|
||||
dateTimeFormat: (value: DatePool, formatOption) => {
|
||||
return new DateTimeFormatter(locales, getStyleOption(formatOption), cache).dateTimeFormat(
|
||||
value,
|
||||
formatOption
|
||||
);
|
||||
return new DateTimeFormatter(locales, getStyleOption(formatOption), cache).dateTimeFormat(value, formatOption);
|
||||
},
|
||||
|
||||
// 用于处理未定义的值,接受一个值并直接返回它。
|
||||
|
|
|
@ -18,7 +18,7 @@ import Translation from './Translation';
|
|||
import I18n from '../core/I18n';
|
||||
import { MessageDescriptor, MessageOptions } from '../types/interfaces';
|
||||
import { CompiledMessage } from '../types/types';
|
||||
import creatI18nCache from "./cache/cache";
|
||||
import creatI18nCache from './cache/cache';
|
||||
|
||||
export function getFormatMessage(
|
||||
i18n: I18n,
|
||||
|
|
|
@ -13,16 +13,7 @@
|
|||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
import {
|
||||
AllLocaleConfig,
|
||||
AllMessages,
|
||||
Locale,
|
||||
Locales,
|
||||
Error,
|
||||
DatePool,
|
||||
SelectPool,
|
||||
RawToken,
|
||||
} from './types';
|
||||
import { AllLocaleConfig, AllMessages, Locale, Locales, Error, DatePool, SelectPool, RawToken } from './types';
|
||||
import I18n from '../core/I18n';
|
||||
import Lexer from '../parser/Lexer';
|
||||
|
||||
|
@ -94,24 +85,24 @@ export interface configProps {
|
|||
|
||||
export interface IntlMessageFormat extends configProps, MessageOptions {
|
||||
plural: (
|
||||
value: number,
|
||||
{
|
||||
offset,
|
||||
...rules
|
||||
}: {
|
||||
[x: string]: any;
|
||||
offset?: number | undefined;
|
||||
}
|
||||
value: number,
|
||||
{
|
||||
offset,
|
||||
...rules
|
||||
}: {
|
||||
[x: string]: any;
|
||||
offset?: number | undefined;
|
||||
}
|
||||
) => (ctx: any) => any[];
|
||||
selectordinal: (
|
||||
value: number,
|
||||
{
|
||||
offset,
|
||||
...rules
|
||||
}: {
|
||||
[x: string]: any;
|
||||
offset?: number | undefined;
|
||||
}
|
||||
value: number,
|
||||
{
|
||||
offset,
|
||||
...rules
|
||||
}: {
|
||||
[x: string]: any;
|
||||
offset?: number | undefined;
|
||||
}
|
||||
) => (ctx: any) => any[];
|
||||
select: (value: SelectPool, formatRules: any) => any;
|
||||
numberFormat: (value: number, formatOption: any) => string;
|
||||
|
@ -200,7 +191,6 @@ export interface Select {
|
|||
}
|
||||
|
||||
export interface InjectedIntl {
|
||||
|
||||
// 日期格式化
|
||||
formatDate(value: DatePool, options?: Intl.DateTimeFormatOptions): string;
|
||||
|
||||
|
|
|
@ -13,12 +13,7 @@
|
|||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
import { isMemo, ForwardRef } from 'openinula';
|
||||
import {
|
||||
INULA_FORWARD_REF_STATICS,
|
||||
INULA_MEMO_STATICS,
|
||||
INULA_STATICS,
|
||||
NATIVE_STATICS,
|
||||
} from '../constants';
|
||||
import { INULA_FORWARD_REF_STATICS, INULA_MEMO_STATICS, INULA_STATICS, NATIVE_STATICS } from '../constants';
|
||||
|
||||
const staticsMap = new Map();
|
||||
staticsMap.set(ForwardRef, INULA_FORWARD_REF_STATICS);
|
||||
|
@ -29,7 +24,7 @@ function getStatics(component) {
|
|||
return INULA_MEMO_STATICS;
|
||||
}
|
||||
|
||||
if (staticsMap.has(component['vtype'])) {
|
||||
if (staticsMap.has(component['vtype'])) {
|
||||
return staticsMap.get(component['vtype']) || INULA_STATICS;
|
||||
}
|
||||
}
|
||||
|
@ -83,6 +78,6 @@ function copyStaticProps<T, U>(targetComponent: T, sourceComponent: U): T {
|
|||
});
|
||||
|
||||
return targetComponent;
|
||||
};
|
||||
}
|
||||
|
||||
export default copyStaticProps;
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
import { EventCallback } from "../types/types";
|
||||
import { EventCallback } from '../types/types';
|
||||
|
||||
/**
|
||||
* 定义一个时间触发器类,使用泛型实现动态时间的监听
|
||||
|
|
|
@ -25,11 +25,14 @@ enum TokenType {
|
|||
const processToken = token => {
|
||||
if (typeof token === 'string') {
|
||||
return token;
|
||||
} else if (TokenType[token.type] === 'OCTOTHORPE') { // token为符号
|
||||
} else if (TokenType[token.type] === 'OCTOTHORPE') {
|
||||
// token为符号
|
||||
return '#';
|
||||
} else if (TokenType[token.type] === 'ARGUMENT') { // token为变量
|
||||
} else if (TokenType[token.type] === 'ARGUMENT') {
|
||||
// token为变量
|
||||
return [token.arg];
|
||||
} else if (TokenType[token.type] === 'FUNCTION') { // token为函数方法
|
||||
} else if (TokenType[token.type] === 'FUNCTION') {
|
||||
// token为函数方法
|
||||
const _param = token.param && token.param.tokens[0];
|
||||
const param = typeof _param === 'string' ? _param.trim() : _param;
|
||||
return [token.arg, token.key, param].filter(Boolean);
|
||||
|
|
|
@ -12,12 +12,10 @@
|
|||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
import { CompiledMessage } from "../types/types";
|
||||
import parse from "../parser/parser";
|
||||
import getTokenAST from "./getTokenAST";
|
||||
import I18n from "../core/I18n";
|
||||
|
||||
|
||||
import { CompiledMessage } from '../types/types';
|
||||
import parse from '../parser/parser';
|
||||
import getTokenAST from './getTokenAST';
|
||||
import I18n from '../core/I18n';
|
||||
|
||||
export function isVariantI18n(i18n?: I18n) {
|
||||
if (!i18n) {
|
||||
|
@ -43,6 +41,6 @@ const utils = {
|
|||
isVariantI18n,
|
||||
generateKey,
|
||||
compile,
|
||||
}
|
||||
};
|
||||
|
||||
export default utils;
|
||||
|
|
|
@ -17,7 +17,7 @@ import I18nProvider from '../../../src/core/components/I18nProvider';
|
|||
import { FormattedMessage } from '../../../index';
|
||||
import { render } from '@testing-library/react';
|
||||
import '@testing-library/jest-dom';
|
||||
import {createI18nInstance} from "../../../src/core/I18n";
|
||||
import { createI18nInstance } from '../../../src/core/I18n';
|
||||
|
||||
const dummyContext = React.createContext('');
|
||||
const { Provider: DummyProvider, Consumer: DummyConsumer } = dummyContext;
|
||||
|
|
|
@ -17,7 +17,7 @@ import * as React from 'react';
|
|||
import { act, render } from '@testing-library/react';
|
||||
import '@testing-library/jest-dom/extend-expect';
|
||||
import { IntlProvider } from '../../../index';
|
||||
import {createI18nInstance} from "../../../src/core/I18n";
|
||||
import { createI18nInstance } from '../../../src/core/I18n';
|
||||
|
||||
describe('I18nProvider', () => {
|
||||
afterEach(() => {
|
||||
|
@ -61,11 +61,7 @@ describe('I18nProvider', () => {
|
|||
i18n.on = jest.fn(() => jest.fn());
|
||||
expect(i18n.on).not.toBeCalled();
|
||||
render(
|
||||
<IntlProvider
|
||||
key={locale}
|
||||
locale={locale}
|
||||
messages={{}}
|
||||
>
|
||||
<IntlProvider key={locale} locale={locale} messages={{}}>
|
||||
<p />
|
||||
</IntlProvider>
|
||||
);
|
||||
|
@ -78,9 +74,9 @@ describe('I18nProvider', () => {
|
|||
i18n.on = jest.fn(() => jest.fn());
|
||||
expect(i18n.on).not.toBeCalled();
|
||||
render(
|
||||
<IntlProvider i18n={i18n}>
|
||||
<p />
|
||||
</IntlProvider>
|
||||
<IntlProvider i18n={i18n}>
|
||||
<p />
|
||||
</IntlProvider>
|
||||
);
|
||||
setTimeout(() => {
|
||||
expect(i18n.on).toBeCalledWith('change', expect.anything());
|
||||
|
|
|
@ -53,6 +53,8 @@ describe('InjectIntl', () => {
|
|||
};
|
||||
|
||||
const { getByTestId } = mountWithProvider(<Injected {...props} />);
|
||||
expect(getByTestId('test')).toHaveTextContent('{"_events":{},"locale":"en","locales":["en"],"allMessages":{},"_localeData":{}}');
|
||||
expect(getByTestId('test')).toHaveTextContent(
|
||||
'{"_events":{},"locale":"en","locales":["en"],"allMessages":{},"_localeData":{}}'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -41,6 +41,3 @@ describe('createI18n', () => {
|
|||
expect(onWarn).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
*/
|
||||
|
||||
import Translation from '../../src/format/Translation';
|
||||
import {createIntlCache} from "../../index";
|
||||
import { createIntlCache } from '../../index';
|
||||
|
||||
describe('Translation', () => {
|
||||
let translation;
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
*/
|
||||
|
||||
import { DateTimeFormatter } from '../../../index';
|
||||
import creatI18nCache from "../../../src/format/cache/cache";
|
||||
import creatI18nCache from '../../../src/format/cache/cache';
|
||||
|
||||
describe('DateTimeFormatter', () => {
|
||||
const date = new Date('2023-04-03T12:34:56Z');
|
||||
|
@ -92,7 +92,7 @@ describe('DateTimeFormatter', () => {
|
|||
});
|
||||
|
||||
it('should format using memorized formatter when useMemorize is true', () => {
|
||||
const formatter = new DateTimeFormatter('en-US',{"year":'numeric'}, creatI18nCache());
|
||||
const formatter = new DateTimeFormatter('en-US', { year: 'numeric' }, creatI18nCache());
|
||||
const date = new Date(2023, 0, 1);
|
||||
const formatted1 = formatter.dateTimeFormat(date);
|
||||
const formatted2 = formatter.dateTimeFormat(date);
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
*/
|
||||
|
||||
import { NumberFormatter } from '../../../index';
|
||||
import creatI18nCache from "../../../src/format/cache/cache";
|
||||
import creatI18nCache from '../../../src/format/cache/cache';
|
||||
|
||||
describe('NumberFormatter', () => {
|
||||
it('number formatter is memoized', async () => {
|
||||
|
@ -58,7 +58,6 @@ describe('NumberFormatter', () => {
|
|||
const format1 = new NumberFormatter('en-US', { style: 'currency', currency: 'USD' });
|
||||
const format2 = new NumberFormatter('fr-FR', { style: 'currency', currency: 'EUR' });
|
||||
expect(format1.numberFormat(1000)).toBe('$1,000.00');
|
||||
|
||||
});
|
||||
it('should format a positive number correctly', () => {
|
||||
const formatter = new NumberFormatter('en-US');
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
/*
|
||||
* Copyright (c) 2023 Huawei Technologies Co.,Ltd.
|
||||
*
|
||||
|
|
|
@ -31,15 +31,17 @@ module.exports = {
|
|||
use: {
|
||||
loader: 'babel-loader',
|
||||
options: {
|
||||
presets: ['@babel/preset-env',
|
||||
presets: [
|
||||
'@babel/preset-env',
|
||||
[
|
||||
'@babel/preset-react',
|
||||
{
|
||||
'runtime': 'automatic', // 新增
|
||||
'importSource': 'openinula' // 新增
|
||||
}
|
||||
'@babel/preset-react',
|
||||
{
|
||||
runtime: 'automatic', // 新增
|
||||
importSource: 'openinula', // 新增
|
||||
},
|
||||
],
|
||||
'@babel/preset-typescript',
|
||||
],
|
||||
'@babel/preset-typescript'],
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
|
@ -19,15 +19,13 @@ module.exports = {
|
|||
'@babel/preset-env',
|
||||
{
|
||||
targets: {
|
||||
'browsers' : ['> 1%', 'last 2 versions', 'not ie <= 8'],
|
||||
'node': 'current'
|
||||
browsers: ['> 1%', 'last 2 versions', 'not ie <= 8'],
|
||||
node: 'current',
|
||||
},
|
||||
useBuiltIns: 'usage',
|
||||
corejs: 3,
|
||||
}
|
||||
},
|
||||
],
|
||||
[
|
||||
'@babel/preset-typescript',
|
||||
]
|
||||
]
|
||||
['@babel/preset-typescript'],
|
||||
],
|
||||
};
|
||||
|
|
|
@ -17,27 +17,27 @@ import Inula, { useState } from 'openinula';
|
|||
import { useIR } from '../../index';
|
||||
|
||||
const App = () => {
|
||||
|
||||
const [message, setMessage] = useState('等待发送请求...');
|
||||
const [isSent, setSend] = useState(false);
|
||||
const options = {
|
||||
pollingInterval: 3000,
|
||||
enablePollingOptimization: true,
|
||||
limitation: {minInterval: 500, maxInterval: 4000}
|
||||
limitation: { minInterval: 500, maxInterval: 4000 },
|
||||
};
|
||||
const {data} = useIR('http://localhost:3001/', null, options);
|
||||
const { data } = useIR('http://localhost:3001/', null, options);
|
||||
|
||||
const handleClick = () => {
|
||||
setSend(true);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<header>useHR Test</header>
|
||||
<div className="container">
|
||||
<div className="card">
|
||||
<h2 style={{whiteSpace: "pre-wrap"}}>{options ? `实时数据流已激活\n更新间隔:${options?.pollingInterval} ms`
|
||||
: '实时数据流未激活'}</h2>
|
||||
<h2 style={{ whiteSpace: 'pre-wrap' }}>
|
||||
{options ? `实时数据流已激活\n更新间隔:${options?.pollingInterval} ms` : '实时数据流未激活'}
|
||||
</h2>
|
||||
<pre>{isSent ? data : message}</pre>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -46,6 +46,6 @@ const App = () => {
|
|||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export default App;
|
||||
|
|
|
@ -14,11 +14,11 @@
|
|||
*/
|
||||
|
||||
import Inula from 'openinula';
|
||||
import App from "./App ";
|
||||
import App from './App ';
|
||||
|
||||
Inula.render(
|
||||
<Inula.Fragment>
|
||||
<App/>
|
||||
<App />
|
||||
</Inula.Fragment>,
|
||||
document.querySelector('#root')
|
||||
)
|
||||
);
|
||||
|
|
|
@ -38,10 +38,8 @@ export default {
|
|||
terser(),
|
||||
babel({
|
||||
babelHelpers: 'bundled',
|
||||
presets: ['@babel/preset-env']
|
||||
})
|
||||
],
|
||||
external:[
|
||||
'openinula'
|
||||
presets: ['@babel/preset-env'],
|
||||
}),
|
||||
],
|
||||
external: ['openinula'],
|
||||
};
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue