Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add fullscreen terminal support #1167

Merged
merged 1 commit into from
Feb 22, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions app/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ <h1>JavaScript Required</h1>
<script src="scripts/services/environment.js"></script>
<script src="scripts/services/keyValueEditorProvider.js"></script>
<script src="scripts/services/keyValueEditorUtils.js"></script>
<script src="scripts/services/fullscreen.js"></script>
<script src="scripts/controllers/projects.js"></script>
<script src="scripts/controllers/pods.js"></script>
<script src="scripts/controllers/pod.js"></script>
Expand Down
2 changes: 2 additions & 0 deletions app/scripts/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,8 @@ angular
.constant('RELATIVE_PATH_PATTERN', /^(?!\/)(?!\.\.(\/|$))(?!.*\/\.\.(\/|$)).*$/)
// http://stackoverflow.com/questions/9038625/detect-if-device-is-ios
.constant('IS_IOS', /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream)
// http://stackoverflow.com/questions/5899783/detect-safari-using-jquery
.constant('IS_SAFARI', /Version\/[\d\.]+.*Safari/.test(navigator.userAgent))
.constant('amTimeAgoConfig', {
// Set the title attribute to a localized time format like "September 4 1986 8:30 PM"
// See http://momentjs.com/docs/#/displaying/format/
Expand Down
16 changes: 16 additions & 0 deletions app/scripts/controllers/pod.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ angular.module('openshiftConsole')
Logger,
DataService,
EnvironmentService,
FullscreenService,
ImageStreamResolver,
MetricsService,
PodsService,
Expand Down Expand Up @@ -330,6 +331,21 @@ angular.module('openshiftConsole')
}
};

var focusTerminal = function() {
$('.terminal:visible').focus();
};

$scope.hasFullscreen = FullscreenService.hasFullscreen(true);
$scope.fullscreenTerminal = function() {
FullscreenService.requestFullscreen('#container-terminal-wrapper');
// Give focus back to the terminal after the user clicks the link.
setTimeout(focusTerminal);
};

$scope.exitFullscreen = function() {
FullscreenService.exitFullscreen();
};

