@xterm/xterm 5.4.0-beta.1

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 (108) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +235 -0
  3. package/css/xterm.css +209 -0
  4. package/lib/xterm.js +2 -0
  5. package/lib/xterm.js.map +1 -0
  6. package/package.json +101 -0
  7. package/src/browser/AccessibilityManager.ts +278 -0
  8. package/src/browser/Clipboard.ts +93 -0
  9. package/src/browser/ColorContrastCache.ts +34 -0
  10. package/src/browser/Lifecycle.ts +33 -0
  11. package/src/browser/Linkifier2.ts +416 -0
  12. package/src/browser/LocalizableStrings.ts +12 -0
  13. package/src/browser/OscLinkProvider.ts +128 -0
  14. package/src/browser/RenderDebouncer.ts +83 -0
  15. package/src/browser/Terminal.ts +1317 -0
  16. package/src/browser/TimeBasedDebouncer.ts +86 -0
  17. package/src/browser/Types.d.ts +181 -0
  18. package/src/browser/Viewport.ts +401 -0
  19. package/src/browser/decorations/BufferDecorationRenderer.ts +134 -0
  20. package/src/browser/decorations/ColorZoneStore.ts +117 -0
  21. package/src/browser/decorations/OverviewRulerRenderer.ts +218 -0
  22. package/src/browser/input/CompositionHelper.ts +246 -0
  23. package/src/browser/input/Mouse.ts +54 -0
  24. package/src/browser/input/MoveToCell.ts +249 -0
  25. package/src/browser/public/Terminal.ts +260 -0
  26. package/src/browser/renderer/dom/DomRenderer.ts +509 -0
  27. package/src/browser/renderer/dom/DomRendererRowFactory.ts +526 -0
  28. package/src/browser/renderer/dom/WidthCache.ts +160 -0
  29. package/src/browser/renderer/shared/CellColorResolver.ts +137 -0
  30. package/src/browser/renderer/shared/CharAtlasCache.ts +96 -0
  31. package/src/browser/renderer/shared/CharAtlasUtils.ts +75 -0
  32. package/src/browser/renderer/shared/Constants.ts +14 -0
  33. package/src/browser/renderer/shared/CursorBlinkStateManager.ts +146 -0
  34. package/src/browser/renderer/shared/CustomGlyphs.ts +687 -0
  35. package/src/browser/renderer/shared/DevicePixelObserver.ts +41 -0
  36. package/src/browser/renderer/shared/README.md +1 -0
  37. package/src/browser/renderer/shared/RendererUtils.ts +58 -0
  38. package/src/browser/renderer/shared/SelectionRenderModel.ts +91 -0
  39. package/src/browser/renderer/shared/TextureAtlas.ts +1082 -0
  40. package/src/browser/renderer/shared/Types.d.ts +173 -0
  41. package/src/browser/selection/SelectionModel.ts +144 -0
  42. package/src/browser/selection/Types.d.ts +15 -0
  43. package/src/browser/services/CharSizeService.ts +102 -0
  44. package/src/browser/services/CharacterJoinerService.ts +339 -0
  45. package/src/browser/services/CoreBrowserService.ts +137 -0
  46. package/src/browser/services/MouseService.ts +46 -0
  47. package/src/browser/services/RenderService.ts +279 -0
  48. package/src/browser/services/SelectionService.ts +1031 -0
  49. package/src/browser/services/Services.ts +147 -0
  50. package/src/browser/services/ThemeService.ts +237 -0
  51. package/src/common/CircularList.ts +241 -0
  52. package/src/common/Clone.ts +23 -0
  53. package/src/common/Color.ts +357 -0
  54. package/src/common/CoreTerminal.ts +284 -0
  55. package/src/common/EventEmitter.ts +78 -0
  56. package/src/common/InputHandler.ts +3461 -0
  57. package/src/common/Lifecycle.ts +108 -0
  58. package/src/common/MultiKeyMap.ts +42 -0
  59. package/src/common/Platform.ts +44 -0
  60. package/src/common/SortedList.ts +118 -0
  61. package/src/common/TaskQueue.ts +166 -0
  62. package/src/common/TypedArrayUtils.ts +17 -0
  63. package/src/common/Types.d.ts +553 -0
  64. package/src/common/WindowsMode.ts +27 -0
  65. package/src/common/buffer/AttributeData.ts +196 -0
  66. package/src/common/buffer/Buffer.ts +654 -0
  67. package/src/common/buffer/BufferLine.ts +524 -0
  68. package/src/common/buffer/BufferRange.ts +13 -0
  69. package/src/common/buffer/BufferReflow.ts +223 -0
  70. package/src/common/buffer/BufferSet.ts +134 -0
  71. package/src/common/buffer/CellData.ts +94 -0
  72. package/src/common/buffer/Constants.ts +149 -0
  73. package/src/common/buffer/Marker.ts +43 -0
  74. package/src/common/buffer/Types.d.ts +52 -0
  75. package/src/common/data/Charsets.ts +256 -0
  76. package/src/common/data/EscapeSequences.ts +153 -0
  77. package/src/common/input/Keyboard.ts +398 -0
  78. package/src/common/input/TextDecoder.ts +346 -0
  79. package/src/common/input/UnicodeV6.ts +145 -0
  80. package/src/common/input/WriteBuffer.ts +246 -0
  81. package/src/common/input/XParseColor.ts +80 -0
  82. package/src/common/parser/Constants.ts +58 -0
  83. package/src/common/parser/DcsParser.ts +192 -0
  84. package/src/common/parser/EscapeSequenceParser.ts +792 -0
  85. package/src/common/parser/OscParser.ts +238 -0
  86. package/src/common/parser/Params.ts +229 -0
  87. package/src/common/parser/Types.d.ts +275 -0
  88. package/src/common/public/AddonManager.ts +53 -0
  89. package/src/common/public/BufferApiView.ts +35 -0
  90. package/src/common/public/BufferLineApiView.ts +29 -0
  91. package/src/common/public/BufferNamespaceApi.ts +36 -0
  92. package/src/common/public/ParserApi.ts +37 -0
  93. package/src/common/public/UnicodeApi.ts +27 -0
  94. package/src/common/services/BufferService.ts +151 -0
  95. package/src/common/services/CharsetService.ts +34 -0
  96. package/src/common/services/CoreMouseService.ts +318 -0
  97. package/src/common/services/CoreService.ts +87 -0
  98. package/src/common/services/DecorationService.ts +140 -0
  99. package/src/common/services/InstantiationService.ts +85 -0
  100. package/src/common/services/LogService.ts +124 -0
  101. package/src/common/services/OptionsService.ts +202 -0
  102. package/src/common/services/OscLinkService.ts +115 -0
  103. package/src/common/services/ServiceRegistry.ts +49 -0
  104. package/src/common/services/Services.ts +373 -0
  105. package/src/common/services/UnicodeService.ts +111 -0
  106. package/src/headless/Terminal.ts +136 -0
  107. package/src/headless/public/Terminal.ts +195 -0
  108. package/typings/xterm.d.ts +1857 -0
