Merge pull request #1079 from loganhz/master

upgrade xterm and make container shell larger
This commit is contained in:
Vincent Fiduccia 2017-03-24 11:09:37 -07:00 committed by GitHub
commit 6fbca89320
9 changed files with 96 additions and 17 deletions

View File

@ -1,22 +1,50 @@
import Ember from 'ember';
import { alternateLabel } from 'ui/utils/platform';
import ThrottledResize from 'ui/mixins/throttled-resize';
import Terminal from 'npm:xterm';
import { proposeGeometry } from 'ui/utils/xterm-fit-addon';
const DEFAULT_COMMAND = ["/bin/sh","-c",'TERM=xterm-256color; export TERM; [ -x /bin/bash ] && ([ -x /usr/bin/script ] && /usr/bin/script -q -c "/bin/bash" /dev/null || exec /bin/bash) || exec /bin/sh'];
export default Ember.Component.extend({
export default Ember.Component.extend(ThrottledResize, {
instance: null,
command: null,
cols: 80,
rows: 24,
alternateLabel: alternateLabel,
showProtip: true,
contenteditable: false,
status: 'connecting',
error: null,
socket: null,
term: null,
actions: {
contextMenuHandler() {
// fix for no paste button in firefox context menu on Windows
this.set('contenteditable', true);
setTimeout(()=> {
this.set('contenteditable', false);
}, 20);
}
},
fit() {
var term = this.get('term');
var socket = this.get('socket');
if (term && socket)
{
var geometry = proposeGeometry(term);
socket.send(`:resizeTTY:${geometry.cols},${geometry.rows}`);
term.resize(geometry.cols, geometry.rows);
}
},
onResize: function () {
this.fit();
},
didInsertElement: function() {
this._super();
Ember.run.next(this, 'exec');
@ -53,8 +81,6 @@ export default Ember.Component.extend({
this.set('status','initializing');
var term = new Terminal({
cols: this.get('cols'),
rows: this.get('rows'),
useStyle: true,
screenKeys: true,
cursorBlink: false
@ -67,7 +93,7 @@ export default Ember.Component.extend({
});
term.open(this.$('.shell-body')[0]);
this.fit();
socket.onmessage = (message) => {
this.set('status','connected');
this.sendAction('connected');

View File

@ -5,7 +5,7 @@
<hr>
{{/if}}
<h2 class='mb-10'><i class="icon icon-terminal"></i> {{t 'modalShell.title' instanceName=instance.displayName}}</h2>
<div class="shell-body">
<div class="shell-body" contenteditable="{{contenteditable}}" oncontextmenu={{action "contextMenuHandler"}}>
</div>
<div class="footer-actions">
<div class="console-status text-muted">{{t (concat-str 'containerShell.status' status character='.') error=error}}</div>

View File

@ -2,7 +2,7 @@ import Ember from 'ember';
import ModalBase from 'ui/mixins/modal-base';
export default Ember.Component.extend(ModalBase, {
classNames: ['modal-container', 'large-modal', 'modal-shell'],
classNames: ['modal-container', 'large-modal', 'fullscreen-modal', 'modal-shell'],
originalModel: Ember.computed.alias('modalService.modalOpts.model'),
init() {
this._super(...arguments);

View File

@ -7,6 +7,5 @@
dismiss=(action "cancel")
disconncted=(action "cancel")
}}
<button {{action "cancel"}} class="btn bg-primary">{{t 'consolePage.closeButton'}}</button>
{{/container-shell}}
</div>

View File

@ -72,7 +72,7 @@ var Container = Instance.extend({
let proj = this.get('projects.current.id');
let id = this.get('id');
Ember.run.later(() => {
window.open(`//${window.location.host}/env/${proj}/infra/console?instanceId=${id}&isPopup=true`, '_blank', "toolbars=0,width=717,height=590,left=200,top=200");
window.open(`//${window.location.host}/env/${proj}/infra/console?instanceId=${id}&isPopup=true`, '_blank', "toolbars=0,width=900,height=700,left=200,top=200");
});
},

View File

@ -1,11 +1,28 @@
.shell-body {
display: flex;
width: 100%;
height: 400px;
height: calc(100vh - 260px);
margin: 0 auto;
background-color: #000;
}
.terminal {
margin: 0 auto;
font-size: 12px;
font-family: "Lucida Console", Monaco, "Courier New", monospace;
}
.shell-body .terminal {
margin: 0 auto;
font-size: 12px;
font-family: "Lucida Console", Monaco, "Courier New", monospace;
padding: 10px;
}
.fullscreen-modal {
max-width: none !important;
}
.terminal .xterm-viewport {
overflow-y: auto;
}
.shell-popup .shell-body{
height: calc(100vh - 100px);
}
.shell-status {
@ -14,7 +31,11 @@
}
.shell-popup {
padding: 20px;
padding: 10px;
}
.shell-popup .footer-actions {
margin: 10px 0;
}
.xterm-rows {

View File

@ -0,0 +1,33 @@
export function proposeGeometry(term) {
if (!term.element.parentElement) {
return null;
}
var parentElementStyle = window.getComputedStyle(term.element.parentElement),
parentElementHeight = parseInt(parentElementStyle.getPropertyValue('height')),
parentElementWidth = Math.max(0, parseInt(parentElementStyle.getPropertyValue('width')) - 17),
elementStyle = window.getComputedStyle(term.element),
elementPaddingVer = parseInt(elementStyle.getPropertyValue('padding-top')) + parseInt(elementStyle.getPropertyValue('padding-bottom')),
elementPaddingHor = parseInt(elementStyle.getPropertyValue('padding-right')) + parseInt(elementStyle.getPropertyValue('padding-left')),
availableHeight = parentElementHeight - elementPaddingVer,
availableWidth = parentElementWidth - elementPaddingHor,
subjectRow = term.rowContainer.firstElementChild,
contentBuffer = subjectRow.innerHTML,
characterHeight,
rows,
characterWidth,
cols,
geometry;
subjectRow.style.display = 'inline';
subjectRow.innerHTML = 'W'; // Common character for measuring width, although on monospace
characterWidth = subjectRow.getBoundingClientRect().width;
subjectRow.style.display = ''; // Revert style before calculating height, since they differ.
characterHeight = parseInt(subjectRow.offsetHeight);
subjectRow.innerHTML = contentBuffer;
rows = Math.floor(availableHeight / characterHeight);
cols = Math.floor(availableWidth / characterWidth);
geometry = { cols: cols, rows: rows };
return geometry;
}

View File

@ -36,7 +36,7 @@ module.exports = function(defaults) {
},
nodeAssets: {
'xterm': {
import: ['src/xterm.css']
import: ['dist/xterm.css']
}
},

View File

@ -65,7 +65,7 @@
"postcss-scss": "^0.4.0",
"semver": "^5.3.0",
"shell-quote": "^1.4.3",
"xterm": "1.0.0",
"xterm": "2.4.0",
"yamljs": "^0.2.7"
},
"dependencies": {