$scope.debugTerminal = function(containerName) {
var debugPod = PodsService.generateDebugPod($scope.pod, containerName);
if (!debugPod) {
Expand Down
61 changes: 61 additions & 0 deletions app/scripts/services/fullscreen.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
'use strict';

angular.module("openshiftConsole")
.factory("FullscreenService", function(IS_SAFARI) {
var requestFullscreen =
document.documentElement.requestFullScreen ||
document.documentElement.webkitRequestFullScreen ||
document.documentElement.mozRequestFullScreen ||
document.documentElement.msRequestFullscreen;

var findElement = function(element) {
if (!element || !_.isString(element)) {
return element;
}

var matches = $(element);
if (!matches.length) {
return null;
}

return matches[0];
};

return {
hasFullscreen: function(needsKeyboard) {
// Safari blocks keyboard input in fullscreen mode. Unfortunately
// there's no feature detection for this, so fall back to user agent
// sniffing.
if (needsKeyboard && IS_SAFARI) {
return false;
}
return !!requestFullscreen;
},

// `element` is a DOM element or selector
requestFullscreen: function(element) {
if (!requestFullscreen) {
return;
}

element = findElement(element);
if (!element) {
return;
}

requestFullscreen.call(element);
},

exitFullscreen: function() {
if(document.exitFullscreen) {
document.exitFullscreen();
} else if(document.mozCancelFullScreen) {
document.mozCancelFullScreen();
} else if(document.webkitExitFullscreen) {
document.webkitExitFullscreen();
} else if (document.msExitFullscreen) {
document.msExitFullscreen();
}
}
};
});
8 changes: 0 additions & 8 deletions app/styles/_components.less
Original file line number Diff line number Diff line change
Expand Up @@ -216,14 +216,6 @@ code.command {
}
}

.pod-container-terminal {
margin-top: 15px;
margin-bottom: 15px;
kubernetes-container-terminal .terminal-wrapper {
max-width: 100%;
overflow-x: auto;
}
}
.builds-no-service {
.builds-block {
.builds {
Expand Down
76 changes: 72 additions & 4 deletions app/styles/_container-terminal.less
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,77 @@ kubernetes-container-terminal .terminal {
.terminal-font();
}

// Fill the extra right border we get when we cant quite fit the last col so it lines up with the Actions dropdown button
@media(min-width: @screen-sm-min) {
.container-terminal-wrapper {
.pod-container-terminal {
margin-top: 15px;
margin-bottom: 15px;
kubernetes-container-terminal .terminal-wrapper {
max-width: 100%;
overflow-x: auto;
}
}

.container-terminal-wrapper {
.style-terminal-action() {
color: @gray-light;
cursor: pointer;
font-size: 18px;
&:hover, &:active, &:focus {
color: #fff;
text-decoration: none;
}
}
position: relative;
.terminal-actions .btn {
.btn-link();
.style-terminal-action();
background: none;
}
.fullscreen-toggle {
display: none;
position: absolute;
top: 7px;
right: 15px;
z-index: 1;
a {
.style-terminal-action();
}
.exit-fullscreen {
display: none;
}
}
&.disconnected .go-fullscreen {
display: none;
}
.fullscreen() {
width: 100%;
height: 100%;
.go-fullscreen {
display: none;
}
.exit-fullscreen {
display: inline;
}
}
&:-webkit-full-screen {
.fullscreen();
}
&:-moz-full-screen {
.fullscreen();
}
&:-ms-full-screen {
.fullscreen();
}
&:-fullscreen {
.fullscreen();
}
@media(min-width: @screen-sm-min) {
// Fill the extra right border we get when we cant quite fit the last col so it lines up with the Actions dropdown button
background-color: #000;
// Show the expand to fullscreen action when hovering over the terminal.
&:hover {
.fullscreen-toggle {
display: inline-block;
}
}
}
}
}
55 changes: 33 additions & 22 deletions app/views/browse/pod.html
Original file line number Diff line number Diff line change
Expand Up @@ -131,16 +131,23 @@ <h2>
</h2>
</div>

<div ng-if="!noContainersYet">
<div class="mar-bottom-md mar-top-xl">
<div ng-if="!noContainersYet" class="mar-top-xl mar-bottom-xl">
<div class="mar-bottom-md">
<span class="pficon pficon-info" aria-hidden="true"></span>
When you navigate away from this pod, any open terminal connections will be closed.
This will kill any foreground processes you started from the terminal.
<span ng-class="{ 'mar-right-md': hasFullscreen }">
When you navigate away from this pod, any open terminal connections will be closed.
This will kill any foreground processes you started from the&nbsp;terminal.
</span>
<a href=""
ng-if="hasFullscreen"
ng-click="fullscreenTerminal()"
class="nowrap"
aria-hidden="true">Open Fullscreen Terminal</a>
</div>

<alerts ng-if="selectedTerminalContainer.status === 'disconnected'" alerts="terminalDisconnectAlert"></alerts>

<div class="mar-left-xl mar-bottom-xl">
<div class="mar-left-xl">
<div class="row">
<div class="pad-left-none pad-bottom-md col-sm-6 col-lg-4">
<span ng-if="pod.spec.containers.length === 1">
Expand Down Expand Up @@ -182,25 +189,29 @@ <h2>
</ui-select>
</div>
</div>
</div>

<div class="container-terminal-wrapper">
<div class="row" ng-repeat="term in containerTerminals">
<div class="column">
<kubernetes-container-terminal
prevent="!terminalTabWasSelected"
ng-if="term.isUsed"
ng-show="term.isVisible"
pod="pod"
container="term.containerName"
status="term.status"
rows="terminalRows"
cols="terminalCols"
autofocus="true"
command='["/bin/sh", "-i", "-c", "TERM=xterm /bin/sh"]'
>
</kubernetes-container-terminal>
</div>
<div id="container-terminal-wrapper"
class="container-terminal-wrapper"
ng-class="{ disconnected: selectedTerminalContainer.status === 'disconnected' }">
<div ng-repeat="term in containerTerminals">
<div ng-if="hasFullscreen" class="fullscreen-toggle" aria-hidden="true">
<a ng-href="" ng-click="fullscreenTerminal()" class="go-fullscreen" title="Open Fullscreen Terminal"><i class="fa fa-expand"></i></a>
<a ng-href="" ng-click="exitFullscreen()" class="exit-fullscreen" title="Exit Fullscreen"><i class="fa fa-compress"></i></a>
</div>
<kubernetes-container-terminal
prevent="!terminalTabWasSelected"
ng-if="term.isUsed"
ng-show="term.isVisible"
pod="pod"
container="term.containerName"
status="term.status"
rows="terminalRows"
cols="terminalCols"
autofocus="true"
command='["/bin/sh", "-i", "-c", "TERM=xterm /bin/sh"]'
>
</kubernetes-container-terminal>
</div>
</div>
</div>
Expand Down
Loading