@@ -0,0 +1,792 @@
1
+ /**
2
+ * Copyright (c) 2018 The xterm.js authors. All rights reserved.
3
+ * @license MIT
4
+ */
5
+
6
+ import { IParsingState, IDcsHandler, IEscapeSequenceParser, IParams, IOscHandler, IHandlerCollection, CsiHandlerType, OscFallbackHandlerType, IOscParser, EscHandlerType, IDcsParser, DcsFallbackHandlerType, IFunctionIdentifier, ExecuteFallbackHandlerType, CsiFallbackHandlerType, EscFallbackHandlerType, PrintHandlerType, PrintFallbackHandlerType, ExecuteHandlerType, IParserStackState, ParserStackType, ResumableHandlersType } from 'common/parser/Types';
7
+ import { ParserState, ParserAction } from 'common/parser/Constants';
8
+ import { Disposable, toDisposable } from 'common/Lifecycle';
9
+ import { IDisposable } from 'common/Types';
10
+ import { Params } from 'common/parser/Params';
11
+ import { OscParser } from 'common/parser/OscParser';
12
+ import { DcsParser } from 'common/parser/DcsParser';
13
+
14
+ /**
15
+ * Table values are generated like this:
16
+ * index: currentState << TableValue.INDEX_STATE_SHIFT | charCode
17
+ * value: action << TableValue.TRANSITION_ACTION_SHIFT | nextState
18
+ */
19
+ const enum TableAccess {
20
+ TRANSITION_ACTION_SHIFT = 4,
21
+ TRANSITION_STATE_MASK = 15,
22
+ INDEX_STATE_SHIFT = 8
23
+ }
24
+
25
+ /**
26
+ * Transition table for EscapeSequenceParser.
27
+ */
28
+ export class TransitionTable {
29
+ public table: Uint8Array;
30
+
31
+ constructor(length: number) {
32
+ this.table = new Uint8Array(length);
33
+ }
34
+
35
+ /**
36
+ * Set default transition.
37
+ * @param action default action
38
+ * @param next default next state
39
+ */
40
+ public setDefault(action: ParserAction, next: ParserState): void {
41
+ this.table.fill(action << TableAccess.TRANSITION_ACTION_SHIFT | next);
42
+ }
43
+
44
+ /**
45
+ * Add a transition to the transition table.
46
+ * @param code input character code
47
+ * @param state current parser state
48
+ * @param action parser action to be done
49
+ * @param next next parser state
50
+ */
51
+ public add(code: number, state: ParserState, action: ParserAction, next: ParserState): void {
52
+ this.table[state << TableAccess.INDEX_STATE_SHIFT | code] = action << TableAccess.TRANSITION_ACTION_SHIFT | next;
53
+ }
54
+
55
+ /**
56
+ * Add transitions for multiple input character codes.
57
+ * @param codes input character code array
58
+ * @param state current parser state
59
+ * @param action parser action to be done
60
+ * @param next next parser state
61
+ */
62
+ public addMany(codes: number[], state: ParserState, action: ParserAction, next: ParserState): void {
63
+ for (let i = 0; i < codes.length; i++) {
64
+ this.table[state << TableAccess.INDEX_STATE_SHIFT | codes[i]] = action << TableAccess.TRANSITION_ACTION_SHIFT | next;
65
+ }
66
+ }
67
+ }
68
+
69
+
70
+ // Pseudo-character placeholder for printable non-ascii characters (unicode).
71
+ const NON_ASCII_PRINTABLE = 0xA0;
72
+
73
+
74
+ /**
75
+ * VT500 compatible transition table.
76
+ * Taken from https://vt100.net/emu/dec_ansi_parser.
77
+ */
78
+ export const VT500_TRANSITION_TABLE = (function (): TransitionTable {
79
+ const table: TransitionTable = new TransitionTable(4095);
80
+
81
+ // range macro for byte
82
+ const BYTE_VALUES = 256;
83
+ const blueprint = Array.apply(null, Array(BYTE_VALUES)).map((unused: any, i: number) => i);
84
+ const r = (start: number, end: number): number[] => blueprint.slice(start, end);
85
+
86
+ // Default definitions.
87
+ const PRINTABLES = r(0x20, 0x7f); // 0x20 (SP) included, 0x7F (DEL) excluded
88
+ const EXECUTABLES = r(0x00, 0x18);
89
+ EXECUTABLES.push(0x19);
90
+ EXECUTABLES.push.apply(EXECUTABLES, r(0x1c, 0x20));
91
+
92
+ const states: number[] = r(ParserState.GROUND, ParserState.DCS_PASSTHROUGH + 1);
93
+ let state: any;
94
+
95
+ // set default transition
96
+ table.setDefault(ParserAction.ERROR, ParserState.GROUND);
97
+ // printables
98
+ table.addMany(PRINTABLES, ParserState.GROUND, ParserAction.PRINT, ParserState.GROUND);
99
+ // global anywhere rules
100
+ for (state in states) {
101
+ table.addMany([0x18, 0x1a, 0x99, 0x9a], state, ParserAction.EXECUTE, ParserState.GROUND);
102
+ table.addMany(r(0x80, 0x90), state, ParserAction.EXECUTE, ParserState.GROUND);
103
+ table.addMany(r(0x90, 0x98), state, ParserAction.EXECUTE, ParserState.GROUND);
104
+ table.add(0x9c, state, ParserAction.IGNORE, ParserState.GROUND); // ST as terminator
105
+ table.add(0x1b, state, ParserAction.CLEAR, ParserState.ESCAPE); // ESC
106
+ table.add(0x9d, state, ParserAction.OSC_START, ParserState.OSC_STRING); // OSC
107
+ table.addMany([0x98, 0x9e, 0x9f], state, ParserAction.IGNORE, ParserState.SOS_PM_APC_STRING);
108
+ table.add(0x9b, state, ParserAction.CLEAR, ParserState.CSI_ENTRY); // CSI
109
+ table.add(0x90, state, ParserAction.CLEAR, ParserState.DCS_ENTRY); // DCS
110
+ }
111
+ // rules for executables and 7f
112
+ table.addMany(EXECUTABLES, ParserState.GROUND, ParserAction.EXECUTE, ParserState.GROUND);
113
+ table.addMany(EXECUTABLES, ParserState.ESCAPE, ParserAction.EXECUTE, ParserState.ESCAPE);
114
+ table.add(0x7f, ParserState.ESCAPE, ParserAction.IGNORE, ParserState.ESCAPE);
115
+ table.addMany(EXECUTABLES, ParserState.OSC_STRING, ParserAction.IGNORE, ParserState.OSC_STRING);
116
+ table.addMany(EXECUTABLES, ParserState.CSI_ENTRY, ParserAction.EXECUTE, ParserState.CSI_ENTRY);
117
+ table.add(0x7f, ParserState.CSI_ENTRY, ParserAction.IGNORE, ParserState.CSI_ENTRY);
118
+ table.addMany(EXECUTABLES, ParserState.CSI_PARAM, ParserAction.EXECUTE, ParserState.CSI_PARAM);
119
+ table.add(0x7f, ParserState.CSI_PARAM, ParserAction.IGNORE, ParserState.CSI_PARAM);
120
+ table.addMany(EXECUTABLES, ParserState.CSI_IGNORE, ParserAction.EXECUTE, ParserState.CSI_IGNORE);
121
+ table.addMany(EXECUTABLES, ParserState.CSI_INTERMEDIATE, ParserAction.EXECUTE, ParserState.CSI_INTERMEDIATE);
122
+ table.add(0x7f, ParserState.CSI_INTERMEDIATE, ParserAction.IGNORE, ParserState.CSI_INTERMEDIATE);
123
+ table.addMany(EXECUTABLES, ParserState.ESCAPE_INTERMEDIATE, ParserAction.EXECUTE, ParserState.ESCAPE_INTERMEDIATE);
124
+ table.add(0x7f, ParserState.ESCAPE_INTERMEDIATE, ParserAction.IGNORE, ParserState.ESCAPE_INTERMEDIATE);
125
+ // osc
126
+ table.add(0x5d, ParserState.ESCAPE, ParserAction.OSC_START, ParserState.OSC_STRING);
127
+ table.addMany(PRINTABLES, ParserState.OSC_STRING, ParserAction.OSC_PUT, ParserState.OSC_STRING);
128
+ table.add(0x7f, ParserState.OSC_STRING, ParserAction.OSC_PUT, ParserState.OSC_STRING);
129
+ table.addMany([0x9c, 0x1b, 0x18, 0x1a, 0x07], ParserState.OSC_STRING, ParserAction.OSC_END, ParserState.GROUND);
130
+ table.addMany(r(0x1c, 0x20), ParserState.OSC_STRING, ParserAction.IGNORE, ParserState.OSC_STRING);
131
+ // sos/pm/apc does nothing
132
+ table.addMany([0x58, 0x5e, 0x5f], ParserState.ESCAPE, ParserAction.IGNORE, ParserState.SOS_PM_APC_STRING);
133
+ table.addMany(PRINTABLES, ParserState.SOS_PM_APC_STRING, ParserAction.IGNORE, ParserState.SOS_PM_APC_STRING);
134
+ table.addMany(EXECUTABLES, ParserState.SOS_PM_APC_STRING, ParserAction.IGNORE, ParserState.SOS_PM_APC_STRING);
135
+ table.add(0x9c, ParserState.SOS_PM_APC_STRING, ParserAction.IGNORE, ParserState.GROUND);
136
+ table.add(0x7f, ParserState.SOS_PM_APC_STRING, ParserAction.IGNORE, ParserState.SOS_PM_APC_STRING);
137
+ // csi entries
138
+ table.add(0x5b, ParserState.ESCAPE, ParserAction.CLEAR, ParserState.CSI_ENTRY);
139
+ table.addMany(r(0x40, 0x7f), ParserState.CSI_ENTRY, ParserAction.CSI_DISPATCH, ParserState.GROUND);
140
+ table.addMany(r(0x30, 0x3c), ParserState.CSI_ENTRY, ParserAction.PARAM, ParserState.CSI_PARAM);
141
+ table.addMany([0x3c, 0x3d, 0x3e, 0x3f], ParserState.CSI_ENTRY, ParserAction.COLLECT, ParserState.CSI_PARAM);
142
+ table.addMany(r(0x30, 0x3c), ParserState.CSI_PARAM, ParserAction.PARAM, ParserState.CSI_PARAM);
143
+ table.addMany(r(0x40, 0x7f), ParserState.CSI_PARAM, ParserAction.CSI_DISPATCH, ParserState.GROUND);
144
+ table.addMany([0x3c, 0x3d, 0x3e, 0x3f], ParserState.CSI_PARAM, ParserAction.IGNORE, ParserState.CSI_IGNORE);
145
+ table.addMany(r(0x20, 0x40), ParserState.CSI_IGNORE, ParserAction.IGNORE, ParserState.CSI_IGNORE);
146
+ table.add(0x7f, ParserState.CSI_IGNORE, ParserAction.IGNORE, ParserState.CSI_IGNORE);
147
+ table.addMany(r(0x40, 0x7f), ParserState.CSI_IGNORE, ParserAction.IGNORE, ParserState.GROUND);
148
+ table.addMany(r(0x20, 0x30), ParserState.CSI_ENTRY, ParserAction.COLLECT, ParserState.CSI_INTERMEDIATE);
149
+ table.addMany(r(0x20, 0x30), ParserState.CSI_INTERMEDIATE, ParserAction.COLLECT, ParserState.CSI_INTERMEDIATE);
150
+ table.addMany(r(0x30, 0x40), ParserState.CSI_INTERMEDIATE, ParserAction.IGNORE, ParserState.CSI_IGNORE);
151
+ table.addMany(r(0x40, 0x7f), ParserState.CSI_INTERMEDIATE, ParserAction.CSI_DISPATCH, ParserState.GROUND);
152
+ table.addMany(r(0x20, 0x30), ParserState.CSI_PARAM, ParserAction.COLLECT, ParserState.CSI_INTERMEDIATE);
153
+ // esc_intermediate
154
+ table.addMany(r(0x20, 0x30), ParserState.ESCAPE, ParserAction.COLLECT, ParserState.ESCAPE_INTERMEDIATE);
155
+ table.addMany(r(0x20, 0x30), ParserState.ESCAPE_INTERMEDIATE, ParserAction.COLLECT, ParserState.ESCAPE_INTERMEDIATE);
156
+ table.addMany(r(0x30, 0x7f), ParserState.ESCAPE_INTERMEDIATE, ParserAction.ESC_DISPATCH, ParserState.GROUND);
157
+ table.addMany(r(0x30, 0x50), ParserState.ESCAPE, ParserAction.ESC_DISPATCH, ParserState.GROUND);
158
+ table.addMany(r(0x51, 0x58), ParserState.ESCAPE, ParserAction.ESC_DISPATCH, ParserState.GROUND);
159
+ table.addMany([0x59, 0x5a, 0x5c], ParserState.ESCAPE, ParserAction.ESC_DISPATCH, ParserState.GROUND);
160
+ table.addMany(r(0x60, 0x7f), ParserState.ESCAPE, ParserAction.ESC_DISPATCH, ParserState.GROUND);
161
+ // dcs entry
162
+ table.add(0x50, ParserState.ESCAPE, ParserAction.CLEAR, ParserState.DCS_ENTRY);
163
+ table.addMany(EXECUTABLES, ParserState.DCS_ENTRY, ParserAction.IGNORE, ParserState.DCS_ENTRY);
164
+ table.add(0x7f, ParserState.DCS_ENTRY, ParserAction.IGNORE, ParserState.DCS_ENTRY);
165
+ table.addMany(r(0x1c, 0x20), ParserState.DCS_ENTRY, ParserAction.IGNORE, ParserState.DCS_ENTRY);
166
+ table.addMany(r(0x20, 0x30), ParserState.DCS_ENTRY, ParserAction.COLLECT, ParserState.DCS_INTERMEDIATE);
167
+ table.addMany(r(0x30, 0x3c), ParserState.DCS_ENTRY, ParserAction.PARAM, ParserState.DCS_PARAM);
168
+ table.addMany([0x3c, 0x3d, 0x3e, 0x3f], ParserState.DCS_ENTRY, ParserAction.COLLECT, ParserState.DCS_PARAM);
169
+ table.addMany(EXECUTABLES, ParserState.DCS_IGNORE, ParserAction.IGNORE, ParserState.DCS_IGNORE);
170
+ table.addMany(r(0x20, 0x80), ParserState.DCS_IGNORE, ParserAction.IGNORE, ParserState.DCS_IGNORE);
171
+ table.addMany(r(0x1c, 0x20), ParserState.DCS_IGNORE, ParserAction.IGNORE, ParserState.DCS_IGNORE);
172
+ table.addMany(EXECUTABLES, ParserState.DCS_PARAM, ParserAction.IGNORE, ParserState.DCS_PARAM);
173
+ table.add(0x7f, ParserState.DCS_PARAM, ParserAction.IGNORE, ParserState.DCS_PARAM);
174
+ table.addMany(r(0x1c, 0x20), ParserState.DCS_PARAM, ParserAction.IGNORE, ParserState.DCS_PARAM);
175
+ table.addMany(r(0x30, 0x3c), ParserState.DCS_PARAM, ParserAction.PARAM, ParserState.DCS_PARAM);
176
+ table.addMany([0x3c, 0x3d, 0x3e, 0x3f], ParserState.DCS_PARAM, ParserAction.IGNORE, ParserState.DCS_IGNORE);
177
+ table.addMany(r(0x20, 0x30), ParserState.DCS_PARAM, ParserAction.COLLECT, ParserState.DCS_INTERMEDIATE);
178
+ table.addMany(EXECUTABLES, ParserState.DCS_INTERMEDIATE, ParserAction.IGNORE, ParserState.DCS_INTERMEDIATE);
179
+ table.add(0x7f, ParserState.DCS_INTERMEDIATE, ParserAction.IGNORE, ParserState.DCS_INTERMEDIATE);
180
+ table.addMany(r(0x1c, 0x20), ParserState.DCS_INTERMEDIATE, ParserAction.IGNORE, ParserState.DCS_INTERMEDIATE);
181
+ table.addMany(r(0x20, 0x30), ParserState.DCS_INTERMEDIATE, ParserAction.COLLECT, ParserState.DCS_INTERMEDIATE);
182
+ table.addMany(r(0x30, 0x40), ParserState.DCS_INTERMEDIATE, ParserAction.IGNORE, ParserState.DCS_IGNORE);
183
+ table.addMany(r(0x40, 0x7f), ParserState.DCS_INTERMEDIATE, ParserAction.DCS_HOOK, ParserState.DCS_PASSTHROUGH);
184
+ table.addMany(r(0x40, 0x7f), ParserState.DCS_PARAM, ParserAction.DCS_HOOK, ParserState.DCS_PASSTHROUGH);
185
+ table.addMany(r(0x40, 0x7f), ParserState.DCS_ENTRY, ParserAction.DCS_HOOK, ParserState.DCS_PASSTHROUGH);
186
+ table.addMany(EXECUTABLES, ParserState.DCS_PASSTHROUGH, ParserAction.DCS_PUT, ParserState.DCS_PASSTHROUGH);
187
+ table.addMany(PRINTABLES, ParserState.DCS_PASSTHROUGH, ParserAction.DCS_PUT, ParserState.DCS_PASSTHROUGH);
188
+ table.add(0x7f, ParserState.DCS_PASSTHROUGH, ParserAction.IGNORE, ParserState.DCS_PASSTHROUGH);
189
+ table.addMany([0x1b, 0x9c, 0x18, 0x1a], ParserState.DCS_PASSTHROUGH, ParserAction.DCS_UNHOOK, ParserState.GROUND);
190
+ // special handling of unicode chars
191
+ table.add(NON_ASCII_PRINTABLE, ParserState.GROUND, ParserAction.PRINT, ParserState.GROUND);
192
+ table.add(NON_ASCII_PRINTABLE, ParserState.OSC_STRING, ParserAction.OSC_PUT, ParserState.OSC_STRING);
193
+ table.add(NON_ASCII_PRINTABLE, ParserState.CSI_IGNORE, ParserAction.IGNORE, ParserState.CSI_IGNORE);
194
+ table.add(NON_ASCII_PRINTABLE, ParserState.DCS_IGNORE, ParserAction.IGNORE, ParserState.DCS_IGNORE);
195
+ table.add(NON_ASCII_PRINTABLE, ParserState.DCS_PASSTHROUGH, ParserAction.DCS_PUT, ParserState.DCS_PASSTHROUGH);
196
+ return table;
197
+ })();
198
+
199
+
200
+ /**
201
+ * EscapeSequenceParser.
202
+ * This class implements the ANSI/DEC compatible parser described by
203
+ * Paul Williams (https://vt100.net/emu/dec_ansi_parser).
204
+ *
205
+ * To implement custom ANSI compliant escape sequences it is not needed to
206
+ * alter this parser, instead consider registering a custom handler.
207
+ * For non ANSI compliant sequences change the transition table with
208
+ * the optional `transitions` constructor argument and
209
+ * reimplement the `parse` method.
210
+ *
211
+ * This parser is currently hardcoded to operate in ZDM (Zero Default Mode)
212
+ * as suggested by the original parser, thus empty parameters are set to 0.
213
+ * This this is not in line with the latest ECMA-48 specification
214
+ * (ZDM was part of the early specs and got completely removed later on).
215
+ *
216
+ * Other than the original parser from vt100.net this parser supports
217
+ * sub parameters in digital parameters separated by colons. Empty sub parameters
218
+ * are set to -1 (no ZDM for sub parameters).
219
+ *
220
+ * About prefix and intermediate bytes:
221
+ * This parser follows the assumptions of the vt100.net parser with these restrictions:
222
+ * - only one prefix byte is allowed as first parameter byte, byte range 0x3c .. 0x3f
223
+ * - max. two intermediates are respected, byte range 0x20 .. 0x2f
224
+ * Note that this is not in line with ECMA-48 which does not limit either of those.
225
+ * Furthermore ECMA-48 allows the prefix byte range at any param byte position. Currently
226
+ * there are no known sequences that follow the broader definition of the specification.
227
+ *
228
+ * TODO: implement error recovery hook via error handler return values
229
+ */
230
+ export class EscapeSequenceParser extends Disposable implements IEscapeSequenceParser {
231
+ public initialState: number;
232
+ public currentState: number;
233
+ public precedingJoinState: number; // UnicodeJoinProperties
234
+
235
+ // buffers over several parse calls
236
+ protected _params: Params;
237
+ protected _collect: number;
238
+
239
+ // handler lookup containers
240
+ protected _printHandler: PrintHandlerType;
241
+ protected _executeHandlers: { [flag: number]: ExecuteHandlerType };
242
+ protected _csiHandlers: IHandlerCollection<CsiHandlerType>;
243
+ protected _escHandlers: IHandlerCollection<EscHandlerType>;
244
+ protected readonly _oscParser: IOscParser;
245
+ protected readonly _dcsParser: IDcsParser;
246
+ protected _errorHandler: (state: IParsingState) => IParsingState;
247
+
248
+ // fallback handlers
249
+ protected _printHandlerFb: PrintFallbackHandlerType;
250
+ protected _executeHandlerFb: ExecuteFallbackHandlerType;
251
+ protected _csiHandlerFb: CsiFallbackHandlerType;
252
+ protected _escHandlerFb: EscFallbackHandlerType;
253
+ protected _errorHandlerFb: (state: IParsingState) => IParsingState;
254
+
255
+ // parser stack save for async handler support
256
+ protected _parseStack: IParserStackState = {
257
+ state: ParserStackType.NONE,
258
+ handlers: [],
259
+ handlerPos: 0,
260
+ transition: 0,
261
+ chunkPos: 0
262
+ };
263
+
264
+ constructor(
265
+ protected readonly _transitions: TransitionTable = VT500_TRANSITION_TABLE
266
+ ) {
267
+ super();
268
+
269
+ this.initialState = ParserState.GROUND;
270
+ this.currentState = this.initialState;
271
+ this._params = new Params(); // defaults to 32 storable params/subparams
272
+ this._params.addParam(0); // ZDM
273
+ this._collect = 0;
274
+ this.precedingJoinState = 0;
275
+
276
+ // set default fallback handlers and handler lookup containers
277
+ this._printHandlerFb = (data, start, end): void => { };
278
+ this._executeHandlerFb = (code: number): void => { };
279
+ this._csiHandlerFb = (ident: number, params: IParams): void => { };
280
+ this._escHandlerFb = (ident: number): void => { };
281
+ this._errorHandlerFb = (state: IParsingState): IParsingState => state;
282
+ this._printHandler = this._printHandlerFb;
283
+ this._executeHandlers = Object.create(null);
284
+ this._csiHandlers = Object.create(null);
285
+ this._escHandlers = Object.create(null);
286
+ this.register(toDisposable(() => {
287
+ this._csiHandlers = Object.create(null);
288
+ this._executeHandlers = Object.create(null);
289
+ this._escHandlers = Object.create(null);
290
+ }));
291
+ this._oscParser = this.register(new OscParser());
292
+ this._dcsParser = this.register(new DcsParser());
293
+ this._errorHandler = this._errorHandlerFb;
294
+
295
+ // swallow 7bit ST (ESC+\)
296
+ this.registerEscHandler({ final: '\\' }, () => true);
297
+ }
298
+
299
+ protected _identifier(id: IFunctionIdentifier, finalRange: number[] = [0x40, 0x7e]): number {
300
+ let res = 0;
301
+ if (id.prefix) {
302
+ if (id.prefix.length > 1) {
303
+ throw new Error('only one byte as prefix supported');
304
+ }
305
+ res = id.prefix.charCodeAt(0);
306
+ if (res && 0x3c > res || res > 0x3f) {
307
+ throw new Error('prefix must be in range 0x3c .. 0x3f');
308
+ }
309
+ }
310
+ if (id.intermediates) {
311
+ if (id.intermediates.length > 2) {
312
+ throw new Error('only two bytes as intermediates are supported');
313
+ }
314
+ for (let i = 0; i < id.intermediates.length; ++i) {
315
+ const intermediate = id.intermediates.charCodeAt(i);
316
+ if (0x20 > intermediate || intermediate > 0x2f) {
317
+ throw new Error('intermediate must be in range 0x20 .. 0x2f');
318
+ }
319
+ res <<= 8;
320
+ res |= intermediate;
321
+ }
322
+ }
323
+ if (id.final.length !== 1) {
324
+ throw new Error('final must be a single byte');
325
+ }
326
+ const finalCode = id.final.charCodeAt(0);
327
+ if (finalRange[0] > finalCode || finalCode > finalRange[1]) {
328
+ throw new Error(`final must be in range ${finalRange[0]} .. ${finalRange[1]}`);
329
+ }
330
+ res <<= 8;
331
+ res |= finalCode;
332
+
333
+ return res;
334
+ }
335
+
336
+ public identToString(ident: number): string {
337
+ const res: string[] = [];
338
+ while (ident) {
339
+ res.push(String.fromCharCode(ident & 0xFF));
340
+ ident >>= 8;
341
+ }
342
+ return res.reverse().join('');
343
+ }
344
+
345
+ public setPrintHandler(handler: PrintHandlerType): void {
346
+ this._printHandler = handler;
347
+ }
348
+ public clearPrintHandler(): void {
349
+ this._printHandler = this._printHandlerFb;
350
+ }
351
+
352
+ public registerEscHandler(id: IFunctionIdentifier, handler: EscHandlerType): IDisposable {
353
+ const ident = this._identifier(id, [0x30, 0x7e]);
354
+ if (this._escHandlers[ident] === undefined) {
355
+ this._escHandlers[ident] = [];
356
+ }
357
+ const handlerList = this._escHandlers[ident];
358
+ handlerList.push(handler);
359
+ return {
360
+ dispose: () => {
361
+ const handlerIndex = handlerList.indexOf(handler);
362
+ if (handlerIndex !== -1) {
363
+ handlerList.splice(handlerIndex, 1);
364
+ }
365
+ }
366
+ };
367
+ }
368
+ public clearEscHandler(id: IFunctionIdentifier): void {
369
+ if (this._escHandlers[this._identifier(id, [0x30, 0x7e])]) delete this._escHandlers[this._identifier(id, [0x30, 0x7e])];
370
+ }
371
+ public setEscHandlerFallback(handler: EscFallbackHandlerType): void {
372
+ this._escHandlerFb = handler;
373
+ }
374
+
375
+ public setExecuteHandler(flag: string, handler: ExecuteHandlerType): void {
376
+ this._executeHandlers[flag.charCodeAt(0)] = handler;
377
+ }
378
+ public clearExecuteHandler(flag: string): void {
379
+ if (this._executeHandlers[flag.charCodeAt(0)]) delete this._executeHandlers[flag.charCodeAt(0)];
380
+ }
381
+ public setExecuteHandlerFallback(handler: ExecuteFallbackHandlerType): void {
382
+ this._executeHandlerFb = handler;
383
+ }
384
+
385
+ public registerCsiHandler(id: IFunctionIdentifier, handler: CsiHandlerType): IDisposable {
386
+ const ident = this._identifier(id);
387
+ if (this._csiHandlers[ident] === undefined) {
388
+ this._csiHandlers[ident] = [];
389
+ }
390
+ const handlerList = this._csiHandlers[ident];
391
+ handlerList.push(handler);
392
+ return {
393
+ dispose: () => {
394
+ const handlerIndex = handlerList.indexOf(handler);
395
+ if (handlerIndex !== -1) {
396
+ handlerList.splice(handlerIndex, 1);
397
+ }
398
+ }
399
+ };
400
+ }
401
+ public clearCsiHandler(id: IFunctionIdentifier): void {
402
+ if (this._csiHandlers[this._identifier(id)]) delete this._csiHandlers[this._identifier(id)];
403
+ }
404
+ public setCsiHandlerFallback(callback: (ident: number, params: IParams) => void): void {
405
+ this._csiHandlerFb = callback;
406
+ }
407
+
408
+ public registerDcsHandler(id: IFunctionIdentifier, handler: IDcsHandler): IDisposable {
409
+ return this._dcsParser.registerHandler(this._identifier(id), handler);
410
+ }
411
+ public clearDcsHandler(id: IFunctionIdentifier): void {
412
+ this._dcsParser.clearHandler(this._identifier(id));
413
+ }
414
+ public setDcsHandlerFallback(handler: DcsFallbackHandlerType): void {
415
+ this._dcsParser.setHandlerFallback(handler);
416
+ }
417
+
418
+ public registerOscHandler(ident: number, handler: IOscHandler): IDisposable {
419
+ return this._oscParser.registerHandler(ident, handler);
420
+ }
421
+ public clearOscHandler(ident: number): void {
422
+ this._oscParser.clearHandler(ident);
423
+ }
424
+ public setOscHandlerFallback(handler: OscFallbackHandlerType): void {
425
+ this._oscParser.setHandlerFallback(handler);
426
+ }
427
+
428
+ public setErrorHandler(callback: (state: IParsingState) => IParsingState): void {
429
+ this._errorHandler = callback;
430
+ }
431
+ public clearErrorHandler(): void {
432
+ this._errorHandler = this._errorHandlerFb;
433
+ }
434
+
435
+ /**
436
+ * Reset parser to initial values.
437
+ *
438
+ * This can also be used to lift the improper continuation error condition
439
+ * when dealing with async handlers. Use this only as a last resort to silence
440
+ * that error when the terminal has no pending data to be processed. Note that
441
+ * the interrupted async handler might continue its work in the future messing
442
+ * up the terminal state even further.
443
+ */
444
+ public reset(): void {
445
+ this.currentState = this.initialState;
446
+ this._oscParser.reset();
447
+ this._dcsParser.reset();
448
+ this._params.reset();
449
+ this._params.addParam(0); // ZDM
450
+ this._collect = 0;
451
+ this.precedingJoinState = 0;
452
+ // abort pending continuation from async handler
453
+ // Here the RESET type indicates, that the next parse call will
454
+ // ignore any saved stack, instead continues sync with next codepoint from GROUND
455
+ if (this._parseStack.state !== ParserStackType.NONE) {
456
+ this._parseStack.state = ParserStackType.RESET;
457
+ this._parseStack.handlers = []; // also release handlers ref
458
+ }
459
+ }
460
+
461
+ /**
462
+ * Async parse support.
463
+ */
464
+ protected _preserveStack(
465
+ state: ParserStackType,
466
+ handlers: ResumableHandlersType,
467
+ handlerPos: number,
468
+ transition: number,
469
+ chunkPos: number
470
+ ): void {
471
+ this._parseStack.state = state;
472
+ this._parseStack.handlers = handlers;
473
+ this._parseStack.handlerPos = handlerPos;
474
+ this._parseStack.transition = transition;
475
+ this._parseStack.chunkPos = chunkPos;
476
+ }
477
+
478
+ /**
479
+ * Parse UTF32 codepoints in `data` up to `length`.
480
+ *
481
+ * Note: For several actions with high data load the parsing is optimized
482
+ * by using local read ahead loops with hardcoded conditions to
483
+ * avoid costly table lookups. Make sure that any change of table values
484
+ * will be reflected in the loop conditions as well and vice versa.
485
+ * Affected states/actions:
486
+ * - GROUND:PRINT
487
+ * - CSI_PARAM:PARAM
488
+ * - DCS_PARAM:PARAM
489
+ * - OSC_STRING:OSC_PUT
490
+ * - DCS_PASSTHROUGH:DCS_PUT
491
+ *
492
+ * Note on asynchronous handler support:
493
+ * Any handler returning a promise will be treated as asynchronous.
494
+ * To keep the in-band blocking working for async handlers, `parse` pauses execution,
495
+ * creates a stack save and returns the promise to the caller.
496
+ * For proper continuation of the paused state it is important
497
+ * to await the promise resolving. On resolve the parse must be repeated
498
+ * with the same chunk of data and the resolved value in `promiseResult`
499
+ * until no promise is returned.
500
+ *
501
+ * Important: With only sync handlers defined, parsing is completely synchronous as well.
502
+ * As soon as an async handler is involved, synchronous parsing is not possible anymore.
503
+ *
504
+ * Boilerplate for proper parsing of multiple chunks with async handlers:
505
+ *
506
+ * ```typescript
507
+ * async function parseMultipleChunks(chunks: Uint32Array[]): Promise<void> {
508
+ * for (const chunk of chunks) {
509
+ * let result: void | Promise<boolean>;
510
+ * let prev: boolean | undefined;
511
+ * while (result = parser.parse(chunk, chunk.length, prev)) {
512
+ * prev = await result;
513
+ * }
514
+ * }
515
+ * // finished parsing all chunks...
516
+ * }
517
+ * ```
518
+ */
519
+ public parse(data: Uint32Array, length: number, promiseResult?: boolean): void | Promise<boolean> {
520
+ let code = 0;
521
+ let transition = 0;
522
+ let start = 0;
523
+ let handlerResult: void | boolean | Promise<boolean>;
524
+
525
+ // resume from async handler
526
+ if (this._parseStack.state) {
527
+ // allow sync parser reset even in continuation mode
528
+ // Note: can be used to recover parser from improper continuation error below
529
+ if (this._parseStack.state === ParserStackType.RESET) {
530
+ this._parseStack.state = ParserStackType.NONE;
531
+ start = this._parseStack.chunkPos + 1; // continue with next codepoint in GROUND
532
+ } else {
533
+ if (promiseResult === undefined || this._parseStack.state === ParserStackType.FAIL) {
534
+ /**
535
+ * Reject further parsing on improper continuation after pausing. This is a really bad
536
+ * condition with screwed up execution order and prolly messed up terminal state,
537
+ * therefore we exit hard with an exception and reject any further parsing.
538
+ *
539
+ * Note: With `Terminal.write` usage this exception should never occur, as the top level
540
+ * calls are guaranteed to handle async conditions properly. If you ever encounter this
541
+ * exception in your terminal integration it indicates, that you injected data chunks to
542
+ * `InputHandler.parse` or `EscapeSequenceParser.parse` synchronously without waiting for
543
+ * continuation of a running async handler.
544
+ *
545
+ * It is possible to get rid of this error by calling `reset`. But dont rely on that, as
546
+ * the pending async handler still might mess up the terminal later. Instead fix the
547
+ * faulty async handling, so this error will not be thrown anymore.
548
+ */
549
+ this._parseStack.state = ParserStackType.FAIL;
550
+ throw new Error('improper continuation due to previous async handler, giving up parsing');
551
+ }
552
+
553
+ // we have to resume the old handler loop if:
554
+ // - return value of the promise was `false`
555
+ // - handlers are not exhausted yet
556
+ const handlers = this._parseStack.handlers;
557
+ let handlerPos = this._parseStack.handlerPos - 1;
558
+ switch (this._parseStack.state) {
559
+ case ParserStackType.CSI:
560
+ if (promiseResult === false && handlerPos > -1) {
561
+ for (; handlerPos >= 0; handlerPos--) {
562
+ handlerResult = (handlers as CsiHandlerType[])[handlerPos](this._params);
563
+ if (handlerResult === true) {
564
+ break;
565
+ } else if (handlerResult instanceof Promise) {
566
+ this._parseStack.handlerPos = handlerPos;
567
+ return handlerResult;
568
+ }
569
+ }
570
+ }
571
+ this._parseStack.handlers = [];
572
+ break;
573
+ case ParserStackType.ESC:
574
+ if (promiseResult === false && handlerPos > -1) {
575
+ for (; handlerPos >= 0; handlerPos--) {
576
+ handlerResult = (handlers as EscHandlerType[])[handlerPos]();
577
+ if (handlerResult === true) {
578
+ break;
579
+ } else if (handlerResult instanceof Promise) {
580
+ this._parseStack.handlerPos = handlerPos;
581
+ return handlerResult;
582
+ }
583
+ }
584
+ }
585
+ this._parseStack.handlers = [];
586
+ break;
587
+ case ParserStackType.DCS:
588
+ code = data[this._parseStack.chunkPos];
589
+ handlerResult = this._dcsParser.unhook(code !== 0x18 && code !== 0x1a, promiseResult);
590
+ if (handlerResult) {
591
+ return handlerResult;
592
+ }
593
+ if (code === 0x1b) this._parseStack.transition |= ParserState.ESCAPE;
594
+ this._params.reset();
595
+ this._params.addParam(0); // ZDM
596
+ this._collect = 0;
597
+ break;
598
+ case ParserStackType.OSC:
599
+ code = data[this._parseStack.chunkPos];
600
+ handlerResult = this._oscParser.end(code !== 0x18 && code !== 0x1a, promiseResult);
601
+ if (handlerResult) {
602
+ return handlerResult;
603
+ }
604
+ if (code === 0x1b) this._parseStack.transition |= ParserState.ESCAPE;
605
+ this._params.reset();
606
+ this._params.addParam(0); // ZDM
607
+ this._collect = 0;
608
+ break;
609
+ }
610
+ // cleanup before continuing with the main sync loop
611
+ this._parseStack.state = ParserStackType.NONE;
612
+ start = this._parseStack.chunkPos + 1;
613
+ this.precedingJoinState = 0;
614
+ this.currentState = this._parseStack.transition & TableAccess.TRANSITION_STATE_MASK;
615
+ }
616
+ }
617
+
618
+ // continue with main sync loop
619
+
620
+ // process input string
621
+ for (let i = start; i < length; ++i) {
622
+ code = data[i];
623
+
624
+ // normal transition & action lookup
625
+ transition = this._transitions.table[this.currentState << TableAccess.INDEX_STATE_SHIFT | (code < 0xa0 ? code : NON_ASCII_PRINTABLE)];
626
+ switch (transition >> TableAccess.TRANSITION_ACTION_SHIFT) {
627
+ case ParserAction.PRINT:
628
+ // read ahead with loop unrolling
629
+ // Note: 0x20 (SP) is included, 0x7F (DEL) is excluded
630
+ for (let j = i + 1; ; ++j) {
631
+ if (j >= length || (code = data[j]) < 0x20 || (code > 0x7e && code < NON_ASCII_PRINTABLE)) {
632
+ this._printHandler(data, i, j);
633
+ i = j - 1;
634
+ break;
635
+ }
636
+ if (++j >= length || (code = data[j]) < 0x20 || (code > 0x7e && code < NON_ASCII_PRINTABLE)) {
637
+ this._printHandler(data, i, j);
638
+ i = j - 1;
639
+ break;
640
+ }
641
+ if (++j >= length || (code = data[j]) < 0x20 || (code > 0x7e && code < NON_ASCII_PRINTABLE)) {
642
+ this._printHandler(data, i, j);
643
+ i = j - 1;
644
+ break;
645
+ }
646
+ if (++j >= length || (code = data[j]) < 0x20 || (code > 0x7e && code < NON_ASCII_PRINTABLE)) {
647
+ this._printHandler(data, i, j);
648
+ i = j - 1;
649
+ break;
650
+ }
651
+ }
652
+ break;
653
+ case ParserAction.EXECUTE:
654
+ if (this._executeHandlers[code]) this._executeHandlers[code]();
655
+ else this._executeHandlerFb(code);
656
+ this.precedingJoinState = 0;
657
+ break;
658
+ case ParserAction.IGNORE:
659
+ break;
660
+ case ParserAction.ERROR:
661
+ const inject: IParsingState = this._errorHandler(
662
+ {
663
+ position: i,
664
+ code,
665
+ currentState: this.currentState,
666
+ collect: this._collect,
667
+ params: this._params,
668
+ abort: false
669
+ });
670
+ if (inject.abort) return;
671
+ // inject values: currently not implemented
672
+ break;
673
+ case ParserAction.CSI_DISPATCH:
674
+ // Trigger CSI Handler
675
+ const handlers = this._csiHandlers[this._collect << 8 | code];
676
+ let j = handlers ? handlers.length - 1 : -1;
677
+ for (; j >= 0; j--) {
678
+ // true means success and to stop bubbling
679
+ // a promise indicates an async handler that needs to finish before progressing
680
+ handlerResult = handlers[j](this._params);
681
+ if (handlerResult === true) {
682
+ break;
683
+ } else if (handlerResult instanceof Promise) {
684
+ this._preserveStack(ParserStackType.CSI, handlers, j, transition, i);
685
+ return handlerResult;
686
+ }
687
+ }
688
+ if (j < 0) {
689
+ this._csiHandlerFb(this._collect << 8 | code, this._params);
690
+ }
691
+ this.precedingJoinState = 0;
692
+ break;
693
+ case ParserAction.PARAM:
694
+ // inner loop: digits (0x30 - 0x39) and ; (0x3b) and : (0x3a)
695
+ do {
696
+ switch (code) {
697
+ case 0x3b:
698
+ this._params.addParam(0); // ZDM
699
+ break;
700
+ case 0x3a:
701
+ this._params.addSubParam(-1);
702
+ break;
703
+ default: // 0x30 - 0x39
704
+ this._params.addDigit(code - 48);
705
+ }
706
+ } while (++i < length && (code = data[i]) > 0x2f && code < 0x3c);
707
+ i--;
708
+ break;
709
+ case ParserAction.COLLECT:
710
+ this._collect <<= 8;
711
+ this._collect |= code;
712
+ break;
713
+ case ParserAction.ESC_DISPATCH:
714
+ const handlersEsc = this._escHandlers[this._collect << 8 | code];
715
+ let jj = handlersEsc ? handlersEsc.length - 1 : -1;
716
+ for (; jj >= 0; jj--) {
717
+ // true means success and to stop bubbling
718
+ // a promise indicates an async handler that needs to finish before progressing
719
+ handlerResult = handlersEsc[jj]();
720
+ if (handlerResult === true) {
721
+ break;
722
+ } else if (handlerResult instanceof Promise) {
723
+ this._preserveStack(ParserStackType.ESC, handlersEsc, jj, transition, i);
724
+ return handlerResult;
725
+ }
726
+ }
727
+ if (jj < 0) {
728
+ this._escHandlerFb(this._collect << 8 | code);
729
+ }
730
+ this.precedingJoinState = 0;
731
+ break;
732
+ case ParserAction.CLEAR:
733
+ this._params.reset();
734
+ this._params.addParam(0); // ZDM
735
+ this._collect = 0;
736
+ break;
737
+ case ParserAction.DCS_HOOK:
738
+ this._dcsParser.hook(this._collect << 8 | code, this._params);
739
+ break;
740
+ case ParserAction.DCS_PUT:
741
+ // inner loop - exit DCS_PUT: 0x18, 0x1a, 0x1b, 0x7f, 0x80 - 0x9f
742
+ // unhook triggered by: 0x1b, 0x9c (success) and 0x18, 0x1a (abort)
743
+ for (let j = i + 1; ; ++j) {
744
+ if (j >= length || (code = data[j]) === 0x18 || code === 0x1a || code === 0x1b || (code > 0x7f && code < NON_ASCII_PRINTABLE)) {
745
+ this._dcsParser.put(data, i, j);
746
+ i = j - 1;
747
+ break;
748
+ }
749
+ }
750
+ break;
751
+ case ParserAction.DCS_UNHOOK:
752
+ handlerResult = this._dcsParser.unhook(code !== 0x18 && code !== 0x1a);
753
+ if (handlerResult) {
754
+ this._preserveStack(ParserStackType.DCS, [], 0, transition, i);
755
+ return handlerResult;
756
+ }
757
+ if (code === 0x1b) transition |= ParserState.ESCAPE;
758
+ this._params.reset();
759
+ this._params.addParam(0); // ZDM
760
+ this._collect = 0;
761
+ this.precedingJoinState = 0;
762
+ break;
763
+ case ParserAction.OSC_START:
764
+ this._oscParser.start();
765
+ break;
766
+ case ParserAction.OSC_PUT:
767
+ // inner loop: 0x20 (SP) included, 0x7F (DEL) included
768
+ for (let j = i + 1; ; j++) {
769
+ if (j >= length || (code = data[j]) < 0x20 || (code > 0x7f && code < NON_ASCII_PRINTABLE)) {
770
+ this._oscParser.put(data, i, j);
771
+ i = j - 1;
772
+ break;
773
+ }
774
+ }
775
+ break;
776
+ case ParserAction.OSC_END:
777
+ handlerResult = this._oscParser.end(code !== 0x18 && code !== 0x1a);
778
+ if (handlerResult) {
779
+ this._preserveStack(ParserStackType.OSC, [], 0, transition, i);
780
+ return handlerResult;
781
+ }
782
+ if (code === 0x1b) transition |= ParserState.ESCAPE;
783
+ this._params.reset();
784
+ this._params.addParam(0); // ZDM
785
+ this._collect = 0;
786
+ this.precedingJoinState = 0;
787
+ break;
788
+ }
789
+ this.currentState = transition & TableAccess.TRANSITION_STATE_MASK;
790
+ }
791
+ }
792
+ }