@electerm/electerm-react 1.34.68 → 1.35.0

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 (46) hide show
  1. package/client/common/constants.js +3 -1
  2. package/client/common/key-pressed.js +1 -1
  3. package/client/common/rand-hex-color.js +28 -0
  4. package/client/common/shortcuts-defaults.js +51 -0
  5. package/client/components/batch-op/batch-op.jsx +6 -2
  6. package/client/components/bookmark-form/color-picker-item.jsx +14 -0
  7. package/client/components/bookmark-form/color-picker.jsx +90 -0
  8. package/client/components/bookmark-form/color-picker.styl +20 -0
  9. package/client/components/bookmark-form/form-ssh-common.jsx +4 -0
  10. package/client/components/bookmark-form/hex-input.jsx +39 -0
  11. package/client/components/bookmark-form/local-form-ui.jsx +1 -0
  12. package/client/components/bookmark-form/serial-form-ui.jsx +12 -8
  13. package/client/components/bookmark-form/ssh-form-ui.jsx +3 -0
  14. package/client/components/bookmark-form/telnet-form-ui.jsx +1 -0
  15. package/client/components/bookmark-form/use-ui.jsx +11 -1
  16. package/client/components/context-menu/context-menu.styl +1 -1
  17. package/client/components/context-menu/menu-btn.jsx +6 -3
  18. package/client/components/main/custom-css.jsx +28 -0
  19. package/client/components/main/main.jsx +5 -2
  20. package/client/components/session/session.jsx +11 -35
  21. package/client/components/session/sessions.jsx +15 -15
  22. package/client/components/setting-panel/setting.jsx +20 -32
  23. package/client/components/setting-panel/tab-settings.jsx +13 -10
  24. package/client/components/sftp/transfer-tag.jsx +2 -2
  25. package/client/components/sftp/transport-action.jsx +1 -0
  26. package/client/components/shortcuts/get-key-char.js +45 -0
  27. package/client/components/shortcuts/shortcut-control.jsx +63 -0
  28. package/client/components/shortcuts/shortcut-editor.jsx +194 -0
  29. package/client/components/shortcuts/shortcut-handler.js +76 -0
  30. package/client/components/shortcuts/shortcut.styl +0 -0
  31. package/client/components/shortcuts/shortcuts-defaults.js +87 -0
  32. package/client/components/shortcuts/shortcuts.jsx +166 -0
  33. package/client/components/sidebar/index.jsx +1 -1
  34. package/client/components/sidebar/transfer-history-modal.jsx +14 -2
  35. package/client/components/tabs/index.jsx +0 -25
  36. package/client/components/tabs/tab.jsx +6 -5
  37. package/client/components/terminal/index.jsx +93 -110
  38. package/client/components/terminal/term-search.jsx +9 -21
  39. package/client/components/terminal-theme/index.jsx +4 -3
  40. package/client/store/index.js +17 -2
  41. package/client/store/init-state.js +1 -8
  42. package/client/store/item.js +3 -0
  43. package/client/store/session.js +0 -22
  44. package/client/store/watch.js +3 -1
  45. package/client/views/index.pug +2 -0
  46. package/package.json +1 -1
