Skip to content

Commit

Permalink
feat: jetbrains-webview
Browse files Browse the repository at this point in the history
  • Loading branch information
dineug committed Jan 19, 2024
1 parent 7f0487d commit 0f0f296
Show file tree
Hide file tree
Showing 10 changed files with 346 additions and 5 deletions.
4 changes: 4 additions & 0 deletions erd-editor.code-workspace
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@
"name": "erd-editor-vscode-bridge",
"path": "packages/erd-editor-vscode-bridge"
},
{
"name": "erd-editor-jetbrains-webview",
"path": "packages/erd-editor-jetbrains-webview"
},
{
"name": "erd-editor-app",
"path": "packages/erd-editor-app"
Expand Down
33 changes: 33 additions & 0 deletions packages/erd-editor-jetbrains-webview/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"name": "@dineug/erd-editor-jetbrains-webview",
"version": "0.1.0",
"private": true,
"description": "Entity-Relationship Diagram Editor jetbrains webview",
"author": "SeungHwan-Lee <[email protected]>",
"license": "MIT",
"scripts": {
"dev": "webpack serve --mode development",
"build": "webpack --mode production",
"build:analyzer": "webpack --mode production --env target=analyzer",
"build:webview": "webpack --mode production --env target=webview"
},
"devDependencies": {
"@dineug/erd-editor": "workspace:*",
"@dineug/erd-editor-shiki-worker": "workspace:*",
"@dineug/erd-editor-vscode-bridge": "workspace:*",
"@swc/core": "^1.3.101",
"base64-arraybuffer": "^1.0.2",
"core-js": "^3.34.0",
"css-loader": "^6.8.1",
"html-webpack-plugin": "^5.6.0",
"mini-css-extract-plugin": "^2.7.6",
"style-loader": "^3.3.3",
"swc-loader": "^0.2.3",
"tsconfig-paths-webpack-plugin": "^4.1.0",
"typescript": "5.3.3",
"webpack": "^5.89.0",
"webpack-bundle-analyzer": "^4.10.1",
"webpack-cli": "^5.1.4",
"webpack-dev-server": "^4.15.1"
}
}
10 changes: 10 additions & 0 deletions packages/erd-editor-jetbrains-webview/public/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
<title>erd-editor</title>
</head>
<body></body>
</html>
5 changes: 5 additions & 0 deletions packages/erd-editor-jetbrains-webview/src/env.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
declare global {
interface Window {
cefQuery: (arg: any) => number;
}
}
99 changes: 99 additions & 0 deletions packages/erd-editor-jetbrains-webview/src/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import './webview.css';

import {
setExportFileCallback,
setGetShikiServiceCallback,
setImportFileCallback,
} from '@dineug/erd-editor';
import {
AnyAction,
Emitter,
ThemeOptions,
vscodeExportFileAction,
vscodeImportFileAction,
vscodeInitialAction,
vscodeSaveReplicationAction,
vscodeSaveThemeAction,
vscodeSaveValueAction,
} from '@dineug/erd-editor-vscode-bridge';
import { encode } from 'base64-arraybuffer';

const bridge = new Emitter();
// const vscode = globalThis.acquireVsCodeApi();
const editor = document.createElement('erd-editor');
const sharedStore = editor.getSharedStore({ mouseTracker: false });

const dispatch = (action: AnyAction) => {
// vscode.postMessage(action);
};

import('@dineug/erd-editor-shiki-worker').then(({ getShikiService }) => {
setGetShikiServiceCallback(getShikiService);
});
setImportFileCallback(options => {
dispatch(vscodeImportFileAction(options));
});
setExportFileCallback(async (blob, options) => {
const arrayBuffer = await blob.arrayBuffer();
dispatch(
vscodeExportFileAction({
value: encode(arrayBuffer),
fileName: options.fileName,
})
);
});

const getSystemTheme = () =>
document.body.classList.contains('vscode-light') ? 'light' : 'dark';

const handleChange = () => {
dispatch(
vscodeSaveValueAction({
value: editor.value,
})
);
};

const handleChangePresetTheme = (event: Event) => {
const e = event as CustomEvent<ThemeOptions>;
dispatch(vscodeSaveThemeAction(e.detail));
};

bridge.on({
webviewImportFile: ({ payload: { type, value } }) => {
switch (type) {
case 'json':
editor.value = value;
break;
case 'sql':
editor.setSchemaSQL(value);
break;
}
},
webviewInitialValue: ({ payload: { value } }) => {
// editor.addEventListener('change', handleChange);
editor.addEventListener('changePresetTheme', handleChangePresetTheme);
editor.setInitialValue(value);
editor.enableThemeBuilder = true;
sharedStore.subscribe(actions => {
dispatch(vscodeSaveReplicationAction({ actions }));
});
document.body.appendChild(editor);
},
webviewReplication: ({ payload: { actions } }) => {
sharedStore.dispatch(actions);
},
webviewUpdateTheme: ({ payload }) => {
editor.setPresetTheme({
...payload,
appearance:
payload.appearance === 'auto' ? getSystemTheme() : payload.appearance,
});
},
webviewReadonly: ({ payload }) => {
editor.readonly = payload;
},
});

