Skip to content

Commit

Permalink
🚀 Performance tuning & bugfix (#1111)
Browse files Browse the repository at this point in the history
* Perfomance tuning

* cleanup matchesContainer method

* fixes #1131
  • Loading branch information
dotcypress authored and rauchg committed Dec 14, 2016
1 parent 23bff8b commit d6316dd
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 77 deletions.
3 changes: 0 additions & 3 deletions lib/components/term.js
Original file line number Diff line number Diff line change
Expand Up @@ -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}
Expand Down
111 changes: 37 additions & 74 deletions lib/hterm.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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) {
Expand All @@ -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) {
Expand Down Expand Up @@ -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;
if (!containsNonLatinCodepoints(string)) {
this.terminal_.interpret(string);
return;
}

for (let curChar = 0; curChar <= length; curChar++) {
this.terminal_.interpret(splitString[curChar]);
}
runes(string).forEach(rune => {
this.terminal_.getTextAttributes().unicodeNode = containsNonLatinCodepoints(rune);
this.terminal_.interpret(rune);
this.terminal_.getTextAttributes().unicodeNode = false;
});
};

this.terminal_.getTextAttributes().hasUnicode = false;
} else {
this.terminal_.interpret(string);
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
Expand Down

0 comments on commit d6316dd

Please sign in to comment.