@@ -0,0 +1,87 @@
1
+ export default () => {
2
+ return [
3
+ {
4
+ name: 'app_closeCurrentTab',
5
+ shortcut: 'ctrl+w',
6
+ shortcutMac: 'ctrl+w'
7
+ },
8
+ {
9
+ name: 'app_newBookmark',
10
+ shortcut: 'ctrl+b',
11
+ shortcutMac: 'meta+b'
12
+ },
13
+ {
14
+ name: 'app_togglefullscreen',
15
+ shortcut: 'alt+f',
16
+ shortcutMac: 'alt+f'
17
+ },
18
+ {
19
+ name: 'app_zoomin',
20
+ shortcut: 'ctrl+=',
21
+ shortcutMac: 'meta+='
22
+ },
23
+ {
24
+ name: 'app_zoomout',
25
+ shortcut: 'ctrl+-',
26
+ shortcutMac: 'meta+-'
27
+ },
28
+ {
29
+ name: 'app_prevTab',
30
+ shortcut: 'ctrl+shift+tab',
31
+ shortcutMac: 'ctrl+shift+tab'
32
+ },
33
+ {
34
+ name: 'app_nextTab',
35
+ shortcut: 'ctrl+tab',
36
+ shortcutMac: 'ctrl+tab'
37
+ },
38
+ {
39
+ name: 'terminal_clear',
40
+ shortcut: 'ctrl+l,ctrl+shift+l',
41
+ shortcutMac: 'meta+l'
42
+ },
43
+ {
44
+ name: 'terminal_selectAll',
45
+ shortcut: 'ctrl+a,ctrl+shift+a',
46
+ shortcutMac: 'meta+a',
47
+ readonly: true
48
+ },
49
+ {
50
+ name: 'terminal_copy',
51
+ shortcut: 'ctrl+c,ctrl+shift+c',
52
+ shortcutMac: 'meta+c',
53
+ readonly: true
54
+ },
55
+ {
56
+ name: 'terminal_paste',
57
+ shortcut: 'ctrl+v,ctrl+shift+v',
58
+ shortcutMac: 'meta+v',
59
+ readonly: true
60
+ },
61
+ {
62
+ name: 'terminal_search',
63
+ shortcut: 'ctrl+f',
64
+ shortcutMac: 'meta+f'
65
+ },
66
+ {
67
+ name: 'terminal_pasteSelected',
68
+ shortcut: 'alt+insert',
69
+ shortcutMac: 'alt+insert'
70
+ },
71
+ {
72
+ name: 'terminal_showNormalBuffer',
73
+ shortcut: 'ctrl+ArrowUp',
74
+ shortcutMac: 'meta+↑'
75
+ },
76
+ {
77
+ name: 'terminal_zoominTerminal',
78
+ shortcut: 'ctrl+▲',
79
+ shortcutMac: 'meta+▲'
80
+ },
81
+ {
82
+ name: 'terminal_zoomoutTerminal',
83
+ shortcut: 'ctrl+▼',
84
+ shortcutMac: 'meta+▼'
85
+ }
86
+ ]
87
+ }
@@ -0,0 +1,166 @@
1
+ import { Component } from '../common/react-subx'
2
+ import shortcutsDefaultsGen from './shortcuts-defaults'
3
+ import ShortcutEdit from './shortcut-editor'
4
+ import deepCopy from 'json-deep-copy'
5
+ import {
6
+ Table,
7
+ Button
8
+ } from 'antd'
9
+ import {
10
+ isMacJs as isMac
11
+ } from '../../common/constants.js'
12
+
13
+ const { prefix } = window
14
+ const e = prefix('form')
15
+ const c = prefix('control')
16
+ const m = prefix('menu')
17
+ const ss = prefix('ssh')
18
+ const s = prefix('setting')
19
+ const shortcutsDefaults = shortcutsDefaultsGen()
20
+
21
+ export default class Shortcuts extends Component {
22
+ handleResetAll = () => {
23
+ this.props.store.updateConfig({
24
+ shortcuts: {}
25
+ })
26
+ }
27
+
28
+ updateConfig = (name, value) => {
29
+ const { store } = this.props
30
+ const shortcuts = deepCopy(store.config.shortcuts || {})
31
+ shortcuts[name] = value
32
+ this.props.store.updateConfig({
33
+ shortcuts
34
+ })
35
+ }
36
+
37
+ getData () {
38
+ const { shortcuts = {} } = this.props.store.config
39
+ return shortcutsDefaults.map((c, i) => {
40
+ const propName = isMac ? 'shortcutMac' : 'shortcut'
41
+ const name = c.name + '_' + propName
42
+ return {
43
+ index: i + 1,
44
+ name,
45
+ readonly: c.readonly,
46
+ shortcut: c.readonly ? c[propName] : (shortcuts[name] || c[propName])
47
+ }
48
+ })
49
+ }
50
+
51
+ getKeysTakenData = () => {
52
+ const { shortcuts = {} } = this.props.store.config
53
+ return shortcutsDefaults
54
+ .reduce((p, k) => {
55
+ const propName = isMac ? 'shortcutMac' : 'shortcut'
56
+ const name = k.name + '_' + propName
57
+ const vv = k.readonly ? k[propName] : (shortcuts[name] || k[propName])
58
+ const v = vv
59
+ .split(',')
60
+ .map(f => f.trim())
61
+ .reduce((p, k, i) => {
62
+ return {
63
+ ...p,
64
+ [k]: true
65
+ }
66
+ }, {})
67
+ return {
68
+ ...p,
69
+ ...v
70
+ }
71
+ }, {})
72
+ }
73
+
74
+ render () {
75
+ const { store } = this.props
76
+ const columns = [
77
+ {
78
+ title: 'NO.',
79
+ dataIndex: 'index',
80
+ key: 'index',
81
+ render: (index) => {
82
+ return index
83
+ }
84
+ },
85
+ {
86
+ title: e('description'),
87
+ dataIndex: 'name',
88
+ key: 'name',
89
+ render: (name) => {
90
+ const [a, b] = name.split('_')
91
+ const pre = a === 'terminal' ? `[${ss('terminal')}] ` : ''
92
+ if (
93
+ [
94
+ 'clear', 'selectAll', 'search'
95
+ ].includes(b)
96
+ ) {
97
+ return pre + ss(b)
98
+ } else if (b === 'copy') {
99
+ return pre + m(b)
100
+ } else if (b === 'newBookmark') {
101
+ return pre + c(b)
102
+ } else if (b.includes('zoomin')) {
103
+ return pre + m('zoomin')
104
+ } else if (b.includes('zoomout')) {
105
+ return pre + m('zoomout')
106
+ } else if (['togglefullscreen'].includes(b)) {
107
+ return pre + m(b)
108
+ } else {
109
+ return pre + s(b)
110
+ }
111
+ }
112
+ },
113
+ {
114
+ title: s('shortcut'),
115
+ dataIndex: 'shortcut',
116
+ key: 'shortcut',
117
+ render: (shortcut, inst) => {
118
+ const { readonly } = inst
119
+ if (readonly) {
120
+ return (
121
+ <span className='readonly'>
122
+ {
123
+ shortcut.split(',').map(s => {
124
+ return (
125
+ <span className='shortcut-unit' key={s}>{s}</span>
126
+ )
127
+ })
128
+ }
129
+ </span>
130
+ )
131
+ }
132
+ return (
133
+ <ShortcutEdit
134
+ data={inst}
135
+ keysTaken={this.getKeysTakenData()}
136
+ store={store}
137
+ updateConfig={this.updateConfig}
138
+ />
139
+ )
140
+ }
141
+ }
142
+ ]
143
+ const props = {
144
+ dataSource: this.getData(),
145
+ columns,
146
+ bordered: true,
147
+ pagination: false,
148
+ size: 'small',
149
+ rowKey: 'id'
150
+ }
151
+ return (
152
+ <div>
153
+ <Table
154
+ {...props}
155
+ />
156
+ <div className='pd1y'>
157
+ <Button
158
+ onClick={this.handleResetAll}
159
+ >
160
+ {s('resetAllToDefault')}
161
+ </Button>
162
+ </div>
163
+ </div>
164
+ )
165
+ }
166
+ }
@@ -116,7 +116,7 @@ export default class Sidebar extends Component {
116
116
  >
117
117
  <div className='sidebar-bar btns'>
118
118
  <div className='control-icon-wrap'>
119
- <MenuBtn store={store} />
119
+ <MenuBtn store={store} config={store.config} />
120
120
  </div>
121
121
  <SideIcon
122
122
  title={e('newBookmark')}
@@ -22,12 +22,20 @@ const sorterFactory = prop => {
22
22
  }
23
23
  }
