🚀 Performance tuning & bugfix (#1111)

* Perfomance tuning

* cleanup matchesContainer method

* fixes #1131
This commit is contained in:
Vitaly Domnikov 2016-12-14 11:18:15 -08:00 committed by Guillermo Rauch
parent 23bff8b4b9
commit d6316dd209
2 changed files with 38 additions and 78 deletions

View file

@ -231,9 +231,6 @@ export default class Term extends Component {
.cursor-node[focus="false"] {
border-width: 1px !important;
}
x-row {
line-height: 1.2em;
}
${hyperCaret}
${osSpecificCss}
${css}

View file

@ -8,11 +8,6 @@ import selection from './utils/selection';
hterm.defaultStorage = new lib.Storage.Memory();
// The current width of characters rendered in hterm
let charWidth;
// Containers to resize when char width changes
const containers = [];
// Provide selectAll to terminal viewport
hterm.Terminal.prototype.selectAll = function () {
// If the cursorNode_ having hyperCaret we need to remove it
@ -24,25 +19,6 @@ hterm.Terminal.prototype.selectAll = function () {
}
};
const oldSetFontSize = hterm.Terminal.prototype.setFontSize;
hterm.Terminal.prototype.setFontSize = function (px) {
oldSetFontSize.call(this, px);
charWidth = this.scrollPort_.characterSize.width;
// @TODO Maybe clear old spans from the list of spans to resize ?
// Resize all containers to match the new whar width.
containers.forEach(container => {
if (container && container.style) {
container.style.width = `${container.wcNode ? charWidth * 2 : charWidth}px`;
}
});
};
const oldSyncFontFamily = hterm.Terminal.prototype.syncFontFamily;
hterm.Terminal.prototype.syncFontFamily = function () {
oldSyncFontFamily.call(this);
this.setFontSize();
};
// override double click behavior to copy
const oldMouse = hterm.Terminal.prototype.onMouse_;
hterm.Terminal.prototype.onMouse_ = function (e) {
@ -67,10 +43,10 @@ hterm.TextAttributes.splitWidecharString = function (str) {
return ctx;
}
if (ctx.acc) {
context.items.push({str: ctx.acc});
ctx.items.push({str: ctx.acc});
ctx.acc = '';
}
context.items.push({str: rune, wcNode: true});
ctx.items.push({str: rune, wcNode: true});
return ctx;
}, {items: [], acc: ''});
if (context.acc) {
@ -140,69 +116,56 @@ hterm.Terminal.IO.prototype.writeUTF8 = function (string) {
throw new Error('Attempt to print from inactive IO object.');
}
if (containsNonLatinCodepoints(string)) {
const splitString = runes(string);
const length = splitString.length;
this.terminal_.getTextAttributes().hasUnicode = true;
for (let curChar = 0; curChar <= length; curChar++) {
this.terminal_.interpret(splitString[curChar]);
}
this.terminal_.getTextAttributes().hasUnicode = false;
} else {
if (!containsNonLatinCodepoints(string)) {
this.terminal_.interpret(string);
return;
}
runes(string).forEach(rune => {
this.terminal_.getTextAttributes().unicodeNode = containsNonLatinCodepoints(rune);
this.terminal_.interpret(rune);
this.terminal_.getTextAttributes().unicodeNode = false;
});
};
const oldIsDefault = hterm.TextAttributes.prototype.isDefault;
hterm.TextAttributes.prototype.isDefault = function () {
return !this.unicodeNode && oldIsDefault.call(this);
};
const oldSetFontSize = hterm.Terminal.prototype.setFontSize;
hterm.Terminal.prototype.setFontSize = function (px) {
oldSetFontSize.call(this, px);
const doc = this.getDocument();
let unicodeNodeStyle = doc.getElementById('hyper-unicode-styles');
if (!unicodeNodeStyle) {
unicodeNodeStyle = doc.createElement('style');
unicodeNodeStyle.setAttribute('id', 'hyper-unicode-styles');
doc.head.appendChild(unicodeNodeStyle);
}
unicodeNodeStyle.innerHTML = `
.unicode-node {
display: inline-block;
width: ${this.scrollPort_.characterSize.width}px;
}
`;
};
const oldCreateContainer = hterm.TextAttributes.prototype.createContainer;
hterm.TextAttributes.prototype.createContainer = function (text) {
const container = oldCreateContainer.call(this, text);
if (container.style && text.length === 1 && containsNonLatinCodepoints(text)) {
container.style.width = `${container.wcNode ? charWidth * 2 : charWidth}px`;
container.style.display = 'inline-block';
// If the container has unicode text, the char can overlap neigbouring containers. We need
// to ensure that the text is not hidden behind other containers.
container.style.overflow = 'visible';
container.style.position = 'relative';
// Remember this container to resize it later when font size changes.
containers.push(container);
if (container.style && runes(text).length === 1 && containsNonLatinCodepoints(text)) {
container.className += ' unicode-node';
}
return container;
};
// Do not match containers when one of them has unicode text (unicode chars need to be alone in their containers)
const oldMatchesContainer = hterm.TextAttributes.prototype.matchesContainer;
hterm.TextAttributes.prototype.matchesContainer = function (obj) {
const content = typeof obj === 'string' ? obj : obj.textContent;
if (containsNonLatinCodepoints(content)) {
return false;
}
if (this.hasUnicode) {
return false;
}
return oldMatchesContainer.call(this, obj);
};
/**
* Override 'containersMatch' so that containers with unicode do not match anything.
*/
const oldContainersMatch = hterm.TextAttributes.containersMatch;
hterm.TextAttributes.containersMatch = function (obj1, obj2) {
const content1 = typeof obj1 === 'string' ? obj1 : obj1.textContent;
const content2 = typeof obj2 === 'string' ? obj2 : obj2.textContent;
if (containsNonLatinCodepoints(content1) || containsNonLatinCodepoints(content2)) {
return false;
}
return oldContainersMatch(obj1, obj2);
return oldMatchesContainer.call(this, obj) &&
!this.unicodeNode &&
!containsNonLatinCodepoints(obj.textContent);
};
// there's no option to turn off the size overlay