@electerm/electerm-react 5.5.6 → 5.5.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/client/common/default-setting.js +1 -0
  2. package/client/common/download.jsx +12 -0
  3. package/client/common/resolve.js +20 -14
  4. package/client/components/ai/ai-history-item.jsx +1 -1
  5. package/client/components/ai/ai-history.jsx +1 -0
  6. package/client/components/ai/ai-history.styl +23 -0
  7. package/client/components/bookmark-form/common/color-picker.styl +3 -0
  8. package/client/components/common/remote-pointer.js +49 -0
  9. package/client/components/common/remote-session-shell.jsx +137 -0
  10. package/client/components/common/remote-session-shell.styl +80 -0
  11. package/client/components/common/responsive-tabs.jsx +89 -0
  12. package/client/components/common/responsive-tabs.styl +34 -0
  13. package/client/components/footer/cmd-history.jsx +132 -45
  14. package/client/components/footer/cmd-history.styl +42 -4
  15. package/client/components/footer/multi-tab-run-modal.jsx +83 -0
  16. package/client/components/footer/tab-select.jsx +34 -17
  17. package/client/components/quick-commands/quick-command-create-modal.jsx +60 -0
  18. package/client/components/quick-commands/quick-commands-form-elem.jsx +10 -4
  19. package/client/components/rdp/rdp-session.jsx +94 -124
  20. package/client/components/rdp/rdp.styl +13 -36
  21. package/client/components/session/session.styl +0 -16
  22. package/client/components/setting-panel/setting-modal.jsx +8 -3
  23. package/client/components/setting-panel/setting-terminal.jsx +1 -0
  24. package/client/components/sftp/sftp-entry.jsx +30 -0
  25. package/client/components/sidebar/side-panel.jsx +1 -1
  26. package/client/components/spice/spice-session.jsx +69 -72
  27. package/client/components/spice/spice.styl +10 -19
  28. package/client/components/terminal/mixins/term-content.js +38 -0
  29. package/client/components/terminal/mixins/term-context-menu.jsx +35 -3
  30. package/client/components/terminal/mixins/term-socket.js +5 -5
  31. package/client/components/terminal/mixins/term-touch.js +444 -57
  32. package/client/components/terminal/shortcut-bar-defs.js +30 -4
  33. package/client/components/terminal/shortcut-bar-edit.jsx +40 -9
  34. package/client/components/terminal/shortcut-bar.jsx +13 -4
  35. package/client/components/terminal/ssh-reload-state.js +41 -1
  36. package/client/components/terminal/startup-queue.js +67 -13
  37. package/client/components/terminal/terminal-select-text.jsx +69 -0
  38. package/client/components/terminal/terminal.jsx +72 -4
  39. package/client/components/terminal/terminal.styl +61 -0
  40. package/client/components/theme/theme-form.jsx +18 -21
  41. package/client/components/theme/theme-form.styl +8 -10
  42. package/client/components/vnc/vnc-session.jsx +72 -104
  43. package/client/components/vnc/vnc.styl +25 -16
  44. package/client/css/mobile.styl +20 -7
  45. package/client/store/setting.js +4 -0
  46. package/client/store/tab.js +5 -4
  47. package/package.json +1 -1
@@ -1,29 +1,20 @@
1
+ // SPICE only styling — the session layout (control bar, viewport, fit mode)
2
+ // lives in the shared remote session shell: common/remote-session-shell.styl
1
3
  .spice-session-wrap
2
- display: flex
3
- flex-direction: column
4
- align-items: center
5
- .session-v-info
6
- position: relative
7
- width: 100%
8
- z-index: 300
9
- &.scale-viewport
10
- .spice-scroll-wrapper
4
+ // fit: the mount box fills the viewport and the canvas (sized by the spice
5
+ // client to the remote resolution) is scaled to it, keeping the ratio.
6
+ // !important because the client writes the surface size into the mount box
7
+ // inline style (`screen_id` height = surface height).
8
+ &.fit
9
+ .spice-session-mount
10
+ width 100% !important
11
+ height 100% !important
11
12
  display flex
12
13
  align-items center
13
14
  justify-content center
14
- > div
15
- width 100% !important
16
- height 100% !important
17
- display flex
18
- align-items center
19
- justify-content center
20
15
  canvas
21
16
  width 100% !important
22
17
  height 100% !important
23
18
  max-width 100% !important
24
19
  max-height 100% !important
25
20
  object-fit contain
26
- .spice-scroll-wrapper
27
- position relative
28
- background var(--main)
29
- z-index 299
@@ -84,5 +84,43 @@ export const contentMixin = {
84
84
  const ts = `[${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')} ${String(now.getHours()).padStart(2, '0')}:${String(now.getMinutes()).padStart(2, '0')}:${String(now.getSeconds()).padStart(2, '0')}.${String(now.getMilliseconds()).padStart(3, '0')}] `
85
85
  return ts + text
86
86
  }).join('\n')
