Skip to content
Snippets Groups Projects
Commit b5083adb authored by selva's avatar selva Committed by dilawar
Browse files

Fix termynal

parent 53f4d2b5
No related branches found
No related tags found
1 merge request!11update Documentation
/**
* termynal.js
*
* @author Ines Montani <ines@ines.io>
* @version 0.0.1
* @license MIT
*/
:root {
--color-bg: #252a33;
--color-text: #eee;
--color-text-subtle: #a2a2a2;
}
[data-termynal] {
width: 750px;
max-width: 100%;
background: var(--color-bg);
color: var(--color-text);
font-size: 18px;
font-family: 'Fira Mono', Consolas, Menlo, Monaco, 'Courier New', Courier, monospace;
border-radius: 4px;
padding: 75px 45px 35px;
position: relative;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
[data-termynal]:before {
content: '';
position: absolute;
top: 15px;
left: 15px;
display: inline-block;
width: 15px;
height: 15px;
border-radius: 50%;
/* A little hack to display the window buttons in one pseudo element. */
background: #d9515d;
-webkit-box-shadow: 25px 0 0 #f4c025, 50px 0 0 #3ec930;
box-shadow: 25px 0 0 #f4c025, 50px 0 0 #3ec930;
}
[data-termynal]:after {
content: 'bash';
position: absolute;
color: var(--color-text-subtle);
top: 5px;
left: 0;
width: 100%;
text-align: center;
}
[data-ty] {
display: block;
line-height: 2;
}
[data-ty]:before {
/* Set up defaults and ensure empty lines are displayed. */
content: '';
display: inline-block;
vertical-align: middle;
}
[data-ty="input"]:before,
[data-ty-prompt]:before {
margin-right: 0.75em;
color: var(--color-text-subtle);
}
[data-ty="input"]:before {
content: '$';
}
[data-ty][data-ty-prompt]:before {
content: attr(data-ty-prompt);
}
[data-ty-cursor]:after {
content: attr(data-ty-cursor);
font-family: monospace;
margin-left: 0.5em;
-webkit-animation: blink 1s infinite;
animation: blink 1s infinite;
}
/* Cursor animation */
@-webkit-keyframes blink {
50% {
opacity: 0;
}
}
@keyframes blink {
50% {
opacity: 0;
}
}
/**
* termynal.js
* A lightweight, modern and extensible animated terminal window, using
* async/await.
*
* @author Ines Montani <ines@ines.io>
* @version 0.0.1
* @license MIT
*/
'use strict';
/** Generate a terminal widget. */
class Termynal {
/**
* Construct the widget's settings.
* @param {(string|Node)=} container - Query selector or container element.
* @param {Object=} options - Custom settings.
* @param {string} options.prefix - Prefix to use for data attributes.
* @param {number} options.startDelay - Delay before animation, in ms.
* @param {number} options.typeDelay - Delay between each typed character, in ms.
* @param {number} options.lineDelay - Delay between each line, in ms.
* @param {number} options.progressLength - Number of characters displayed as progress bar.
* @param {string} options.progressChar – Character to use for progress bar, defaults to █.
* @param {number} options.progressPercent - Max percent of progress.
* @param {string} options.cursor – Character to use for cursor, defaults to ▋.
* @param {Object[]} lineData - Dynamically loaded line data objects.
* @param {boolean} options.noInit - Don't initialise the animation.
*/
constructor(container = '#termynal', options = {}) {
this.container = (typeof container === 'string') ? document.querySelector(container) : container;
this.pfx = `data-${options.prefix || 'ty'}`;
this.startDelay = options.startDelay
|| parseFloat(this.container.getAttribute(`${this.pfx}-startDelay`)) || 600;
this.typeDelay = options.typeDelay
|| parseFloat(this.container.getAttribute(`${this.pfx}-typeDelay`)) || 90;
this.lineDelay = options.lineDelay
|| parseFloat(this.container.getAttribute(`${this.pfx}-lineDelay`)) || 1500;
this.progressLength = options.progressLength
|| parseFloat(this.container.getAttribute(`${this.pfx}-progressLength`)) || 40;
this.progressChar = options.progressChar
|| this.container.getAttribute(`${this.pfx}-progressChar`) || '';
this.progressPercent = options.progressPercent
|| parseFloat(this.container.getAttribute(`${this.pfx}-progressPercent`)) || 100;
this.cursor = options.cursor
|| this.container.getAttribute(`${this.pfx}-cursor`) || '';
this.lineData = this.lineDataToElements(options.lineData || []);
if (!options.noInit) this.init()
}
/**
* Initialise the widget, get lines, clear container and start animation.
*/
init() {
// Appends dynamically loaded lines to existing line elements.
this.lines = [...this.container.querySelectorAll(`[${this.pfx}]`)].concat(this.lineData);
/**
* Calculates width and height of Termynal container.
* If container is empty and lines are dynamically loaded, defaults to browser `auto` or CSS.
*/
const containerStyle = getComputedStyle(this.container);
this.container.style.width = containerStyle.width !== '0px' ?
containerStyle.width : undefined;
this.container.style.minHeight = containerStyle.height !== '0px' ?
containerStyle.height : undefined;
this.container.setAttribute('data-termynal', '');
this.container.innerHTML = '';
this.start();
}
/**
* Start the animation and rener the lines depending on their data attributes.
*/
async start() {
await this._wait(this.startDelay);
for (let line of this.lines) {
const type = line.getAttribute(this.pfx);
const delay = line.getAttribute(`${this.pfx}-delay`) || this.lineDelay;
if (type == 'input') {
line.setAttribute(`${this.pfx}-cursor`, this.cursor);
await this.type(line);
await this._wait(delay);
}
else if (type == 'progress') {
await this.progress(line);
await this._wait(delay);
}
else {
this.container.appendChild(line);
await this._wait(delay);
}
line.removeAttribute(`${this.pfx}-cursor`);
}
}
/**
* Animate a typed line.
* @param {Node} line - The line element to render.
*/
async type(line) {
const chars = [...line.textContent];
const delay = line.getAttribute(`${this.pfx}-typeDelay`) || this.typeDelay;
line.textContent = '';
this.container.appendChild(line);
for (let char of chars) {
await this._wait(delay);
line.textContent += char;
}
}
/**
* Animate a progress bar.
* @param {Node} line - The line element to render.
*/
async progress(line) {
const progressLength = line.getAttribute(`${this.pfx}-progressLength`)
|| this.progressLength;
const progressChar = line.getAttribute(`${this.pfx}-progressChar`)
|| this.progressChar;
const chars = progressChar.repeat(progressLength);
const progressPercent = line.getAttribute(`${this.pfx}-progressPercent`)
|| this.progressPercent;
line.textContent = '';
this.container.appendChild(line);
for (let i = 1; i < chars.length + 1; i++) {
await this._wait(this.typeDelay);
const percent = Math.round(i / chars.length * 100);
line.textContent = `${chars.slice(0, i)} ${percent}%`;
if (percent>progressPercent) {
break;
}
}
}
/**
* Helper function for animation delays, called with `await`.
* @param {number} time - Timeout, in ms.
*/
_wait(time) {
return new Promise(resolve => setTimeout(resolve, time));
}
/**
* Converts line data objects into line elements.
*
* @param {Object[]} lineData - Dynamically loaded lines.
* @param {Object} line - Line data object.
* @returns {Element[]} - Array of line elements.
*/
lineDataToElements(lineData) {
return lineData.map(line => {
let div = document.createElement('div');
div.innerHTML = `<span ${this._attributes(line)}>${line.value || ''}</span>`;
return div.firstElementChild;
});
}
/**
* Helper function for generating attributes string.
*
* @param {Object} line - Line data object.
* @returns {string} - String of attributes.
*/
_attributes(line) {
let attrs = '';
for (let prop in line) {
attrs += this.pfx;
if (prop === 'type') {
attrs += `="${line[prop]}" `
} else if (prop !== 'value') {
attrs += `-${prop}="${line[prop]}" `
}
}
return attrs;
}
}
/**
* HTML API: If current script has container(s) specified, initialise Termynal.
*/
if (document.currentScript.hasAttribute('data-termynal-container')) {
const containers = document.currentScript.getAttribute('data-termynal-container');
containers.split('|')
.forEach(container => new Termynal(container))
}
\ No newline at end of file
...@@ -64,8 +64,8 @@ sphinx_tabs_valid_builders = ['linkcheck'] ...@@ -64,8 +64,8 @@ sphinx_tabs_valid_builders = ['linkcheck']
sphinx_tabs_disable_tab_closing = True sphinx_tabs_disable_tab_closing = True
#html_css_files=['./css/termynal.css'] html_css_files=['https://raw.githack.com/ines/termynal/master/termynal.css']
# html_js_files=['./js/termynal.js']
sphinx_tabs_disable_css_loading = True sphinx_tabs_disable_css_loading = True
<link rel="stylesheet" type="text/css" href="./../_static/./css/termynal.css" />
# BiTIA Installation # BiTIA Installation
BiTIA CLI is the Command Line Interface Tool that helps get user inputs with commands, directories, and required files. It sends tasks to the server, where bitia-runner processes them and generates results. BiTIA CLI is the Command Line Interface Tool that helps get user inputs with commands, directories, and required files. It sends tasks to the server, where bitia-runner processes them and generates results.
...@@ -7,7 +7,7 @@ BiTIA CLI is the Command Line Interface Tool that helps get user inputs with com ...@@ -7,7 +7,7 @@ BiTIA CLI is the Command Line Interface Tool that helps get user inputs with com
## Installing bitia ## Installing bitia
BiTIA CLI is available on [PyPi] as [BiTIA]. BiTIA CLI is available on [PyPi] as [BiTIA].
Installing bitia is very simple, you only need to have [python-pip] installed in your system Installing bitia is very simple. You only need to have [python-pip] installed in your system.
...@@ -46,7 +46,7 @@ TODO: Order of searching configuration file. ...@@ -46,7 +46,7 @@ TODO: Order of searching configuration file.
</div> </div>
<script src="./../_static/./js/termynal.js" data-termynal-container="#termynal"></script> <script type="text/javascript" src="https://raw.githack.com/tiangolo/fastapi/master/docs/en/docs/js/termynal.js" data-termynal-container="#termynal"></script>
......
...@@ -63,4 +63,9 @@ The above code will: ...@@ -63,4 +63,9 @@ The above code will:
<script src="../_static/./js/termynal.js" data-termynal-container="#termynal"></script>
\ No newline at end of file <script type="text/javascript" src="https://raw.githack.com/tiangolo/fastapi/master/docs/en/docs/js/termynal.js" data-termynal-container="#termynal"></script>
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment