diff --git a/appimage-scripts/build_appimage.sh b/appimage-scripts/build_appimage.sh index 090e5ec5a..be3eeb086 100755 --- a/appimage-scripts/build_appimage.sh +++ b/appimage-scripts/build_appimage.sh @@ -177,6 +177,9 @@ cp "${ROOT_PATH}/src/helpers.js" "${APP_DIR}/helpers.js" cp "${ROOT_PATH}/src/frontend/index.html" "${APP_DIR}/src/index.html" cp "${ROOT_PATH}/src/frontend/index.html" "${APP_DIR}/index.html" +cp "${ROOT_PATH}/src/frontend/init.js" "${APP_DIR}/src/init.js" +cp "${ROOT_PATH}/src/frontend/init.js" "${APP_DIR}/init.js" + cp "${ROOT_PATH}/src/frontend/subwindow.html" "${APP_DIR}/subwindow.html" cp "${ROOT_PATH}/src/frontend/subwindow.html" "${APP_DIR}/src/subwindow.html" diff --git a/nix/packages/default.nix b/nix/packages/default.nix index 08c98c651..609f1df78 100644 --- a/nix/packages/default.nix +++ b/nix/packages/default.nix @@ -666,6 +666,7 @@ cp -r src/frontend/index.html $out/ cp -r src/frontend/subwindow.html $out/ + cp -r src/frontend/init.js $out/ ''; meta.mainProgram = "ct"; diff --git a/node-packages/package.json b/node-packages/package.json index 24e2fdef3..814b6d9b4 100644 --- a/node-packages/package.json +++ b/node-packages/package.json @@ -31,7 +31,7 @@ "jstree": "3.3.17", "monaco-editor": "0.47.0", "mousetrap": "^1.6.5", - "node-abi": "^4.16.0", + "node-abi": "^4.17.0", "node-gyp": "^11.5.0", "node-ipc": "^12.0.0", "nouislider": "^15.8.1", @@ -40,7 +40,7 @@ "remove": "^0.1.5", "selenium-webdriver": "^4.38.0", "socket.io": "^4.8.1", - "tar": "^7.5.1", + "tar": "^7.5.2", "tippy.js": "^6.3.7", "vex-dialog": "^1.1.0", "vex-js": "^4.1.0", diff --git a/node-packages/yarn-project.nix b/node-packages/yarn-project.nix index ddf13c170..904a55ae3 100644 --- a/node-packages/yarn-project.nix +++ b/node-packages/yarn-project.nix @@ -52,7 +52,7 @@ let rm $out/.gitignore ''; outputHashMode = "recursive"; - outputHash = "sha512-4YpWRcJ674gzGuO1ymgWDK76e5gJ3VBYDKwYAqXTTBtxcKfw0m6ku3T/AVTBz0V1tU94caGERXDr0k0rExYWzw=="; + outputHash = "sha512-ath85hZDR6/oMvq4krn7tzlTWOZ05YA+ZYvQ4986CPHqs6VqeB9VCRGXayoaMriVcndU4RDMefBqWb59bqTiQQ=="; }; # Main project derivation. diff --git a/node-packages/yarn.lock b/node-packages/yarn.lock index 38348db3a..930e2fff7 100644 --- a/node-packages/yarn.lock +++ b/node-packages/yarn.lock @@ -2877,7 +2877,7 @@ __metadata: monaco-editor-webpack-plugin: "npm:7.1.1" mousetrap: "npm:^1.6.5" napi-build-utils: "npm:^2.0.0" - node-abi: "npm:^4.16.0" + node-abi: "npm:^4.17.0" node-gyp: "npm:^11.5.0" node-ipc: "npm:^12.0.0" nouislider: "npm:^15.8.1" @@ -2890,7 +2890,7 @@ __metadata: socket.io: "npm:^4.8.1" style-loader: "npm:4.0.0" stylus: "npm:^0.64.0" - tar: "npm:^7.5.1" + tar: "npm:^7.5.2" tippy.js: "npm:^6.3.7" typescript: "npm:5.9.3" typescript-eslint: "npm:^8.46.2" @@ -7312,12 +7312,12 @@ __metadata: languageName: node linkType: hard -"node-abi@npm:^4.16.0": - version: 4.16.0 - resolution: "node-abi@npm:4.16.0" +"node-abi@npm:^4.17.0": + version: 4.17.0 + resolution: "node-abi@npm:4.17.0" dependencies: semver: "npm:^7.6.3" - checksum: 10c0/86755daa52b07eebd3c0db57cef7f573febb1d70fd11ddc907260fedb5b7a5dd63386e2d7c1c0d3b3e6923d4cc629e8a570768a6597ef0ae6cd4567cda4ea7b6 + checksum: 10c0/0d3e70da5229195fa890db50dd735e52f9f76c1038dd0786ef2d35e6f624d3900bcccae6f5f8e6502aa2392d44949964a4c11d27413c32870f2b25806275f61d languageName: node linkType: hard @@ -10059,16 +10059,16 @@ __metadata: languageName: node linkType: hard -"tar@npm:^7.5.1": - version: 7.5.1 - resolution: "tar@npm:7.5.1" +"tar@npm:^7.5.2": + version: 7.5.2 + resolution: "tar@npm:7.5.2" dependencies: "@isaacs/fs-minipass": "npm:^4.0.0" chownr: "npm:^3.0.0" minipass: "npm:^7.1.2" minizlib: "npm:^3.1.0" yallist: "npm:^5.0.0" - checksum: 10c0/0dad0596a61586180981133b20c32cfd93c5863c5b7140d646714e6ea8ec84583b879e5dc3928a4d683be6e6109ad7ea3de1cf71986d5194f81b3a016c8858c9 + checksum: 10c0/a7d8b801139b52f93a7e34830db0de54c5aa45487c7cb551f6f3d44a112c67f1cb8ffdae856b05fd4f17b1749911f1c26f1e3a23bbe0279e17fd96077f13f467 languageName: node linkType: hard diff --git a/non-nix-build/build_in_simple_env.sh b/non-nix-build/build_in_simple_env.sh index 6eb7a2e27..7fa70d0df 100755 --- a/non-nix-build/build_in_simple_env.sh +++ b/non-nix-build/build_in_simple_env.sh @@ -50,6 +50,8 @@ cp "$ROOT_DIR"/src/helpers.js "$DIST_DIR"/src/helpers.js cp "$ROOT_DIR"/src/helpers.js "$DIST_DIR"/helpers.js cp "$ROOT_DIR"/src/frontend/*.html "$DIST_DIR"/src/ cp "$ROOT_DIR"/src/frontend/*.html "$DIST_DIR"/ +cp "$ROOT_DIR"/src/frontend/*.js "$DIST_DIR"/src/ +cp "$ROOT_DIR"/src/frontend/*.js "$DIST_DIR"/ rm -f "$DIST_DIR"/config rm -f "$DIST_DIR"/public cp -r "$ROOT_DIR"/src/config "$DIST_DIR"/config diff --git a/src/Tupfile b/src/Tupfile index 4bb1f5f16..1ff04720e 100644 --- a/src/Tupfile +++ b/src/Tupfile @@ -5,6 +5,7 @@ include_rules : frontend/subwindow.nim |> !nim_node_subwindow |> subwindow.js | subwindow.js.map : frontend/index.nim |> !nim_node_index_server |> server_index.js | server_index.js.map : frontend/ui_js.nim |> !nim_js |> ui.js +: frontend/init.js |> cp %f %o |> init.js # : frontend/browsersync_serv.nim |> !nim_node |> browsersync_serv.js # : frontend/codetracer_shell.nim |> !codetracer_shell |> bin/codetracer_shell.js diff --git a/src/Tupfile.ini b/src/Tupfile.ini deleted file mode 100644 index 8b1378917..000000000 --- a/src/Tupfile.ini +++ /dev/null @@ -1 +0,0 @@ - diff --git a/src/frontend/index.html b/src/frontend/index.html index 2b8157d7c..5f269b0c7 100644 --- a/src/frontend/index.html +++ b/src/frontend/index.html @@ -4,14 +4,28 @@ - + CodeTracer + + later we use `loadTheme` in ui_js.nim to load the configured theme + --> @@ -38,15 +52,7 @@ - + @@ -57,7 +63,7 @@
- +
diff --git a/src/frontend/index/install.nim b/src/frontend/index/install.nim index 677600e7f..aa045e80f 100644 --- a/src/frontend/index/install.nim +++ b/src/frontend/index/install.nim @@ -6,6 +6,8 @@ import ../[ types ], ../../common/[ paths, ct_logging ] +from window import setupSecureContext + type InstallResponseKind* {.pure.} = enum Ok, Problem, Dismissed @@ -22,31 +24,35 @@ var process {.importc.}: js proc createInstallSubwindow*(): js = - let win = jsnew electron.BrowserWindow( - js{ - "width": 700, - "height": 422, - "resizable": false, - "parent": mainWindow, - "modal": true, - "webPreferences": js{ - "nodeIntegration": true, - "contextIsolation": false, - "spellcheck": false - }, - "frame": false, - "transparent": false, - }) - - let url = "file://" & $codetracerExeDir & "/subwindow.html" - debugPrint "Attempting to load: ", url - win.loadURL(cstring(url)) - - let inDevEnv = nodeProcess.env[cstring"CODETRACER_DEV_TOOLS"] == cstring"1" - if inDevEnv: - electronDebug.devTools(win) - - win.toJs + let win = jsnew electron.BrowserWindow( + js{ + "width": 700, + "height": 422, + "resizable": false, + "parent": mainWindow, + "modal": true, + "webPreferences": js{ + "nodeIntegration": true, + "contextIsolation": false, + "webSecurity": true, + "allowRunningInsecureContent": false, + "spellcheck": false + }, + "frame": false, + "transparent": false, + } + ) + setupSecureContext(win) + + let url = $codetracerExeDir & "/subwindow.html" + debugPrint "Attempting to load: ", url + win.loadFile(url) + + let inDevEnv = nodeProcess.env[cstring"CODETRACER_DEV_TOOLS"] == cstring"1" + if inDevEnv: + electronDebug.devTools(win) + + win.toJs proc onInstallCt*(sender: js, response: js) {.async.} = diff --git a/src/frontend/index/window.nim b/src/frontend/index/window.nim index 04f01a5bf..2f3a1ef40 100644 --- a/src/frontend/index/window.nim +++ b/src/frontend/index/window.nim @@ -36,6 +36,32 @@ proc onClose*(e: js) = mainWindow.webContents.send "CODETRACER::close", js{} close = true +proc setupSecureContext*(win: JsObject) = + # Prevent opening new windows or popups + win.webContents.setWindowOpenHandler(proc: js = + return js{ + "action": "deny" + } + ) + + # Disable webview tags + electron_vars.app.on( + "web-contents-created", + proc(evt: js, contents: js) = + contents.on("will-attach-webview", proc(event: js) = + event.preventDefault() + ) + ) + + # Disable window navigation + win.on( + "will-navigate", + proc(e: js, url: js) = + let current = win.getURL() + if url != current: + e.preventDefault() + ) + proc createMainWindow*: js = when not defined(server): # TODO load from config @@ -53,6 +79,8 @@ proc createMainWindow*: js = "webPreferences": js{ "nodeIntegration": true, "contextIsolation": false, + "webSecurity": true, + "allowRunningInsecureContent": false, "spellcheck": false }, } @@ -72,13 +100,16 @@ proc createMainWindow*: js = let win = jsnew electron.BrowserWindow(initInfo) win.on("maximize", proc() = - win.webContents.executeJavaScript("document.body.style.backgroundColor = 'black';")) + win.webContents.send "CODETRACER::maximize", js{} + ) win.on("unmaximize", proc() = - win.webContents.executeJavaScript("document.body.style.backgroundColor = 'transparent';")) + win.webContents.send "CODETRACER::unmaximize", js{} + ) win.maximize() - let url = "file://" & $codetracerExeDir & "/index.html" - win.loadURL(cstring(url)) + let url = $codetracerExeDir & "/index.html" + win.loadFile(url) + setupSecureContext(win) win.on("close", onClose) # TODO: eventually add a shortcut and ipc message that lets us diff --git a/src/frontend/init.js b/src/frontend/init.js new file mode 100644 index 000000000..ee7535063 --- /dev/null +++ b/src/frontend/init.js @@ -0,0 +1,8 @@ +'use strict' +self.module = undefined +self.process.browser = true + +window.electron = require('electron'); + +window.inElectron = true +window.loadScripts = true \ No newline at end of file diff --git a/src/frontend/lib/electron_lib.nim b/src/frontend/lib/electron_lib.nim index 2a9d6959f..4ec8b0962 100644 --- a/src/frontend/lib/electron_lib.nim +++ b/src/frontend/lib/electron_lib.nim @@ -104,8 +104,8 @@ when defined(ctIndex) or defined(ctTest) or defined(ctInCentralExtensionContext) var nodePath*: NodePath when defined(ctRenderer): - var inElectron* {.importc.}: bool - var loadScripts* {.importc.}: bool + var inElectron* {.importc: "window.inElectron".}: bool + var loadScripts* {.importc: "window.loadScripts".}: bool else: var inElectron*: bool = false var loadScripts*: bool = false diff --git a/src/frontend/styles/components/welcome_screen.styl b/src/frontend/styles/components/welcome_screen.styl index 8e938018e..a991bde53 100644 --- a/src/frontend/styles/components/welcome_screen.styl +++ b/src/frontend/styles/components/welcome_screen.styl @@ -637,3 +637,6 @@ .stylus-content width: 850px !important + +#context-menu-container + display: none \ No newline at end of file diff --git a/src/frontend/subwindow.html b/src/frontend/subwindow.html index 38690f737..cee856385 100644 --- a/src/frontend/subwindow.html +++ b/src/frontend/subwindow.html @@ -1,20 +1,28 @@ - - - - Install Subwindow + + + + + Install Subwindow - - + + +
-
- - - - - + + + diff --git a/src/frontend/ui_js.nim b/src/frontend/ui_js.nim index c972e858e..361e6cf94 100644 --- a/src/frontend/ui_js.nim +++ b/src/frontend/ui_js.nim @@ -1212,6 +1212,11 @@ macro uiIpcHandlers*(namespace: static[string], messages: untyped): untyped = result.add(messageCode) # echo result.repr +proc onMaximize(data: Data) = + jq("body").style.backgroundColor = cstring"black" +proc onUnmaximize(data: Data) = + jq("body").style.backgroundColor = cstring"transparent" + proc configureIPC(data: Data) = uiIpcHandlers("CODETRACER::"): # "new-record-window" @@ -1305,6 +1310,9 @@ proc configureIPC(data: Data) = "dap-receive-response" "dap-receive-event" + "maximize" + "unmaximize" + duration("configureIPCRun") proc zoomInEditors*(data: Data) = diff --git a/src/frontend/webpack.config.js b/src/frontend/webpack.config.js deleted file mode 100644 index 94c38dec0..000000000 --- a/src/frontend/webpack.config.js +++ /dev/null @@ -1,9 +0,0 @@ -const path = require('path'); - -module.exports = { - entry: 'public/third_party/jquery.js', - output: { - path: path.resolve(__dirname, 'dist'), - filename: 'bundle.js' - } -}; diff --git a/views/server_index.ejs b/views/server_index.ejs index 31ee12738..e1e837dc1 100644 --- a/views/server_index.ejs +++ b/views/server_index.ejs @@ -5,14 +5,13 @@ - - + + CodeTracer - diff --git a/webpack.config.js b/webpack.config.js index 206c277da..345fe1dbb 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -2,8 +2,8 @@ const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin'); const path = require('path'); module.exports = { - mode: 'development', - // devtool: "source-map", + mode: "production", + devtool: false, entry: "./src/frontend/frontend_imports.js", output: { globalObject: 'window', @@ -11,16 +11,16 @@ module.exports = { filename: "frontend_bundle.js" }, module: { - rules: [ - { - test: /\.css$/, - use: ['style-loader', 'css-loader'] - }, - // { - // test: /\.ttf$/, - // type: 'asset/resource' - // } - ] + rules: [ + { + test: /\.css$/, + use: ['style-loader', 'css-loader'] }, - plugins: [new MonacoWebpackPlugin()] + // { + // test: /\.ttf$/, + // type: 'asset/resource' + // } + ] + }, + plugins: [new MonacoWebpackPlugin()] };