mirror of
https://github.com/encounter/objdiff-web.git
synced 2026-07-10 12:18:37 -07:00
Add standalone web build & decomp.me integration
This commit is contained in:
@@ -0,0 +1 @@
|
||||
BUILD_TYPE=extension
|
||||
@@ -1,2 +0,0 @@
|
||||
NODE_ENV=development
|
||||
DEV_SERVER=false
|
||||
Vendored
+2
-2
@@ -5,13 +5,13 @@
|
||||
"tasks": [
|
||||
{
|
||||
"type": "npm",
|
||||
"script": "watch",
|
||||
"script": "extension:dev",
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
},
|
||||
"isBackground": true,
|
||||
"label": "npm:watch",
|
||||
"label": "npm:extension:dev",
|
||||
"presentation": {
|
||||
"group": "watch",
|
||||
"reveal": "never"
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
.vscode/**
|
||||
.vscode-test/**
|
||||
out/**
|
||||
node_modules/**
|
||||
src/**
|
||||
webview/**
|
||||
shared/**
|
||||
.gitignore
|
||||
.yarnrc
|
||||
rsbuild.config.ts
|
||||
**/tsconfig.json
|
||||
**/biome.json
|
||||
**/*.map
|
||||
**/*.ts
|
||||
**/.vscode-test.*
|
||||
.env*
|
||||
@@ -1,22 +1,46 @@
|
||||
# objdiff-code
|
||||
# objdiff-web
|
||||
|
||||
> [!WARNING]
|
||||
> This extension is in early development and is **not yet ready for use**.
|
||||
Web interface for [objdiff](https://github.com/encounter/objdiff): a local diffing tool for decompilation projects.
|
||||
|
||||
This project contains both a standalone web interface and a [Visual Studio Code extension](https://marketplace.visualstudio.com/items?itemName=decomp-dev.objdiff).
|
||||
|
||||
<p align="center">
|
||||
<img src="./assets/screenshot_symbols.png" alt="Symbols view" width="45%" style="margin-right: 10px" />
|
||||
<img src="./assets/screenshot_diff.png" alt="Diff view" width="45%" />
|
||||
</p>
|
||||
|
||||
## How It Works
|
||||
|
||||
The object parsing and diffing is powered by [objdiff-core](https://github.com/encounter/objdiff/tree/main/objdiff-core), compiled into a [WebAssembly Component](https://component-model.bytecodealliance.org/). The [API](https://github.com/encounter/objdiff/blob/main/objdiff-wasm/wit/objdiff.wit) is defined using [WIT](https://component-model.bytecodealliance.org/design/wit.html).
|
||||
|
||||
Performance is a priority, so the web stack is deliberately minimal. The application loads from scratch in under 200ms and diffs large object files in 20ms. The build system, powered by [Rsbuild](https://rsbuild.dev/), produces a production build in under 300ms, with near-instantaneous live reloading during development.
|
||||
|
||||
## Setup
|
||||
|
||||
Open the project in Visual Studio Code.
|
||||
|
||||
- Install dependencies:
|
||||
|
||||
```bash
|
||||
pnpm install
|
||||
```
|
||||
|
||||
- Start dev server using `Ctrl+Shift+B` or by running:
|
||||
## Run Dev Server
|
||||
|
||||
- Start the dev server using:
|
||||
|
||||
```bash
|
||||
pnpm watch
|
||||
pnpm web:dev
|
||||
```
|
||||
|
||||
- Visit [http://localhost:3000/](http://localhost:3000/). (The port may change if it is already in use.)
|
||||
|
||||
## Run Extension
|
||||
|
||||
- Open the project in Visual Studio Code.
|
||||
|
||||
- Start the extension build using `Ctrl+Shift+B` or by running:
|
||||
|
||||
```bash
|
||||
pnpm extension:dev
|
||||
```
|
||||
|
||||
- Run the extension in debug mode using `F5`.
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 352 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 368 KiB |
+27
-93
@@ -6,22 +6,25 @@
|
||||
"version": "0.1.0",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/encounter/objdiff-code"
|
||||
"url": "https://github.com/encounter/objdiff-web"
|
||||
},
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"build": "rsbuild build",
|
||||
"watch": "rsbuild build -w --env-mode watch",
|
||||
"dev": "rsbuild dev --env-mode dev",
|
||||
"check": "biome check --write",
|
||||
"format": "biome format --write"
|
||||
"format": "biome format --write",
|
||||
"web:build": "rsbuild build",
|
||||
"web:dev": "rsbuild dev",
|
||||
"extension:build": "rsbuild build --env-mode extension",
|
||||
"extension:dev": "rsbuild build -w -m development --env-mode extension",
|
||||
"extension:package": "pnpm run extension:build && vsce package --no-dependencies",
|
||||
"extension:publish": "pnpm run extension:build && vsce publish --no-dependencies"
|
||||
},
|
||||
"dependencies": {
|
||||
"@protobuf-ts/runtime": "^2.9.4",
|
||||
"@vscode/codicons": "^0.0.36",
|
||||
"clsx": "^2.1.1",
|
||||
"memoize-one": "^6.0.0",
|
||||
"objdiff-wasm": "^3.0.0-alpha.1",
|
||||
"objdiff-wasm": "3.0.0-beta.1",
|
||||
"picomatch": "^4.0.2",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
@@ -46,22 +49,18 @@
|
||||
"@types/vscode-webview": "^1.57.5",
|
||||
"@vscode/test-cli": "^0.0.10",
|
||||
"@vscode/test-electron": "^2.4.1",
|
||||
"@vscode/vsce": "^3.2.2",
|
||||
"tsx": "^4.19.2",
|
||||
"typescript": "^5.7.2"
|
||||
},
|
||||
"main": "./dist/extension.js",
|
||||
"files": ["LICENSE", "README.md", "package.json", "dist", "media"],
|
||||
"engines": {
|
||||
"vscode": "^1.96.0"
|
||||
},
|
||||
"browserslist": [
|
||||
"chrome 128"
|
||||
],
|
||||
"categories": [
|
||||
"Other"
|
||||
],
|
||||
"activationEvents": [
|
||||
"onWebviewPanel:objdiff"
|
||||
],
|
||||
"browserslist": ["chrome 128"],
|
||||
"categories": ["Other"],
|
||||
"activationEvents": ["onWebviewPanel:objdiff"],
|
||||
"contributes": {
|
||||
"commands": [
|
||||
{
|
||||
@@ -103,24 +102,14 @@
|
||||
"type": "string",
|
||||
"description": "How relocation targets will be diffed in the function view.",
|
||||
"default": "name_address",
|
||||
"enum": [
|
||||
"none",
|
||||
"name_address",
|
||||
"data_value",
|
||||
"all"
|
||||
],
|
||||
"enum": ["none", "name_address", "data_value", "all"],
|
||||
"enumItemLabels": [
|
||||
"None",
|
||||
"Name or address",
|
||||
"Data value",
|
||||
"Name or address, data value"
|
||||
],
|
||||
"enumDescriptions": [
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null
|
||||
]
|
||||
"enumDescriptions": [null, null, null, null]
|
||||
},
|
||||
"objdiff.spaceBetweenArgs": {
|
||||
"type": "boolean",
|
||||
@@ -146,24 +135,14 @@
|
||||
"type": "string",
|
||||
"description": "ARM architecture version to use for disassembly.",
|
||||
"default": "auto",
|
||||
"enum": [
|
||||
"auto",
|
||||
"v4t",
|
||||
"v5te",
|
||||
"v6k"
|
||||
],
|
||||
"enum": ["auto", "v4t", "v5te", "v6k"],
|
||||
"enumItemLabels": [
|
||||
"Auto",
|
||||
"ARMv4T (GBA)",
|
||||
"ARMv5TE (DS)",
|
||||
"ARMv6K (3DS)"
|
||||
],
|
||||
"enumDescriptions": [
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null
|
||||
]
|
||||
"enumDescriptions": [null, null, null, null]
|
||||
},
|
||||
"objdiff.arm.unifiedSyntax": {
|
||||
"type": "boolean",
|
||||
@@ -178,11 +157,7 @@
|
||||
"objdiff.arm.r9Usage": {
|
||||
"type": "string",
|
||||
"default": "generalPurpose",
|
||||
"enum": [
|
||||
"generalPurpose",
|
||||
"sb",
|
||||
"tr"
|
||||
],
|
||||
"enum": ["generalPurpose", "sb", "tr"],
|
||||
"enumItemLabels": [
|
||||
"R9 or V6",
|
||||
"SB (static base)",
|
||||
@@ -218,24 +193,9 @@
|
||||
"type": "string",
|
||||
"description": "MIPS ABI to use for disassembly.",
|
||||
"default": "auto",
|
||||
"enum": [
|
||||
"auto",
|
||||
"o32",
|
||||
"n32",
|
||||
"n64"
|
||||
],
|
||||
"enumItemLabels": [
|
||||
"Auto",
|
||||
"O32",
|
||||
"N32",
|
||||
"N64"
|
||||
],
|
||||
"enumDescriptions": [
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null
|
||||
]
|
||||
"enum": ["auto", "o32", "n32", "n64"],
|
||||
"enumItemLabels": ["Auto", "O32", "N32", "N64"],
|
||||
"enumDescriptions": [null, null, null, null]
|
||||
},
|
||||
"objdiff.mips.instrCategory": {
|
||||
"type": "string",
|
||||
@@ -257,14 +217,7 @@
|
||||
"R4000 ALLEGREX (PSP)",
|
||||
"R5900 EE (PS2)"
|
||||
],
|
||||
"enumDescriptions": [
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null
|
||||
]
|
||||
"enumDescriptions": [null, null, null, null, null, null]
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -275,24 +228,9 @@
|
||||
"type": "string",
|
||||
"description": "x86 disassembly syntax.",
|
||||
"default": "intel",
|
||||
"enum": [
|
||||
"intel",
|
||||
"gas",
|
||||
"nasm",
|
||||
"masm"
|
||||
],
|
||||
"enumItemLabels": [
|
||||
"Intel",
|
||||
"AT&T",
|
||||
"NASM",
|
||||
"MASM"
|
||||
],
|
||||
"enumDescriptions": [
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null
|
||||
]
|
||||
"enum": ["intel", "gas", "nasm", "masm"],
|
||||
"enumItemLabels": ["Intel", "AT&T", "NASM", "MASM"],
|
||||
"enumDescriptions": [null, null, null, null]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -340,10 +278,6 @@
|
||||
]
|
||||
},
|
||||
"pnpm": {
|
||||
"onlyBuiltDependencies": [
|
||||
"@biomejs/biome",
|
||||
"core-js",
|
||||
"esbuild"
|
||||
]
|
||||
"onlyBuiltDependencies": ["@biomejs/biome", "core-js", "esbuild"]
|
||||
}
|
||||
}
|
||||
|
||||
Generated
+1361
-5
File diff suppressed because it is too large
Load Diff
+45
-18
@@ -1,28 +1,38 @@
|
||||
import fs from 'node:fs';
|
||||
import type { ServerResponse } from 'node:http';
|
||||
import path from 'node:path';
|
||||
import { type RequestHandler, defineConfig } from '@rsbuild/core';
|
||||
import {
|
||||
type RequestHandler,
|
||||
type RsbuildConfig,
|
||||
defineConfig,
|
||||
} from '@rsbuild/core';
|
||||
import { pluginReact } from '@rsbuild/plugin-react';
|
||||
import { pluginTypeCheck } from '@rsbuild/plugin-type-check';
|
||||
import { pluginTypedCSSModules } from '@rsbuild/plugin-typed-css-modules';
|
||||
|
||||
const devServer = process.env.DEV_SERVER === 'true';
|
||||
|
||||
export default defineConfig({
|
||||
// Disable HMR and live reload. Neither the extension nor the
|
||||
// webview can communicate with the rsbuild dev server.
|
||||
// Standalone web configuration.
|
||||
const webConfig: RsbuildConfig = {
|
||||
source: {
|
||||
entry: {
|
||||
index: './webview/index.tsx',
|
||||
},
|
||||
},
|
||||
html: {
|
||||
title: 'objdiff',
|
||||
},
|
||||
plugins: [pluginReact(), pluginTypeCheck(), pluginTypedCSSModules()],
|
||||
dev: {
|
||||
hmr: devServer,
|
||||
liveReload: devServer,
|
||||
setupMiddlewares: [
|
||||
(middlewares, _server) => {
|
||||
if (devServer) {
|
||||
middlewares.unshift(apiMiddleware);
|
||||
}
|
||||
middlewares.unshift(apiMiddleware);
|
||||
return middlewares;
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
// VS Code extension configuration.
|
||||
const extensionConfig: RsbuildConfig = {
|
||||
environments: {
|
||||
extension: {
|
||||
source: {
|
||||
@@ -52,9 +62,9 @@ export default defineConfig({
|
||||
// VS Code webviews don't have easy access to resources,
|
||||
// (especially if the extension is running on web) so we
|
||||
// simply inline everything into the HTML.
|
||||
dataUriLimit: devServer ? undefined : 1000000000,
|
||||
inlineScripts: !devServer,
|
||||
inlineStyles: !devServer,
|
||||
dataUriLimit: 1000000000,
|
||||
inlineScripts: true,
|
||||
inlineStyles: true,
|
||||
legalComments: 'none',
|
||||
},
|
||||
// <script defer> doesn't work with inline scripts,
|
||||
@@ -66,7 +76,7 @@ export default defineConfig({
|
||||
},
|
||||
plugins: [
|
||||
pluginReact({
|
||||
fastRefresh: devServer,
|
||||
fastRefresh: false,
|
||||
}),
|
||||
pluginTypedCSSModules(),
|
||||
],
|
||||
@@ -76,7 +86,7 @@ export default defineConfig({
|
||||
// the webview must be self-contained files.
|
||||
performance: {
|
||||
chunkSplit: {
|
||||
strategy: devServer ? undefined : 'all-in-one',
|
||||
strategy: 'all-in-one',
|
||||
},
|
||||
},
|
||||
// Enable async TypeScript type checking.
|
||||
@@ -87,16 +97,33 @@ export default defineConfig({
|
||||
tools: {
|
||||
rspack: {
|
||||
output: {
|
||||
asyncChunks: devServer,
|
||||
asyncChunks: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
// Disable HMR and live reload. Neither the extension nor the
|
||||
// webview can communicate with the rsbuild dev server.
|
||||
dev: {
|
||||
hmr: false,
|
||||
liveReload: false,
|
||||
},
|
||||
};
|
||||
|
||||
const buildType = process.env.BUILD_TYPE;
|
||||
let config: RsbuildConfig;
|
||||
if (buildType === 'extension') {
|
||||
config = extensionConfig;
|
||||
} else {
|
||||
config = webConfig;
|
||||
}
|
||||
export default defineConfig(config);
|
||||
|
||||
const PROJECT_ROOT = '../prime';
|
||||
|
||||
// Mock API middleware for development.
|
||||
const apiMiddleware: RequestHandler = (req, res, next) => {
|
||||
res.setHeader('Cross-Origin-Resource-Policy', 'cross-origin');
|
||||
res.setHeader('Cross-Origin-Embedder-Policy', 'require-corp');
|
||||
if (!req.url || !req.headers.host || req.method !== 'GET') {
|
||||
return next();
|
||||
}
|
||||
|
||||
+15
-1
@@ -29,8 +29,22 @@ export type StateMessage = {
|
||||
projectConfig?: ProjectConfig | null;
|
||||
};
|
||||
|
||||
// decomp.me colors
|
||||
export type Colors = {
|
||||
background: string;
|
||||
};
|
||||
|
||||
// decomp.me theme
|
||||
export type ThemeMessage = {
|
||||
type: 'theme';
|
||||
isDark: boolean;
|
||||
colors: Colors;
|
||||
codeFont?: string;
|
||||
codeFontSize?: number;
|
||||
};
|
||||
|
||||
// extension -> webview
|
||||
export type InboundMessage = StateMessage;
|
||||
export type InboundMessage = StateMessage | ThemeMessage;
|
||||
|
||||
export type ReadyMessage = {
|
||||
type: 'ready';
|
||||
|
||||
+91
-26
@@ -3,7 +3,6 @@
|
||||
:root {
|
||||
--code-font-family: var(
|
||||
--vscode-editor-font-family,
|
||||
JetBrainsMono Nerd Font,
|
||||
JetBrains Mono,
|
||||
Consolas,
|
||||
"Courier New",
|
||||
@@ -22,54 +21,87 @@
|
||||
--ui-font-weight: var(--vscode-font-weight, normal);
|
||||
--ui-font-size: var(--vscode-font-size, 13px);
|
||||
|
||||
--color-green: #00ff00;
|
||||
--color-red: #f85149;
|
||||
--color-blue: #add8e6;
|
||||
--color-muted: var(--vscode-disabledForeground, rgba(204, 204, 204, 0.5));
|
||||
--color-green: light-dark(#00c300, #00ff00);
|
||||
--color-red: light-dark(#c80a00, #f85149);
|
||||
--color-blue: light-dark(#006d90, #add8e6);
|
||||
--color-muted: var(
|
||||
--vscode-disabledForeground,
|
||||
light-dark(rgba(97, 97, 97, 0.5), rgba(204, 204, 204, 0.5))
|
||||
);
|
||||
--color-bright: light-dark(black, white);
|
||||
|
||||
--panel-background: var(--vscode-panel-background, #181818);
|
||||
--panel-separator: var(--vscode-menu-separatorBackground, #454545);
|
||||
--panel-background: var(
|
||||
--vscode-panel-background,
|
||||
light-dark(#f8f8f8, #181818)
|
||||
);
|
||||
--panel-separator: var(
|
||||
--vscode-menu-separatorBackground,
|
||||
light-dark(#d4d4d4, #454545)
|
||||
);
|
||||
|
||||
--foreground: var(--vscode-foreground, #ccc);
|
||||
--background: var(--vscode-editor-background, #1f1f1f);
|
||||
--foreground: var(--vscode-foreground, light-dark(#3b3b3b, #ccc));
|
||||
--background: var(--vscode-editor-background, light-dark(#fff, #1f1f1f));
|
||||
|
||||
--list-row-height: calc(var(--code-font-size) * 1.33);
|
||||
--list-row-hover-background: var(--vscode-list-hoverBackground, #2a2d2e);
|
||||
--list-row-hover-background: var(
|
||||
--vscode-list-hoverBackground,
|
||||
light-dark(#f2f2f2, #2a2d2e)
|
||||
);
|
||||
|
||||
--line-number-foreground: var(--vscode-editorLineNumber-foreground, #6e7681);
|
||||
|
||||
--button-background-color: var(--vscode-button-secondaryBackground, #313131);
|
||||
--button-foreground-color: var(--vscode-button-secondaryForeground, #ccc);
|
||||
--button-border-color: var(--vscode-button-border, rgba(255, 255, 255, 0.07));
|
||||
--button-background-color: var(
|
||||
--vscode-button-secondaryBackground,
|
||||
light-dark(#e5e5e5, #313131)
|
||||
);
|
||||
--button-foreground-color: var(
|
||||
--vscode-button-secondaryForeground,
|
||||
light-dark(#3b3b3b, #ccc)
|
||||
);
|
||||
--button-border-color: var(
|
||||
--vscode-button-border,
|
||||
light-dark(rgba(0, 0, 0, 0.1), rgba(255, 255, 255, 0.07))
|
||||
);
|
||||
--button-hover-background-color: var(
|
||||
--vscode-button-secondaryHoverBackground,
|
||||
#3c3c3c
|
||||
light-dark(#cccccc, #3c3c3c)
|
||||
);
|
||||
--button-active-background-color: var(
|
||||
--vscode-toolbar-activeBackground,
|
||||
rgba(99, 102, 103, 0.31)
|
||||
light-dark(rgba(166, 166, 166, 0.31), rgba(99, 102, 103, 0.31))
|
||||
);
|
||||
--button-disabled-foreground-color: var(
|
||||
--vscode-disabledForeground,
|
||||
rgba(204, 204, 204, 0.5)
|
||||
light-dark(rgba(97, 97, 97, 0.5), rgba(204, 204, 204, 0.5))
|
||||
);
|
||||
--focus-border-color: var(--vscode-focusBorder, #0078d4);
|
||||
--focus-border-color: var(--vscode-focusBorder, light-dark(#005fb8, #0078d4));
|
||||
|
||||
--input-background-color: var(--vscode-input-background, #313131);
|
||||
--input-foreground-color: var(--vscode-input-foreground, #ccc);
|
||||
--input-border-color: var(--vscode-input-border, #3c3c3c);
|
||||
--input-background-color: var(
|
||||
--vscode-input-background,
|
||||
light-dark(#fff, #313131)
|
||||
);
|
||||
--input-foreground-color: var(
|
||||
--vscode-input-foreground,
|
||||
light-dark(#3b3b3b, #ccc)
|
||||
);
|
||||
--input-border-color: var(--vscode-input-border, light-dark(#cecece, #3c3c3c));
|
||||
--input-placeholder-foreground-color: var(
|
||||
--vscode-input-placeholderForeground,
|
||||
#989898
|
||||
light-dark(#767676, #989898)
|
||||
);
|
||||
|
||||
--checkbox-background-color: var(
|
||||
--vscode-settings-checkboxBackground,
|
||||
#313131
|
||||
light-dark(#f8f8f8, #313131)
|
||||
);
|
||||
--checkbox-foreground-color: var(
|
||||
--vscode-settings-checkboxForeground,
|
||||
light-dark(#3b3b3b, #ccc)
|
||||
);
|
||||
--checkbox-border-color: var(
|
||||
--vscode-settings-checkboxBorder,
|
||||
light-dark(#cecece, #3c3c3c)
|
||||
);
|
||||
--checkbox-foreground-color: var(--vscode-settings-checkboxForeground, #ccc);
|
||||
--checkbox-border-color: var(--vscode-settings-checkboxBorder, #3c3c3c);
|
||||
|
||||
color-scheme: light dark;
|
||||
|
||||
@@ -83,7 +115,7 @@
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
min-height: 100vh;
|
||||
height: 100vh;
|
||||
color: var(--foreground);
|
||||
font-family: var(--ui-font-family);
|
||||
font-weight: var(--ui-font-weight);
|
||||
@@ -99,12 +131,45 @@ body {
|
||||
&.vscode-high-contrast-dark {
|
||||
color-scheme: dark;
|
||||
}
|
||||
|
||||
&.decomp-me-dark,
|
||||
&.decomp-me-light {
|
||||
--code-font-family: var(
|
||||
--vscode-editor-font-family,
|
||||
Menlo,
|
||||
Monaco,
|
||||
monospace
|
||||
);
|
||||
--ui-font-size: .8rem;
|
||||
}
|
||||
&.decomp-me-dark {
|
||||
--panel-background: hsl(300deg 5% 9.5%);
|
||||
--background: rgb(22, 22, 24);
|
||||
--foreground: #fff9;
|
||||
--color-bright: #f9f9f9;
|
||||
color-scheme: dark;
|
||||
}
|
||||
&.decomp-me-light {
|
||||
--code-font-family: var(
|
||||
--vscode-editor-font-family,
|
||||
Menlo,
|
||||
Monaco,
|
||||
monospace
|
||||
);
|
||||
--ui-font-size: .8rem;
|
||||
--panel-background: #fdfcfd;
|
||||
--background: #fdfcfd;
|
||||
--foreground: rgb(51, 51, 51);
|
||||
--color-bright: #000000e6;
|
||||
color-scheme: light;
|
||||
}
|
||||
}
|
||||
|
||||
#root {
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
min-height: 100vh;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.loading-root {
|
||||
|
||||
+15
-15
@@ -2,12 +2,12 @@ import './App.css';
|
||||
|
||||
import type { diff, display } from 'objdiff-wasm';
|
||||
import { useShallow } from 'zustand/react/shallow';
|
||||
import FunctionView from './FunctionView';
|
||||
import SettingsView from './SettingsView';
|
||||
import SymbolsView from './SymbolsView';
|
||||
import UnitsView from './UnitsView';
|
||||
import { useAppStore, useExtensionStore } from './state';
|
||||
import type { SymbolRefByName } from './state';
|
||||
import FunctionView from './views/FunctionView';
|
||||
import SettingsView from './views/SettingsView';
|
||||
import SymbolsView from './views/SymbolsView';
|
||||
import UnitsView from './views/UnitsView';
|
||||
|
||||
const findSymbol = (
|
||||
obj: diff.ObjectDiff | undefined,
|
||||
@@ -51,19 +51,19 @@ const App = () => {
|
||||
return <div className="loading-root" />;
|
||||
}
|
||||
|
||||
if (result) {
|
||||
const leftSymbol = findSymbol(result.left, leftSymbolRef);
|
||||
const rightSymbol = findSymbol(result.right, rightSymbolRef);
|
||||
if (leftSymbol || rightSymbol) {
|
||||
return (
|
||||
<FunctionView diff={result} left={leftSymbol} right={rightSymbol} />
|
||||
);
|
||||
}
|
||||
return <SymbolsView diff={result} />;
|
||||
}
|
||||
|
||||
switch (currentView) {
|
||||
case 'main':
|
||||
if (result) {
|
||||
const leftSymbol = findSymbol(result.left, leftSymbolRef);
|
||||
const rightSymbol = findSymbol(result.right, rightSymbolRef);
|
||||
if (leftSymbol || rightSymbol) {
|
||||
return (
|
||||
<FunctionView diff={result} left={leftSymbol} right={rightSymbol} />
|
||||
);
|
||||
}
|
||||
return <SymbolsView diff={result} />;
|
||||
}
|
||||
|
||||
if (buildRunning) {
|
||||
return (
|
||||
<div className="content">
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
import './wasm'; // Must come first
|
||||
import './util/wasm'; // Must come first
|
||||
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom/client';
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
if (window.webviewProps?.resourceRoot) {
|
||||
__webpack_public_path__ = window.webviewProps.resourceRoot;
|
||||
}
|
||||
+28
-6
@@ -1,4 +1,5 @@
|
||||
import {
|
||||
type ConfigProperties,
|
||||
type ProjectConfig,
|
||||
type Unit,
|
||||
resolveProjectConfig,
|
||||
@@ -32,10 +33,6 @@ function sendMessage(data: InboundMessage) {
|
||||
window.dispatchEvent(new MessageEvent('message', { data }));
|
||||
}
|
||||
|
||||
// async function delay(ms: number) {
|
||||
// return new Promise((resolve) => setTimeout(resolve, ms));
|
||||
// }
|
||||
|
||||
let resolvedProjectConfig: ProjectConfig | null = null;
|
||||
|
||||
async function fetchFile(path: string): Promise<Response> {
|
||||
@@ -55,6 +52,13 @@ if (serializedLastUnit) {
|
||||
lastUnit = JSON.parse(serializedLastUnit);
|
||||
}
|
||||
|
||||
let configProperties: ConfigProperties = {};
|
||||
|
||||
const serializedConfigProperties = localStorage.getItem('configProperties');
|
||||
if (serializedConfigProperties) {
|
||||
configProperties = JSON.parse(serializedConfigProperties);
|
||||
}
|
||||
|
||||
async function handleMessage(msg: OutboundMessage): Promise<void> {
|
||||
switch (msg.type) {
|
||||
case 'ready': {
|
||||
@@ -64,7 +68,7 @@ async function handleMessage(msg: OutboundMessage): Promise<void> {
|
||||
const out: StateMessage = {
|
||||
type: 'state',
|
||||
buildRunning: false,
|
||||
configProperties: {},
|
||||
configProperties,
|
||||
currentUnit: null,
|
||||
leftObject: null,
|
||||
rightObject: null,
|
||||
@@ -128,6 +132,20 @@ async function handleMessage(msg: OutboundMessage): Promise<void> {
|
||||
sendMessage(out);
|
||||
break;
|
||||
}
|
||||
case 'setConfigProperty': {
|
||||
if (msg.value === undefined) {
|
||||
configProperties = { ...configProperties };
|
||||
delete configProperties[msg.id];
|
||||
} else {
|
||||
configProperties = { ...configProperties, [msg.id]: msg.value };
|
||||
}
|
||||
localStorage.setItem(
|
||||
'configProperties',
|
||||
JSON.stringify(configProperties),
|
||||
);
|
||||
sendMessage({ type: 'state', configProperties });
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
console.warn('Unhandled message', msg);
|
||||
}
|
||||
@@ -136,7 +154,11 @@ async function handleMessage(msg: OutboundMessage): Promise<void> {
|
||||
|
||||
export const mockVsCode: MyWebviewApi<AppStateSerialized> = {
|
||||
postMessage: (msg) => {
|
||||
handleMessage(msg);
|
||||
if (window.parent === window || msg.type === 'setConfigProperty') {
|
||||
handleMessage(msg);
|
||||
} else {
|
||||
window.parent.postMessage(msg, '*');
|
||||
}
|
||||
},
|
||||
getState: () => state,
|
||||
setState: (newState) => {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user