diff --git a/package.json b/package.json index addd20f2..b2ff2922 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ }, "dependencies": { "@babel/plugin-transform-class-static-block": "7.29.7", - "@rancher/shell": "3.0.12-rc.3", + "@rancher/shell": "3.0.12-rc.7", "@vue-flow/background": "^1.3.0", "@vue-flow/controls": "^1.1.1", "@vue-flow/core": "^1.33.5", @@ -15,6 +15,12 @@ "cache-loader": "^4.1.0", "color": "4.2.3", "ip": "2.0.1", + "@xterm/xterm": "6.0.0", + "@xterm/addon-fit": "0.11.0", + "@xterm/addon-search": "0.16.0", + "@xterm/addon-web-links": "0.12.0", + "@xterm/addon-webgl": "0.19.0", + "@xterm/addon-canvas": "0.7.0", "node-polyfill-webpack-plugin": "^3.0.0", "elkjs": "^0.11.0", "vue-draggable-next": "^2.2.1", diff --git a/pkg/harvester/components/SerialConsole/index.vue b/pkg/harvester/components/SerialConsole/index.vue index 69fead2b..e5652e6a 100644 --- a/pkg/harvester/components/SerialConsole/index.vue +++ b/pkg/harvester/components/SerialConsole/index.vue @@ -77,13 +77,13 @@ export default { methods: { async setupTerminal() { const docStyle = getComputedStyle(document.querySelector('body')); - const xterm = await import(/* webpackChunkName: "xterm" */ 'xterm'); + const xterm = await import(/* webpackChunkName: "xterm" */ '@xterm/xterm'); const addons = await allHash({ - fit: import(/* webpackChunkName: "xterm" */ 'xterm-addon-fit'), - webgl: import(/* webpackChunkName: "xterm" */ 'xterm-addon-webgl'), - weblinks: import(/* webpackChunkName: "xterm" */ 'xterm-addon-web-links'), - search: import(/* webpackChunkName: "xterm" */ 'xterm-addon-search'), + fit: import(/* webpackChunkName: "xterm" */ '@xterm/addon-fit'), + webgl: import(/* webpackChunkName: "xterm" */ '@xterm/addon-webgl'), + weblinks: import(/* webpackChunkName: "xterm" */ '@xterm/addon-web-links'), + search: import(/* webpackChunkName: "xterm" */ '@xterm/addon-search'), }); const terminal = new xterm.Terminal({ @@ -98,8 +98,21 @@ export default { this.fitAddon = new addons.fit.FitAddon(); this.searchAddon = new addons.search.SearchAddon(); + // if user is using Safari with webGPU disabled, webglAddon will silently fail + // and we do not have a way to detect that. + // To avoid it, default to DOM rendering for Safari browsers try { - this.webglAddon = new addons.webgl.WebGlAddon(); + const ua = window.navigator.userAgent.toLowerCase(); + const isSafari = ua.includes('safari') && + !ua.includes('crios') && // Chrome iOS + !ua.includes('fxios') && // Firefox iOS + !ua.includes('edgios') && // Edge iOS + !ua.includes('opr'); // Opera + + if (!isSafari) { + this.webglAddon = new addons.webgl.WebglAddon(); + terminal.loadAddon(this.webglAddon); + } } catch (e) { // Some browsers (Safari) don't support the webgl renderer, so don't use it. this.webglAddon = null; @@ -257,7 +270,7 @@ export default {