@xterm/xterm 5.4.0 → 5.5.0-beta.10

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@xterm/xterm",
3
3
  "description": "Full xterm terminal, in your browser",
4
- "version": "5.4.0",
4
+ "version": "5.5.0-beta.10",
5
5
  "main": "lib/xterm.js",
6
6
  "style": "css/xterm.css",
7
7
  "types": "typings/xterm.d.ts",
@@ -183,14 +183,23 @@ export class DomRenderer extends Disposable implements IRenderer {
183
183
  ` font-style: italic;` +
184
184
  `}`;
185
185
  // Blink animation
186
+ const blinkAnimationUnderlineId = `blink_underline_${this._terminalClass}`;
187
+ const blinkAnimationBarId = `blink_bar_${this._terminalClass}`;
188
+ const blinkAnimationBlockId = `blink_block_${this._terminalClass}`;
186
189
  styles +=
187
- `@keyframes blink_box_shadow` + `_` + this._terminalClass + ` {` +
190
+ `@keyframes ${blinkAnimationUnderlineId} {` +
188
191
  ` 50% {` +
189
192
  ` border-bottom-style: hidden;` +
190
193
  ` }` +
191
194
  `}`;
192
195
  styles +=
193
- `@keyframes blink_block` + `_` + this._terminalClass + ` {` +
196
+ `@keyframes ${blinkAnimationBarId} {` +
197
+ ` 50% {` +
198
+ ` box-shadow: none;` +
199
+ ` }` +
200
+ `}`;
201
+ styles +=
202
+ `@keyframes ${blinkAnimationBlockId} {` +
194
203
  ` 0% {` +
195
204
  ` background-color: ${colors.cursor.css};` +
196
205
  ` color: ${colors.cursorAccent.css};` +
@@ -202,13 +211,23 @@ export class DomRenderer extends Disposable implements IRenderer {
202
211
  `}`;
203
212
  // Cursor
204
213
  styles +=
205
- `${this._terminalSelector} .${ROW_CONTAINER_CLASS}.${FOCUS_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_BLINK_CLASS}:not(.${RowCss.CURSOR_STYLE_BLOCK_CLASS}) {` +
206
- ` animation: blink_box_shadow` + `_` + this._terminalClass + ` 1s step-end infinite;` +
214
+ `${this._terminalSelector} .${ROW_CONTAINER_CLASS}.${FOCUS_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_BLINK_CLASS}.${RowCss.CURSOR_STYLE_UNDERLINE_CLASS} {` +
215
+ ` animation: ${blinkAnimationUnderlineId} 1s step-end infinite;` +
216
+ `}` +
217
+ `${this._terminalSelector} .${ROW_CONTAINER_CLASS}.${FOCUS_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_BLINK_CLASS}.${RowCss.CURSOR_STYLE_BAR_CLASS} {` +
218
+ ` animation: ${blinkAnimationBarId} 1s step-end infinite;` +
207
219
  `}` +
208
220
  `${this._terminalSelector} .${ROW_CONTAINER_CLASS}.${FOCUS_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_BLINK_CLASS}.${RowCss.CURSOR_STYLE_BLOCK_CLASS} {` +
209
- ` animation: blink_block` + `_` + this._terminalClass + ` 1s step-end infinite;` +
221
+ ` animation: ${blinkAnimationBlockId} 1s step-end infinite;` +
210
222
  `}` +
223
+ // !important helps fix an issue where the cursor will not render on top of the selection,
224
+ // however it's very hard to fix this issue and retain the blink animation without the use of
225
+ // !important. So this edge case fails when cursor blink is on.
211
226
  `${this._terminalSelector} .${ROW_CONTAINER_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_STYLE_BLOCK_CLASS} {` +
227
+ ` background-color: ${colors.cursor.css};` +
228
+ ` color: ${colors.cursorAccent.css};` +
229
+ `}` +
230
+ `${this._terminalSelector} .${ROW_CONTAINER_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_STYLE_BLOCK_CLASS}:not(.${RowCss.CURSOR_BLINK_CLASS}) {` +
212
231
  ` background-color: ${colors.cursor.css} !important;` +
213
232
  ` color: ${colors.cursorAccent.css} !important;` +
214
233
  `}` +
@@ -23,10 +23,41 @@ export function isRestrictedPowerlineGlyph(codepoint: number): boolean {
23
23
  return 0xE0B0 <= codepoint && codepoint <= 0xE0B7;
24
24
  }
25
25
 
26
+ function isNerdFontGlyph(codepoint: number): boolean {
27
+ return 0xE000 <= codepoint && codepoint <= 0xF8FF;
28
+ }
29
+
26
30
  function isBoxOrBlockGlyph(codepoint: number): boolean {
27
31
  return 0x2500 <= codepoint && codepoint <= 0x259F;
28
32
  }
29
33
 
34
+ export function isEmoji(codepoint: number): boolean {
35
+ return (
36
+ codepoint >= 0x1F600 && codepoint <= 0x1F64F || // Emoticons
37
+ codepoint >= 0x1F300 && codepoint <= 0x1F5FF || // Misc Symbols and Pictographs
38
+ codepoint >= 0x1F680 && codepoint <= 0x1F6FF || // Transport and Map
39
+ codepoint >= 0x2600 && codepoint <= 0x26FF || // Misc symbols
40
+ codepoint >= 0x2700 && codepoint <= 0x27BF || // Dingbats
41
+ codepoint >= 0xFE00 && codepoint <= 0xFE0F || // Variation Selectors
42
+ codepoint >= 0x1F900 && codepoint <= 0x1F9FF || // Supplemental Symbols and Pictographs
43
+ codepoint >= 0x1F1E6 && codepoint <= 0x1F1FF
44
+ );
45
+ }
46
+
47
+ export function allowRescaling(codepoint: number | undefined, width: number, glyphSizeX: number, deviceCellWidth: number): boolean {
48
+ return (
49
+ // Is single cell width
50
+ width === 1 &&
51
+ // Glyph exceeds cell bounds, add 25% to avoid hurting readability by rescaling glyphs that
52
+ // barely overlap
53
+ glyphSizeX > deviceCellWidth * 1.25 &&
54
+ // Never rescale emoji
55
+ codepoint !== undefined && !isEmoji(codepoint) &&
56
+ // Never rescale powerline or nerd fonts
57
+ !isPowerlineGlyph(codepoint) && !isNerdFontGlyph(codepoint)
58
+ );
59
+ }
60
+
30
61
  export function treatGlyphAsBackgroundColor(codepoint: number): boolean {
31
62
  return isPowerlineGlyph(codepoint) || isBoxOrBlockGlyph(codepoint);
32
63
  }
@@ -87,7 +87,8 @@ export class RenderService extends Disposable implements IRenderService {
87
87
  'fontSize',
88
88
  'fontWeight',
89
89
  'fontWeightBold',
90
- 'minimumContrastRatio'
90
+ 'minimumContrastRatio',
91
+ 'rescaleOverlappingGlyphs'
91
92
  ], () => {
92
93
  this.clear();
93
94
  this.handleResize(bufferService.cols, bufferService.rows);
@@ -3,7 +3,6 @@
3
3
  * @license MIT
4
4
  */
5
5
 
6
- import { isNode } from 'common/Platform';
7
6
  import { IColor, IColorRGB } from 'common/Types';
8
7
 
9
8
  let $r = 0;
@@ -117,9 +116,10 @@ export namespace color {
117
116
  * '#rrggbbaa').
118
117
  */
119
118
  export namespace css {
119
+ // Attempt to set get the shared canvas context
120
120
  let $ctx: CanvasRenderingContext2D | undefined;
121
121
  let $litmusColor: CanvasGradient | undefined;
122
- if (!isNode) {
122
+ try {
123
123
  // This is guaranteed to run in the first window, so document should be correct
124
124
  const canvas = document.createElement('canvas');
125
125
  canvas.width = 1;
@@ -133,6 +133,9 @@ export namespace css {
133
133
  $litmusColor = $ctx.createLinearGradient(0, 0, 1, 1);
134
134
  }
135
135
  }
136
+ catch {
137
+ // noop
138
+ }
136
139
 
137
140
  /**
138
141
  * Converts a css string to an IColor, this should handle all valid CSS color strings and will
@@ -14,7 +14,7 @@ interface INavigator {
14
14
  declare const navigator: INavigator;
15
15
  declare const process: unknown;
16
16
 
17
- export const isNode = (typeof process !== 'undefined') ? true : false;
17
+ export const isNode = (typeof process !== 'undefined' && 'title' in (process as any)) ? true : false;
18
18
  const userAgent = (isNode) ? 'node' : navigator.userAgent;
19
19
  const platform = (isNode) ? 'node' : navigator.platform;
20
20
 
@@ -44,6 +44,7 @@ export const DEFAULT_OPTIONS: Readonly<Required<ITerminalOptions>> = {
44
44
  allowTransparency: false,
45
45
  tabStopWidth: 8,
46
46
  theme: {},
47
+ rescaleOverlappingGlyphs: false,
47
48
  rightClickSelectsWord: isMac,
48
49
  windowOptions: {},
49
50
  windowsMode: false,
@@ -234,6 +234,7 @@ export interface ITerminalOptions {
234
234
  macOptionIsMeta?: boolean;
235
235
  macOptionClickForcesSelection?: boolean;
236
236
  minimumContrastRatio?: number;
237
+ rescaleOverlappingGlyphs?: boolean;
237
238
  rightClickSelectsWord?: boolean;
238
239
  rows?: number;
239
240
  screenReaderMode?: boolean;
@@ -209,6 +209,23 @@ declare module '@xterm/xterm' {
209
209
  */
210
210
  minimumContrastRatio?: number;
211
211
 
212
+ /**
213
+ * Whether to rescale glyphs horizontally that are a single cell wide but
214
+ * have glyphs that would overlap following cell(s). This typically happens
215
+ * for ambiguous width characters (eg. the roman numeral characters U+2160+)
216
+ * which aren't featured in monospace fonts. This is an important feature
217
+ * for achieving GB18030 compliance.
218
+ *
219
+ * The following glyphs will never be rescaled:
220
+ *
221
+ * - Emoji glyphs
222
+ * - Powerline glyphs
223
+ * - Nerd font glyphs
224
+ *
225
+ * Note that this doesn't work with the DOM renderer. The default is false.
226
+ */
227
+ rescaleOverlappingGlyphs?: boolean;
228
+
212
229
  /**
213
230
  * Whether to select the word under the cursor on right click, this is
214
231
  * standard behavior in a lot of macOS applications.
@@ -225,7 +242,7 @@ declare module '@xterm/xterm' {
225
242
  /**
226
243
  * The amount of scrollback in the terminal. Scrollback is the amount of
227
244
  * rows that are retained when lines are scrolled beyond the initial
228
- * viewport.
245
+ * viewport. Defaults to 1000.
229
246
  */
230
247
  scrollback?: number;
231
248