Better code (callback -> async) and protection aganist early tab close (Close before terminal is loaded)

This commit is contained in:
NI
2019-12-15 14:55:13 +08:00
parent 8bdfbeb7b9
commit f190cefe33

View File

@@ -188,6 +188,10 @@ class Term {
oldCols = 0; oldCols = 0;
this.term.onResize(dim => { this.term.onResize(dim => {
if (this.closed) {
return;
}
if (dim.cols === oldCols && dim.rows === oldRows) { if (dim.cols === oldCols && dim.rows === oldRows) {
return; return;
} }
@@ -220,16 +224,28 @@ class Term {
} }
setFont(value) { setFont(value) {
if (this.closed) {
return;
}
this.term.setOption("fontFamily", value); this.term.setOption("fontFamily", value);
} }
init(root, callbacks) { init(root, callbacks) {
if (this.closed) {
return;
}
this.term.open(root); this.term.open(root);
this.term.textarea.addEventListener("focus", callbacks.focus); this.term.textarea.addEventListener("focus", callbacks.focus);
this.term.textarea.addEventListener("blur", callbacks.blur); this.term.textarea.addEventListener("blur", callbacks.blur);
this.term.textarea.addEventListener("keyup", async ev => { this.term.textarea.addEventListener("keyup", async ev => {
if (this.closed) {
return;
}
if (ev.ctrlKey && ev.shiftKey) { if (ev.ctrlKey && ev.shiftKey) {
switch (ev.keyCode) { switch (ev.keyCode) {
case 86: case 86:
@@ -258,6 +274,10 @@ class Term {
}); });
this.term.element.addEventListener("click", () => { this.term.element.addEventListener("click", () => {
if (this.closed) {
return;
}
this.term.textarea.blur(); this.term.textarea.blur();
this.term.textarea.click(); this.term.textarea.click();
this.term.textarea.focus(); this.term.textarea.focus();
@@ -267,6 +287,10 @@ class Term {
} }
dispatch(event) { dispatch(event) {
if (this.closed) {
return;
}
try { try {
this.term.textarea.dispatchEvent(event); this.term.textarea.dispatchEvent(event);
} catch (e) { } catch (e) {
@@ -275,6 +299,10 @@ class Term {
} }
writeStr(d) { writeStr(d) {
if (this.closed) {
return;
}
try { try {
this.term.write(d); this.term.write(d);
} catch (e) { } catch (e) {
@@ -283,6 +311,10 @@ class Term {
} }
write(d) { write(d) {
if (this.closed) {
return;
}
try { try {
this.term.write(d); this.term.write(d);
} catch (e) { } catch (e) {
@@ -291,6 +323,10 @@ class Term {
} }
fontSizeUp() { fontSizeUp() {
if (this.closed) {
return;
}
if (this.fontSize >= termMaxFontSize) { if (this.fontSize >= termMaxFontSize) {
return; return;
} }
@@ -301,6 +337,10 @@ class Term {
} }
fontSizeDown() { fontSizeDown() {
if (this.closed) {
return;
}
if (this.fontSize <= termMinFontSize) { if (this.fontSize <= termMinFontSize) {
return; return;
} }
@@ -311,6 +351,10 @@ class Term {
} }
focus() { focus() {
if (this.closed) {
return;
}
try { try {
this.term.focus(); this.term.focus();
} catch (e) { } catch (e) {
@@ -319,6 +363,10 @@ class Term {
} }
blur() { blur() {
if (this.closed) {
return;
}
try { try {
this.term.blur(); this.term.blur();
} catch (e) { } catch (e) {
@@ -327,6 +375,10 @@ class Term {
} }
refit() { refit() {
if (this.closed) {
return;
}
try { try {
this.fit.fit(); this.fit.fit();
} catch (e) { } catch (e) {
@@ -334,7 +386,15 @@ class Term {
} }
} }
destroyed() {
return this.closed;
}
destroy() { destroy() {
if (this.closed) {
return;
}
this.closed = true; this.closed = true;
try { try {
@@ -381,7 +441,6 @@ export default {
screenKeys: consoleScreenKeys, screenKeys: consoleScreenKeys,
term: new Term(this.control), term: new Term(this.control),
typeface: termTypeFace, typeface: termTypeFace,
running: true,
runner: null runner: null
}; };
}, },
@@ -401,13 +460,10 @@ export default {
} }
}, },
async mounted() { async mounted() {
this.running = true;
await this.init(); await this.init();
}, },
beforeDestroy() { beforeDestroy() {
this.deinit(); this.deinit();
this.running = false;
}, },
methods: { methods: {
loadRemoteFont(typeface, timeout) { loadRemoteFont(typeface, timeout) {
@@ -418,38 +474,43 @@ export default {
}).load(null, timeout) }).load(null, timeout)
]); ]);
}, },
retryLoadRemoteFont(typeface, timeout, onSuccess) { async retryLoadRemoteFont(typeface, timeout, onSuccess) {
const self = this; const self = this;
self for (;;) {
.loadRemoteFont(typeface, timeout) if (self.term.destroyed()) {
.then(() => {
onSuccess();
})
.catch(() => {
if (!self.running) {
return; return;
} }
self.retryLoadRemoteFont(typeface, timeout, onSuccess); try {
}); onSuccess(await self.loadRemoteFont(typeface, timeout));
return;
} catch (e) {
// Retry
}
}
}, },
async openTerm(root, callbacks) { async openTerm(root, callbacks) {
const self = this; const self = this;
return self try {
.loadRemoteFont(termTypeFace, termTypeFaceLoadTimeout) await self.loadRemoteFont(termTypeFace, termTypeFaceLoadTimeout);
.then(() => {
if (!self.running) { if (self.term.destroyed()) {
return; return;
} }
root.innerHTML = ""; root.innerHTML = "";
self.term.init(root, callbacks); self.term.init(root, callbacks);
})
.catch(() => { return;
if (!self.running) { } catch (e) {
// Ignore
}
if (self.term.destroyed()) {
return; return;
} }
@@ -460,19 +521,14 @@ export default {
self.term.setFont(termFallbackTypeFace); self.term.setFont(termFallbackTypeFace);
self.term.init(root, callbacks); self.term.init(root, callbacks);
self.retryLoadRemoteFont( self.retryLoadRemoteFont(termTypeFace, termTypeFaceLoadTimeout, () => {
termTypeFace, if (self.term.destroyed()) {
termTypeFaceLoadTimeout,
() => {
if (!self.running) {
return; return;
} }
self.term.setFont(termTypeFace); self.term.setFont(termTypeFace);
callbacks.warn(termTypeFaceLoadError, true); callbacks.warn(termTypeFaceLoadError, true);
}
);
}); });
}, },
triggerActive() { triggerActive() {
@@ -506,6 +562,11 @@ export default {
} }
} }
); );
if (this.term.destroyed()) {
return;
}
this.triggerActive(); this.triggerActive();
this.runRunner(); this.runRunner();
}, },
@@ -545,6 +606,10 @@ export default {
this.runner = (async () => { this.runner = (async () => {
try { try {
for (;;) { for (;;) {
if (this.term.destroyed()) {
break;
}
this.term.write(await this.control.receive()); this.term.write(await this.control.receive());
self.$emit("updated"); self.$emit("updated");