tl; dr Я создал оболочку React для рендеринга массива сообщений журнала в терминал, но изменение размера приводит к странным выводам (см. Скриншот).(В NPM есть React-Wrapper, но он не работает для моего варианта использования - мерцание экрана вызывает)
Я работаю над функцией для Guppy, где добавляю Xterm.JS для вывода терминала.PR можно найти здесь .
Я добавил xterm из-за сканирования / анализа гиперссылок, и это работает.
Но я застрял с получением изменения размераРабота.Если я запускаю devServer в приложении и жду некоторого текста, он будет отображаться с правильной шириной буквы.Если я уменьшу размер, я получу вывод с неправильной шириной буквы.Как на следующем скриншоте: ![Messed output](https://user-images.githubusercontent.com/3046542/51803797-52e9d280-2259-11e9-9d27-5dba3ad4b505.png)
Он всегда выглядит правильно в неизмененном состоянии, но после изменения размера он получит неправильное отображение - поэтому это будет происходить для увеличения и уменьшения ширины экрана.
Вывод должен выглядеть примерно так, как показано на следующем снимке экрана (возможно, с некоторыми обернутыми строками): ![Correct output](https://user-images.githubusercontent.com/3046542/51794649-b3d0c680-21d7-11e9-813c-f154bd593a39.png)
Я думаю, это вызвано Fit addon или тем, как я работаюизменение размера с помощью наблюдателя изменения размера, но я не уверен.
Стиль span для буквы xterm получает ширину NaNpx
, как на следующем снимке экрана:
Это вызвано медиазапросом I 'я использую?Я еще этого не видел, может быть, мне нужно временно отключить все медиазапросы, чтобы увидеть, вызывает ли это поведение.
То, что я пробовал до сих пор:
- Обернуто
this.xterm.fit()
в setTimeout(func, 0)
, но без эффекта - Изменены некоторые стили I 'Я использую, но я не нашел причину.
Код
Код, который я использую, может быть найден в GitHub Branch Feature-Terminal-Links но здесь я хотел бы извлечь части, которые я добавил, чтобы заставить Xterm работать с React:
- Я создал стилевой компонент
XtermContainer
в качестве элемента div, чтобы я мог добавить стили Xterm исобственный стиль.Следующий код находится внутри render
и будет нашим контейнером xterm.js (innerRef
будет использоваться позже в ComponentDidMount
для инициализации Xterm с этим контейнером):
<XtermContainer
width={width}
height={height}
innerRef={node => (this.node = node)}
/>
Init xterm в
componentDidMount
с контейнером выше:
componentDidMount() {
Terminal.applyAddon(webLinks);
Terminal.applyAddon(localLinks);
Terminal.applyAddon(fit);
this.xterm = new Terminal({
convertEol: true,
fontFamily: `'Fira Mono', monospace`,
fontSize: 15,
rendererType: 'dom', // default is canvas
});
this.xterm.setOption('theme', {
background: COLORS.blue[900],
foreground: COLORS.white,
});
this.xterm.open(this.node);
this.xterm.fit();
/* ... some addon setup code here (not relevant for the problem) ... */
}
Добавлен
Reaction-Resize-Observer внутри оболочки, которая также содержит контейнер терминала, так что я могу вызвать
this.xterm.fit()
, если размер изменяется (в репо есть оболочка
setTimeout
длятестирование).
<ResizeObserver onResize={() => this.xterm && this.xterm.fit()} />
Использование
componentDidUpdate(prevProps, prevState)
для обновления терминала и прокрутки терминала до дна, если компонент получает новые журналы:
componentDidUpdate(prevProps, prevState) {
if (prevProps.task.logs !== this.state.logs) {
if (this.state.logs.length === 0) {
this.xterm.clear();
}
for (const log of this.state.logs) {
/*
We need to track what we have added to xterm - feels hacky but it's working.
`this.xterm.clear()` and re-render everything caused screen flicker that's why I decided to not use it.
Todo: Check if there is a react-xterm wrapper that is not using xterm.clear or
create a wrapper component that can render the logs array (with-out flicker).
*/
if (!this.renderedLogs[log.id]) {
this.writeln(log.text);
this.xterm.scrollToBottom();
this.renderedLogs[log.id] = true;
}
}
}
}
Идеи Мне нужно найти причину:
Проверьте код ResizeObserver. (см. Обновление ниже) - Попытайтесь выяснить, почему xterm css получает ширину NaN.Xterm.js использует ширину стиля контейнера?Если да, может быть, это неправильно установлено.
Обновление
ОК, наблюдатель изменения размера, вероятно, не нужен, так как я получаю то же поведение после комментирования<ResizeObserver/>
в рендере.Так что я думаю, что это вызвано xterm.js или CSS в Гуппи.