24
24
  export default class TransferHistoryModal extends Component {
25
+ state = {
26
+ pageSize: 5
27
+ }
28
+
29
+ handlePageSizeChange = (page, pageSize) => {
30
+ this.setState({ pageSize })
31
+ }
32
+
25
33
  render () {
26
34
  const {
27
35
  getTransferHistory,
28
36
  clearTransferHistory
29
37
  } = this.props.store
30
- const transferHistory = getTransferHistory()
38
+ const transferHistory = getTransferHistory().filter(d => !d.unzip)
31
39
  const columns = [{
32
40
  title: e('startTime'),
33
41
  dataIndex: 'startTime',
@@ -88,7 +96,11 @@ export default class TransferHistoryModal extends Component {
88
96
  columns,
89
97
  bordered: true,
90
98
  pagination: {
91
- pageSize: 10
99
+ pageSize: this.state.pageSize,
100
+ showSizeChanger: true,
101
+ pageSizeOptions: [5, 10, 20, 50, 100],
102
+ onChange: this.handlePageSizeChange,
103
+ position: ['topRight']
92
104
  },
93
105
  size: 'small',
94
106
  rowKey: 'id'
@@ -42,7 +42,6 @@ export default class Tabs extends React.Component {
42
42
  const {
43
43
  tabsRef
44
44
  } = this
45
- window.addEventListener('keypress', this.handleTabHotkey)
46
45
  tabsRef.current.addEventListener('dblclick', this.handleDblClickEvent)
47
46
  tabsRef.current.addEventListener('mousedown', this.handleClickEvent)
48
47
  }
@@ -58,14 +57,6 @@ export default class Tabs extends React.Component {
58
57
  }
59
58
  }
60
59
 
61
- // componentWillUnmount () {
62
- // const {
63
- // tabsRef
64
- // } = this
65
- // window.removeEventListener('keydown', this.handleTabHotkey)
66
- // tabsRef.current.removeEventListener('mousedown', this.handleClickEvent)
67
- // }
68
-
69
60
  tabsWidth = () => {
70
61
  return Array.from(
71
62
  document.querySelectorAll('.tab')
@@ -83,22 +74,6 @@ export default class Tabs extends React.Component {
83
74
  return width < (tabsWidthAll + addBtnWidth)
84
75
  }
85
76
 
86
- handleTabHotkey = e => {
87
- if (
88
- e.ctrlKey &&
89
- e.code === 'Tab' &&
90
- !e.shiftKey
91
- ) {
92
- window.store.clickNextTab()
93
- } else if (
94
- e.ctrlKey &&
95
- e.code === 'Tab' &&
96
- e.shiftKey
97
- ) {
98
- window.store.clickPrevTab()
99
- }
100
- }
101
-
102
77
  handleClickEvent = (e) => {
103
78
  if (e.button === 1) {
104
79
  const p = findParentBySel(e.target, '.tab')
@@ -19,7 +19,6 @@ import createName from '../../common/create-title'
19
19
  import { addClass, removeClass } from '../../common/class'
20
20
  import {
21
21
  terminalSshConfigType,
22
- ctrlOrCmd,
23
22
  commonActions
24
23
  } from '../../common/constants'
25
24
 
@@ -255,8 +254,7 @@ export default class Tab extends React.Component {
255
254
  res.push({
256
255
  func: 'handleClose',
257
256
  icon: 'CloseOutlined',
258
- text: e('close'),
259
- subText: `${ctrlOrCmd} + W`
257
+ text: e('close')
260
258
  })
261
259
  res.push({
262
260
  func: 'closeOther',
@@ -359,7 +357,7 @@ export default class Tab extends React.Component {
359
357
  } = this.props
360
358
  const { isLast } = this.props
361
359
  const { tab, terminalOnData } = this.state
362
- const { id, isEditting, status, isTransporting, tabCount } = tab
360
+ const { id, isEditting, status, isTransporting, tabCount, color } = tab
363
361
  const active = id === currentTabId
364
362
  const cls = classnames(
365
363
  `tab-${id}`,
@@ -380,6 +378,9 @@ export default class Tab extends React.Component {
380
378
  if (isEditting) {
381
379
  return this.renderEditting(tab, cls)
382
380
  }
381
+ const styleTag = color
382
+ ? { color }
383
+ : {}
383
384
  return (
384
385
  <Tooltip
385
386
  title={title}
@@ -412,7 +413,7 @@ export default class Tab extends React.Component {
412
413
  onClick={this.handleReloadTab}
413
414
  title={m('reload')}
414
415
  />
415
- {tabCount}. {title}
416
+ <span style={styleTag}>♦</span> {tabCount}. {title}
416
417
  </div>
417
418
  <div className={'tab-status ' + status} />
418
419
  <div className='tab-traffic' />
@@ -10,7 +10,6 @@ import {
10
10
  CheckCircleOutlined,
11
11
  ReloadOutlined
12
12
  } from '@ant-design/icons'
13
-
14
13
  import {
15
14
  notification,
16
15
  Spin,
@@ -26,7 +25,6 @@ import {
26
25
  paneMap,
27
26
  typeMap,
28
27
  isWin,
29
- isMac,
30
28
  terminalSshConfigType,
31
29
  transferTypeMap,
32
30
  terminalActions,
@@ -47,13 +45,12 @@ import getProxy from '../../common/get-proxy'
47
45
  import { Zmodem, AddonZmodem } from './xterm-zmodem'
48
46
  import { Unicode11Addon } from 'xterm-addon-unicode11'
49
47
  import keyControlPressed from '../../common/key-control-pressed'
50
- import keyShiftPressed from '../../common/key-shift-pressed'
51
- import keyPressed from '../../common/key-pressed'
52
48
  import { Terminal } from 'xterm'
53
49
  import * as ls from '../../common/safe-local-storage'
54
50
  import NormalBuffer from './normal-buffer'
55
51
  import { createTerm, resizeTerm } from './terminal-apis'
56
52
  import createLsId from './build-ls-term-id'
53
+ import { shortcutExtend, shortcutDescExtend } from '../shortcuts/shortcut-handler.js'
57
54
 
58
55
  const { prefix } = window
59
56
  const e = prefix('ssh')
@@ -70,7 +67,7 @@ const computePos = (e) => {
70
67
  }
71
68
  }
72
69
 
73
- export default class Term extends Component {
70
+ class Term extends Component {
74
71
  constructor (props) {
75
72
  super(props)
76
73
  this.state = {
@@ -223,13 +220,58 @@ export default class Term extends Component {
223
220
  this.props.pane === paneMap.terminal
224
221
  }
225
222
 
223
+ clearShortcut = (e) => {
224
+ e.stopPropagation()
225
+ this.onClear()
226
+ }
227
+
228
+ selectAllShortcut = (e) => {
229
+ e.stopPropagation()
230
+ this.term.selectAll()
231
+ }
232
+
233
+ copyShortcut = (e) => {
234
+ const sel = this.term.getSelection()
235
+ if (sel) {
236
+ e.stopPropagation()
237
+ e.preventDefault()
238
+ this.copySelectionToClipboard()
239
+ return false
240
+ }
241
+ }
242
+
243
+ searchShortcut = (e) => {
244
+ e.stopPropagation()
245
+ this.toggleSearch()
246
+ }
247
+
248
+ pasteSelectedShortcut = (e) => {
249
+ e.stopPropagation()
250
+ this.tryInsertSelected()
251
+ }
252
+
253
+ showNormalBufferShortcut = (e) => {
254
+ e.stopPropagation()
255
+ this.openNormalBuffer()
256
+ }
257
+
258
+ prevTabShortcut = debounce((e) => {
259
+ e.stopPropagation()
260
+ window.store.clickPrevTab()
261
+ }, 300)
262
+
263
+ nextTabShortcut = debounce((e) => {
264
+ e.stopPropagation()
265
+ window.store.clickNextTab()
266
+ }, 300)
267
+
226
268
  handleEvent = (e) => {
227
269
  const {
228
270
  keyword,
229
271
  options,
230
272
  action,
231
273
  encode,
232
- id,
274
+ // id,
233
275
  type,
234
276
  cmd,
235
277
  activeSplitId,
@@ -312,67 +354,6 @@ export default class Term extends Component {
312
354
  e.stopPropagation()
313
355
  return this.term && this.term.blur()
314
356
  }
315
- if (
316
- keyControlPressed(e) &&
317
- !keyShiftPressed(e) &&
318
- keyPressed(e, 'c')
319
- ) {
320
- const sel = this.term.getSelection()
321
- if (sel) {
322
- e.stopPropagation()
323
- e.preventDefault()
324
- this.copySelectionToClipboard()
325
- return false
326
- }
327
- } else if (
328
- keyControlPressed(e) &&
329
- keyShiftPressed(e) &&
330
- keyPressed(e, 'c')
331
- ) {
332
- e.stopPropagation()
333
- this.copySelectionToClipboard()
334
- } else if (id === this.props.id) {
335
- e.stopPropagation()
336
- this.term.selectAll()
337
- } else if (
338
- keyPressed(e, 'f') && keyControlPressed(e) &&
339
- (
340
- isMac ||
341
- (!isMac && keyShiftPressed(e))
342
- )
343
- ) {
344
- e.stopPropagation()
345
- this.toggleSearch()
346
- } else if (
347
- keyPressed(e, 'tab')
348
- ) {
349
- e.stopPropagation()
350
- e.preventDefault()
351
- if (e.ctrlKey && e.type === 'keydown') {
352
- if (e.shiftKey) {
353
- window.store.clickPrevTab()
354
- } else {
355
- window.store.clickNextTab()
356
- }
357
- return false
358
- }
359
- } else if (
360
- keyControlPressed(e) &&
361
- keyPressed(e, 'ArrowUp') && this.bufferMode === 'alternate'
362
- ) {
363
- e.stopPropagation()
364
- this.openNormalBuffer()
365
- } else if (
366
- e.ctrlKey &&
367
- keyPressed(e, 'tab')
368
- ) {
369
- this.onClear()
370
- } else if (
371
- e.altKey &&
372
- keyPressed(e, 'insert')
373
- ) {
374
- this.tryInsertSelected()
375
- }
376
357
  }
377
358
 
378
359
  onDrop = e => {
@@ -692,12 +673,11 @@ export default class Term extends Component {
692
673
  renderContext = () => {
693
674
  const hasSlected = this.term.hasSelection()
694
675
  const copyed = readClipboard()
695
- const copyShortcut = isMac
696
- ? 'Command+C'
697
- : 'Ctrl+Shift+C'
698
- const pasteShortcut = isMac
699
- ? 'Command+V'
700
- : 'Ctrl+Shift+V'
676
+ const copyShortcut = this.getShortcut('terminal_copy')
677
+ const pasteShortcut = this.getShortcut('terminal_paste')
678
+ const clearShortcut = this.getShortcut('terminal_clear')
679
+ const selectAllShortcut = this.getShortcut('terminal_selectAll')
680
+ const searchShortcut = this.getShortcut('terminal_search')
701
681
  return [
702
682
  {
703
683
  func: 'onCopy',
@@ -717,17 +697,19 @@ export default class Term extends Component {
717
697
  func: 'onClear',
718
698
  icon: 'ReloadOutlined',
719
699
  text: e('clear'),
720
- subText: 'Ctrl+L'
700
+ subText: clearShortcut
721
701
  },
722
702
  {
723
703
  func: 'onSelectAll',
724
704
  icon: 'SelectOutlined',
725
- text: e('selectAll')
705
+ text: e('selectAll'),
706
+ subText: selectAllShortcut
726
707
  },
727
708
  {
728
709
  func: 'toggleSearch',
729
710
  icon: 'SearchOutlined',
730
- text: e('search')
711
+ text: e('search'),
712
+ subText: searchShortcut
731
713
  },
732
714
  {
733
715
  func: 'split',
@@ -837,7 +819,7 @@ export default class Term extends Component {
837
819
  // term.on('keydown', this.handleEvent)
838
820
  term.onData(this.onData)
839
821
  this.term = term
840
- term.attachCustomKeyEventHandler(this.handleEvent)
822
+ term.attachCustomKeyEventHandler(this.handleKeyboardEvent.bind(this))
841
823
  term.onKey(this.onKey)
842
824
  // if (host && !password && !privateKey) {
843
825
  // return this.promote()
@@ -895,16 +877,6 @@ export default class Term extends Component {
895
877
  })
896
878
  }
897
879
 
898
- watchNormalBufferTrigger = e => {
899
- if (
900
- keyControlPressed(e) &&
901
- keyPressed(e, 'ArrowUp')
902
- ) {
903
- e.stopPropagation()
904
- this.copySelectionToClipboard()
905
- }
906
- }
907
-
908
880
  openNormalBuffer = () => {
909
881
  const normal = this.term.buffer._normal
910
882
  const len = normal.length
@@ -940,7 +912,8 @@ export default class Term extends Component {
940
912
  srcId, from = 'bookmarks',
941
913
  type,
942
914
  encode,
943
- term: terminalType
915
+ term: terminalType,
916
+ displayRaw
944
917
  } = tab
945
918
  const { savePassword } = this.state
946
919
  const isSshConfig = type === terminalSshConfigType
@@ -1054,32 +1027,40 @@ export default class Term extends Component {
1054
1027
  }
1055
1028
 
1056
1029
  // this.decoder = new TextDecoder(encode)
1057
- // const oldWrite = term.write
1058
- // const th = this
1059
- // term.write = function (data) {
1060
- // let str = ''
1061
- // if (typeof data === 'object') {
1062
- // if (data instanceof ArrayBuffer) {
1063
- // str = th.decoder.decode(data)
1064
- // oldWrite.call(term, str)
1065
- // } else {
1066
- // const fileReader = new FileReader()
1067
- // fileReader.addEventListener('load', () => {
1068
- // str = th.decoder.decode(fileReader.result)
1069
- // oldWrite.call(term, str)
1070
- // })
1071
- // fileReader.readAsArrayBuffer(new window.Blob([data]))
1072
- // }
1073
- // } else if (typeof data === 'string') {
1074
- // oldWrite.call(term, data)
1075
- // } else {
1076
- // throw Error(`Cannot handle ${typeof data} websocket message.`)
1077
- // }
1078
- // }
1030
+ if (displayRaw) {
1031
+ const oldWrite = term.write
1032
+ const th = this
1033
+ term.write = function (data) {
1034
+ // let str = ''
1035
+ // if (typeof data === 'object') {
1036
+ // if (data instanceof ArrayBuffer) {
1037
+ // str = th.decoder.decode(data)
1038
+ // oldWrite.call(term, th.escape(str))
1039
+ // } else {
1040
+ // const fileReader = new FileReader()
1041
+ // fileReader.addEventListener('load', () => {
1042
+ // str = th.decoder.decode(fileReader.result)
1043
+ // oldWrite.call(term, th.escape(str))
1044
+ // })
1045
+ // fileReader.readAsArrayBuffer(new window.Blob([data]))
1046
+ // }
1047
+ // } else if (typeof data === 'string') {
1048
+ // oldWrite.call(term, th.escape(data))
1049
+ // } else {
1050
+ // throw Error(`Cannot handle ${typeof data} websocket message.`)
1051
+ // }
1052
+ oldWrite.call(term, th.escape(data))
1053
+ }
1054
+ }
1079
1055
  this.term = term
1080
1056
  window.store.triggerResize()
1081
1057
  }
1082
1058
 
1059
+ escape = str => {
1060
+ return str.replace(/\\x1B/g, '\\x1B')
1061
+ .replace(/\033/g, '\\033')
1062
+ }
1063
+
1083
1064
  onKey = (key, e) => {
1084
1065
  // log.log('onKey', key, e)
1085
1066
  }
@@ -1382,3 +1363,5 @@ export default class Term extends Component {
1382
1363
  )
1383
1364
  }
1384
1365
  }
1366
+
1367
+ export default shortcutDescExtend(shortcutExtend(Term))