diff --git a/app/components/container-shell/component.js b/app/components/container-shell/component.js index bc09f2e50..d9475d14c 100644 --- a/app/components/container-shell/component.js +++ b/app/components/container-shell/component.js @@ -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'); diff --git a/app/components/container-shell/template.hbs b/app/components/container-shell/template.hbs index d58871862..f94d68fcd 100644 --- a/app/components/container-shell/template.hbs +++ b/app/components/container-shell/template.hbs @@ -5,7 +5,7 @@
{{/if}}

{{t 'modalShell.title' instanceName=instance.displayName}}

-
+
diff --git a/app/models/container.js b/app/models/container.js index 6228db44a..8e1217657 100644 --- a/app/models/container.js +++ b/app/models/container.js @@ -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"); }); }, diff --git a/app/styles/components/_container-shell.scss b/app/styles/components/_container-shell.scss index 7d1887726..2213383bf 100644 --- a/app/styles/components/_container-shell.scss +++ b/app/styles/components/_container-shell.scss @@ -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 { diff --git a/app/utils/xterm-fit-addon.js b/app/utils/xterm-fit-addon.js new file mode 100644 index 000000000..75c0c2c76 --- /dev/null +++ b/app/utils/xterm-fit-addon.js @@ -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; +} diff --git a/ember-cli-build.js b/ember-cli-build.js index 8a181deaa..ea18704fd 100644 --- a/ember-cli-build.js +++ b/ember-cli-build.js @@ -36,7 +36,7 @@ module.exports = function(defaults) { }, nodeAssets: { 'xterm': { - import: ['src/xterm.css'] + import: ['dist/xterm.css'] } }, diff --git a/package.json b/package.json index 23f14e5c5..3550e523f 100644 --- a/package.json +++ b/package.json @@ -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": {