mirror of
https://github.com/quine-global/hyper.git
synced 2026-01-12 20:18:41 -09:00
Fix xterm.js resource leaks in split pane (#3409)
This commit is contained in:
parent
ee8e95b8f1
commit
3881703e01
2 changed files with 25 additions and 19 deletions
|
|
@ -76,13 +76,11 @@ export default class Term extends React.PureComponent {
|
|||
constructor(props) {
|
||||
super(props);
|
||||
props.ref_(props.uid, this);
|
||||
this.termRef = null;
|
||||
this.termWrapperRef = null;
|
||||
this.termRect = null;
|
||||
this.onOpen = this.onOpen.bind(this);
|
||||
this.onWindowResize = this.onWindowResize.bind(this);
|
||||
this.onWindowPaste = this.onWindowPaste.bind(this);
|
||||
this.onTermRef = this.onTermRef.bind(this);
|
||||
this.onTermWrapperRef = this.onTermWrapperRef.bind(this);
|
||||
this.onMouseUp = this.onMouseUp.bind(this);
|
||||
this.termOptions = {};
|
||||
|
|
@ -94,15 +92,21 @@ export default class Term extends React.PureComponent {
|
|||
|
||||
this.termOptions = getTermOptions(props);
|
||||
this.term = props.term || new Terminal(this.termOptions);
|
||||
this.term.attachCustomKeyEventHandler(this.keyboardHandler);
|
||||
this.term.open(this.termRef);
|
||||
this.term.webLinksInit();
|
||||
this.term.winptyCompatInit();
|
||||
|
||||
if (props.term) {
|
||||
//We need to set options again after reattaching an existing term
|
||||
Object.keys(this.termOptions).forEach(option => this.term.setOption(option, this.termOptions[option]));
|
||||
// The parent element for the terminal is attached and removed manually so
|
||||
// that we can preserve it across mounts and unmounts of the component
|
||||
let parent = props.term ? props.term._core._parent : document.createElement('div');
|
||||
parent.className = 'term_fit term_term';
|
||||
|
||||
this.termWrapperRef.appendChild(parent);
|
||||
|
||||
if (!props.term) {
|
||||
this.term.attachCustomKeyEventHandler(this.keyboardHandler);
|
||||
this.term.open(parent);
|
||||
this.term.webLinksInit();
|
||||
this.term.winptyCompatInit();
|
||||
}
|
||||
|
||||
if (this.props.isTermActive) {
|
||||
this.term.focus();
|
||||
}
|
||||
|
|
@ -302,12 +306,9 @@ export default class Term extends React.PureComponent {
|
|||
this.termWrapperRef = component;
|
||||
}
|
||||
|
||||
onTermRef(component) {
|
||||
this.termRef = component;
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
terms[this.props.uid] = null;
|
||||
this.termWrapperRef.removeChild(this.term._core._parent);
|
||||
this.props.ref_(this.props.uid, null);
|
||||
|
||||
// to clean up the terminal, we remove the listeners
|
||||
|
|
@ -334,12 +335,10 @@ export default class Term extends React.PureComponent {
|
|||
onMouseUp={this.onMouseUp}
|
||||
>
|
||||
{this.props.customChildrenBefore}
|
||||
<div ref={this.onTermWrapperRef} className="term_fit term_wrapper">
|
||||
<div ref={this.onTermRef} className="term_fit term_term" />
|
||||
</div>
|
||||
<div ref={this.onTermWrapperRef} className="term_fit term_wrapper" />
|
||||
{this.props.customChildren}
|
||||
|
||||
<style jsx>{`
|
||||
<style jsx global>{`
|
||||
.term_fit {
|
||||
display: block;
|
||||
width: 100%;
|
||||
|
|
|
|||
|
|
@ -42,8 +42,6 @@ export default class Terms extends React.Component {
|
|||
onRef(uid, term) {
|
||||
if (term) {
|
||||
this.terms[uid] = term;
|
||||
} else if (!this.props.sessions[uid]) {
|
||||
delete this.terms[uid];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -71,6 +69,15 @@ export default class Terms extends React.Component {
|
|||
});
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
for (let uid in prevProps.sessions) {
|
||||
if (!this.props.sessions[uid]) {
|
||||
this.terms[uid].term.dispose();
|
||||
delete this.terms[uid];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this.props.ref_(null);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue