@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.
- package/client/common/default-setting.js +1 -0
- package/client/common/download.jsx +12 -0
- package/client/common/resolve.js +20 -14
- package/client/components/ai/ai-history-item.jsx +1 -1
- package/client/components/ai/ai-history.jsx +1 -0
- package/client/components/ai/ai-history.styl +23 -0
- package/client/components/bookmark-form/common/color-picker.styl +3 -0
- package/client/components/common/remote-pointer.js +49 -0
- package/client/components/common/remote-session-shell.jsx +137 -0
- package/client/components/common/remote-session-shell.styl +80 -0
- package/client/components/common/responsive-tabs.jsx +89 -0
- package/client/components/common/responsive-tabs.styl +34 -0
- package/client/components/footer/cmd-history.jsx +132 -45
- package/client/components/footer/cmd-history.styl +42 -4
- package/client/components/footer/multi-tab-run-modal.jsx +83 -0
- package/client/components/footer/tab-select.jsx +34 -17
- package/client/components/quick-commands/quick-command-create-modal.jsx +60 -0
- package/client/components/quick-commands/quick-commands-form-elem.jsx +10 -4
- package/client/components/rdp/rdp-session.jsx +94 -124
- package/client/components/rdp/rdp.styl +13 -36
- package/client/components/session/session.styl +0 -16
- package/client/components/setting-panel/setting-modal.jsx +8 -3
- package/client/components/setting-panel/setting-terminal.jsx +1 -0
- package/client/components/sftp/sftp-entry.jsx +30 -0
- package/client/components/sidebar/side-panel.jsx +1 -1
- package/client/components/spice/spice-session.jsx +69 -72
- package/client/components/spice/spice.styl +10 -19
- package/client/components/terminal/mixins/term-content.js +38 -0
- package/client/components/terminal/mixins/term-context-menu.jsx +35 -3
- package/client/components/terminal/mixins/term-socket.js +5 -5
- package/client/components/terminal/mixins/term-touch.js +444 -57
- package/client/components/terminal/shortcut-bar-defs.js +30 -4
- package/client/components/terminal/shortcut-bar-edit.jsx +40 -9
- package/client/components/terminal/shortcut-bar.jsx +13 -4
- package/client/components/terminal/ssh-reload-state.js +41 -1
- package/client/components/terminal/startup-queue.js +67 -13
- package/client/components/terminal/terminal-select-text.jsx +69 -0
- package/client/components/terminal/terminal.jsx +72 -4
- package/client/components/terminal/terminal.styl +61 -0
- package/client/components/theme/theme-form.jsx +18 -21
- package/client/components/theme/theme-form.styl +8 -10
- package/client/components/vnc/vnc-session.jsx +72 -104
- package/client/components/vnc/vnc.styl +25 -16
- package/client/css/mobile.styl +20 -7
- package/client/store/setting.js +4 -0
- package/client/store/tab.js +5 -4
- 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
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
.
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
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
|
-
|
|
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 (
|
|
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
|
-
|
|
21
|
+
createTerminalReloadState,
|
|
22
22
|
getAlternateBufferSnapshot,
|
|
23
|
-
|
|
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
|
|
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 (!
|
|
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
|
|
416
|
+
return createTerminalReloadState({ cwd, screen })
|
|
417
417
|
},
|
|
418
418
|
|
|
419
419
|
restoreReloadScreen (term) {
|