globalThis.addEventListener('message', event => bridge.emit(event.data));
dispatch(vscodeInitialAction());
6 changes: 6 additions & 0 deletions packages/erd-editor-jetbrains-webview/src/webview.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
body {
padding: 0;
margin: 0;
width: 100%;
height: 100vh;
}
10 changes: 10 additions & 0 deletions packages/erd-editor-jetbrains-webview/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["src/*"]
}
},
"include": ["src"]
}
119 changes: 119 additions & 0 deletions packages/erd-editor-jetbrains-webview/webpack.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
const path = require('path');
const { DefinePlugin } = require('webpack');
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin');

const resolvePath = value => path.resolve(__dirname, value);

module.exports = (env, argv) => {
const isProduction = argv.mode === 'production';
const isDevelopment = argv.mode !== 'production';
const mode = isDevelopment ? 'development' : 'production';
const isAnalyzer = env.target === 'analyzer';
const isWebview = env.target === 'webview';

const config = {
mode,
devtool: isDevelopment ? 'eval-source-map' : 'source-map',
devServer: {
static: {
directory: resolvePath('public'),
},
compress: true,
historyApiFallback: true,
open: true,
hot: true,
client: {
overlay: false,
},
},
entry: './src/main',
output: {
path: isWebview
? resolvePath('../../../src/main/resources/assets')
: resolvePath('dist'),
publicPath: '/',
filename: isProduction
? 'static/js/bundle.[contenthash:8].js'
: 'static/js/bundle.js',
chunkFilename: isProduction
? 'static/js/[id].[contenthash:8].js'
: 'static/js/[name].js',
clean: true,
},
resolve: {
extensions: ['.ts', '.ts', '.js'],
plugins: [new TsconfigPathsPlugin()],
},
module: {
rules: [
{
test: /\.[jt]s$/,
exclude: /node_modules/,
use: {
loader: 'swc-loader',
options: {
env: {
targets: 'defaults',
mode: 'entry',
coreJs: '3.34',
},
},
},
},
{
test: /\.css$/i,
use: [
isProduction ? MiniCssExtractPlugin.loader : 'style-loader',
'css-loader',
],
},
{
test: /\.(png|svg|jpg|jpeg|gif)$/i,
type: 'asset/resource',
},
{
test: /\.(woff|woff2|eot|ttf|otf)$/i,
type: 'asset/resource',
},
],
},
plugins: [
new DefinePlugin({
'import.meta.env.MODE': JSON.stringify(mode),
}),
isProduction &&
new MiniCssExtractPlugin({
filename: 'static/css/bundle.[contenthash:8].css',
chunkFilename: 'static/css/[id].[contenthash:8].css',
}),
new HtmlWebpackPlugin({
inject: true,
template: resolvePath('public/index.html'),
templateParameters: {
gtag: isProduction ? toGtag() : '',
},
}),
isAnalyzer && new BundleAnalyzerPlugin(),
].filter(Boolean),
performance: false,
};

return config;
};

function toGtag() {
// return /*html*/ `
// <script async src="https://www.googletagmanager.com/gtag/js?id=G-3VBWD4V1JX"></script>
// <script>
// window.dataLayer = window.dataLayer || [];
// function gtag() {
// dataLayer.push(arguments);
// }
// gtag('js', new Date());
// gtag('config', 'G-3VBWD4V1JX');
// </script>`;
return '';
}
11 changes: 6 additions & 5 deletions packages/erd-editor-vscode-webview/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { defineConfig, loadEnv } from 'vite';
export default defineConfig(({ command, mode }) => {
const envDir = './environment';
const env = loadEnv(mode, envDir);
const target = env.VITE_TARGET;

const targetMap = {
modern: {
Expand Down Expand Up @@ -37,11 +38,11 @@ export default defineConfig(({ command, mode }) => {
},
};

const entry = targetMap[env.VITE_TARGET].entry;
const name = targetMap[env.VITE_TARGET].name;
const fileName = targetMap[env.VITE_TARGET].fileName;
const outDir = targetMap[env.VITE_TARGET].outDir;
const emptyOutDir = targetMap[env.VITE_TARGET].emptyOutDir;
const entry = targetMap[target].entry;
const name = targetMap[target].name;
const fileName = targetMap[target].fileName;
const outDir = targetMap[target].outDir;
const emptyOutDir = targetMap[target].emptyOutDir;
const isBuild = command === 'build';

return {
Expand Down
54 changes: 54 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 0f0f296

Please sign in to comment.