87
+ },
88
+
89
+ /**
90
+ * The whole buffer as clean plain text, for the touch select-text overlay.
91
+ *
92
+ * Differs from getTerminalBufferText() on purpose: that one is for log files
93
+ * and keeps xterm's fixed-width padding (`translateToString(false)`), which
94
+ * would trail a screen-full of spaces into a textarea and make every line
95
+ * look wrapped. Here each row is right-trimmed, rows xterm reports as
96
+ * `isWrapped` are glued back so a line the shell printed as one line is
97
+ * copied as one line, and the blank rows scrollback starts out with are
98
+ * dropped so the panel opens on real output.
99
+ */
100
+ getSelectableBufferText () {
101
+ const buffer = this.term.buffer.active
102
+ const len = buffer.length
103
+ const lines = []
104
+ for (let i = 0; i < len; i++) {
105
+ const line = buffer.getLine(i)
106
+ if (!line) {
107
+ continue
108
+ }
109
+ const text = line.translateToString(true)
110
+ if (line.isWrapped && lines.length) {
111
+ lines[lines.length - 1] += text
112
+ } else {
113
+ lines.push(text)
114
+ }
115
+ }
116
+ let start = 0
117
+ let end = lines.length
118
+ while (start < end && !lines[start].trim()) {
119
+ start++
120
+ }
121
+ while (end > start && !lines[end - 1].trim()) {
122
+ end--
123
+ }
124
+ return lines.slice(start, end).join('\n')
87
125
  }
88
126
  }
@@ -44,12 +44,23 @@ export const contextMenuMixin = {
44
44
  disabled: !hasSelection
45
45
  },
46
46
  {
47
-
48
47
  key: 'onSelectAll',
49
48
  icon: <iconsMap.CheckSquareOutlined />,
50
49
  label: e('selectall'),
51
50
  extra: selectAllShortcut
52
51
  },
52
+ // Touch only: a selection dragged out on the canvas can only ever be an
53
+ // approximation of a native one, so offer the overlay where the OS does
54
+ // the selecting (see term-touch.js / terminal-select-text.jsx).
55
+ ...(
56
+ this.isTouchMode()
57
+ ? [{
58
+ key: 'onSelectTextMode',
59
+ icon: <iconsMap.SelectOutlined />,
60
+ label: e('selectText')
61
+ }]
62
+ : []
63
+ ),
53
64
  ...(
54
65
  isAIDisabled()
55
66
  ? []
@@ -124,11 +135,25 @@ export const contextMenuMixin = {
124
135
  ) {
125
136
  return false
126
137
  }
138
+ // While a touch drag is still building the selection we copy once on
139
+ // release instead — otherwise every cell the finger crosses would write
140
+ // the clipboard and raise a toast.
141
+ if (this.dragSelect) {
142
+ return false
143
+ }
127
144
  this.copySelectionToClipboard()
128
145
  },
129
146
 
130
147
  copySelectionToClipboard () {
131
- const txt = this.term.getSelection()
148
+ this.copyToClipboard(this.term.getSelection())
149
+ },
150
+
151
+ /**
152
+ * Shared clipboard write. Lives here rather than in term-touch.js so that
153
+ * the touch module stays free of imports (it is loaded directly by a
154
+ * node:test unit spec), and so every copy raises the same `copied` toast.
155
+ */
156
+ copyToClipboard (txt) {
132
157
  if (txt) {
133
158
  copy(txt)
134
159
  }
@@ -152,6 +177,9 @@ export const contextMenuMixin = {
152
177
  },
153
178
 
154
179
  pasteTextTooLong () {
180
+ if (this.props.config.disableConfirmForLargeClipboardContent) {
181
+ return false
182
+ }
155
183
  if (window.et.isWebApp) {
156
184
  return false
157
185
  }
@@ -180,7 +208,11 @@ export const contextMenuMixin = {
180
208
 
181
209
  async onPaste (skipTextLengthCheck) {
182
210
  let selected = await readClipboardAsync()
183
- if (!skipTextLengthCheck && selected.length > 500) {
211
+ if (
212
+ !skipTextLengthCheck &&
213
+ !this.props.config.disableConfirmForLargeClipboardContent &&
214
+ selected.length > 500
215
+ ) {
184
216
  return this.askUserConfirm()
185
217
  }
186
218
  if (isWin && this.isRemote()) {
@@ -18,9 +18,9 @@ import { XmodemClient } from '../xmodem-client.js'
18
18
  import { loadWebLinksAddon } from '../xterm-loader.js'
19
19
  import { KeywordHighlighterAddon } from '../highlight-addon.js'
20
20
  import {
21
- createSshReloadState,
21
+ createTerminalReloadState,
22
22
  getAlternateBufferSnapshot,
23
- shouldCaptureSshReloadState
23
+ shouldCaptureTerminalReloadState
24
24
  } from '../ssh-reload-state.js'
25
25
 
26
26
  // Expands \n \t \r \\ and \xHH hex byte escapes, used to let users type
@@ -58,7 +58,7 @@ function expandCloseSequence (text) {
58
58
  /**
59
59
  * Session lifecycle: opening the pty/ssh session over its websocket, error
60
60
  * and reconnect handling, input broadcast, and the screen snapshot used to
61
- * restore an ssh session after a reload.
61
+ * restore a shell session (ssh, local, telnet, serial) after a reload.
62
62
  */
63
63
  export const socketMixin = {
64
64
  buildWsUrl (port) {
@@ -392,7 +392,7 @@ export const socketMixin = {
392
392
  },
393
393
 
394
394
  getReloadState () {
395
- if (!shouldCaptureSshReloadState(this.props.tab, this.props.config)) {
395
+ if (!shouldCaptureTerminalReloadState(this.props.tab, this.props.config)) {
396
396
  return undefined
397
397
  }
398
398
  let screen = ''
@@ -413,7 +413,7 @@ export const socketMixin = {
413
413
  console.warn('Failed to serialize terminal before reload', e)
414
414
  }
415
415
  const cwd = this.cmdAddon?.getCwd() || this.props.tab._reloadState?.cwd || ''
416
- return createSshReloadState({ cwd, screen })
416
+ return createTerminalReloadState({ cwd, screen })
417
417
  },
418
418
 
419
419
  restoreReloadScreen (term) {