Better code (callback -> async) and protection aganist early tab close (Close before terminal is loaded)
This commit is contained in:
@@ -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,62 +474,62 @@ 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(() => {
|
return;
|
||||||
onSuccess();
|
}
|
||||||
})
|
|
||||||
.catch(() => {
|
|
||||||
if (!self.running) {
|
|
||||||
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) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
root.innerHTML = "";
|
if (self.term.destroyed()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
self.term.init(root, callbacks);
|
root.innerHTML = "";
|
||||||
})
|
|
||||||
.catch(() => {
|
|
||||||
if (!self.running) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
root.innerHTML = "";
|
self.term.init(root, callbacks);
|
||||||
|
|
||||||
callbacks.warn(termTypeFaceLoadError, false);
|
return;
|
||||||
|
} catch (e) {
|
||||||
|
// Ignore
|
||||||
|
}
|
||||||
|
|
||||||
self.term.setFont(termFallbackTypeFace);
|
if (self.term.destroyed()) {
|
||||||
self.term.init(root, callbacks);
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
self.retryLoadRemoteFont(
|
root.innerHTML = "";
|
||||||
termTypeFace,
|
|
||||||
termTypeFaceLoadTimeout,
|
|
||||||
() => {
|
|
||||||
if (!self.running) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
self.term.setFont(termTypeFace);
|
callbacks.warn(termTypeFaceLoadError, false);
|
||||||
|
|
||||||
callbacks.warn(termTypeFaceLoadError, true);
|
self.term.setFont(termFallbackTypeFace);
|
||||||
}
|
self.term.init(root, callbacks);
|
||||||
);
|
|
||||||
});
|
self.retryLoadRemoteFont(termTypeFace, termTypeFaceLoadTimeout, () => {
|
||||||
|
if (self.term.destroyed()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.term.setFont(termTypeFace);
|
||||||
|
|
||||||
|
callbacks.warn(termTypeFaceLoadError, true);
|
||||||
|
});
|
||||||
},
|
},
|
||||||
triggerActive() {
|
triggerActive() {
|
||||||
this.active ? this.activate() : this.deactivate();
|
this.active ? this.activate() : this.deactivate();
|
||||||
@@ -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");
|
||||||
|
|||||||
Reference in New Issue
Block a user