Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Element going out of html, body set dimension

I was working with xtermjs to make an in browser terminal and everything works fine except for 1 bug I have in my code which I can’t figure out. The problem is when the terminal is aligned to the bottom of the page and you type any key and pressed enter a couple of times until you reach near the end of vertical space the terminal will start to go out of bounding of HTML, body. I tried adding border: 0px; as it is suggested at xterms github but that didn’t fix it. I even tried position: fixed; overflow: hidden; margin: 0%; but that didn’t fix it too. How can I make the position of the terminal stick to the bottom of the page and not go out of the HTML, body’s dimension which is width: 100%; height: 100%; when the end of the vertical line space is about to be reached?

var term = new Terminal({
  cursorBlink: "block"
});

var curr_line = '';
var entries = [];
var currPos = 0;
var pos = 0;

term.open(document.getElementById('terminal'));
term.prompt = () => {
  term.write('\n\r' + curr_line + '\r\n\u001b[32m~$>> \u001b[37m');
};
term.write('#Terminal');
term.prompt();

term.onKey(function(key) {
  const printable = !key.altKey && !key.altGraphKey && !key.ctrlKey && !key.metaKey &&
    !(key.key === ' ' && term._core.buffer.x < 6);
  if (key.key === '\r') { // Enter key
    if (curr_line.replace(/^\s+|\s+$/g, '').length != 0) { // Check if string is all whitespace
      entries.push(curr_line);
      currPos = entries.length - 1;
      term.prompt();
    } else {
      term.write('\n\33[2K\r\u001b[32m~$>> \u001b[37m');
    }
    curr_line = '';
  } else if (key.key === '\x7F') { // Backspace\
    if (term._core.buffer.x > 5) {
      curr_line = curr_line.slice(0, term._core.buffer.x - 6) + curr_line.slice(term._core.buffer.x - 5);
      pos = curr_line.length - term._core.buffer.x + 6;
      term.write('\33[2K\r\u001b[32m~$>> \u001b[37m' + curr_line);
      term.write('\033['.concat(pos.toString()).concat('D')); //term.write('\033[<N>D');
      if (term._core.buffer.x == 5 || term._core.buffer.x == curr_line.length + 6) {
        term.write('\033[1C')
      }
    }
  } else if (key.key === '\x1B[A') { // Up arrow
    if (entries.length > 0) {
      if (currPos > 0) {
        currPos -= 1;
      }
      curr_line = entries[currPos];
      term.write('\33[2K\r\u001b[32m~$>> \u001b[37m' + curr_line);
    }
  } else if (key.key === '\x1B[B') { // Down arrow
    currPos += 1;
    if (currPos === entries.length || entries.length === 0) {
      currPos -= 1;
      curr_line = '';
      term.write('\33[2K\r\u001b[32m~$>> \u001b[37m');
    } else {
      curr_line = entries[currPos];
      term.write('\33[2K\r\u001b[32m~$>> \u001b[37m' + curr_line);

    }
  } else if (printable && !(key.key === '\x1B[C' && term._core.buffer.x > curr_line.length + 4)) {
    if (key.key != '\x1B[D' && key.key != '\x1B[C') {
      var input = key.key;
      if (key.key == '\t') { // Tab
        input = "    ";
      }
      curr_line += input;
      term.write(input);
      // pos = curr_line.length - term._core.buffer.x + 4;
      // curr_line = [curr_line.slice(0, term._core.buffer.x - 5), input, curr_line.slice(term._core.buffer.x - 5)].join('');
      // term.write('\33[2K\r\u001b[32m~$>> \u001b[37m' + curr_line);
      // term.write('\033['.concat(pos.toString()).concat('D')); //term.write('\033[<N>D');
    } else {
      term.write(key.key);
    }
  }
});
html,
body {
  width: 100%;
  height: 100%;
  /*overflow: hidden; didn't work*/
}

.codeRunCon {
  display: flex;
  position: absolute;
  right: 0%;
  bottom: 0%;
  width: 100%;
  height: 80%;
  background-color: inherit;
}

.codeRunCon #terminal {
  display: flex;
  position: absolute;
  top: 20px;
  left: 0%;
  width: 100%;
  height: 100%;
  background-color: #000000;
}

.xterm {
  position: absolute;
  top: 0%;
  left: 0%;
  width: 100%;
  height: 100%;
  font-feature-settings: "liga" 0;
  position: relative;
  user-select: none;
  -ms-user-select: none;
  -webkit-user-select: none;
}

.xterm.focus,
.xterm:focus {
  outline: none;
}

.xterm .xterm-helpers {
  position: absolute;
  top: 0;
  /**
     * The z-index of the helpers must be higher than the canvases in order for
     * IMEs to appear on top.
     */
  z-index: 5;
}

.xterm .xterm-helper-textarea {
  /*
     * HACK: to fix IE's blinking cursor
     * Move textarea out of the screen to the far left, so that the cursor is not visible.
     */
  border: 0px;
  position: absolute;
  opacity: 0;
  left: -9999em;
  top: 0;
  width: 0;
  height: 0;
  z-index: -5;
  /** Prevent wrapping so the IME appears against the textarea at the correct position */
  white-space: nowrap;
  overflow: hidden;
  resize: none;
}

.xterm .composition-view {
  /* TODO: Composition position got messed up somewhere */
  background: #000;
  color: #FFF;
  display: none;
  position: absolute;
  white-space: nowrap;
  z-index: 1;
}

.xterm .composition-view.active {
  display: block;
}

.xterm .xterm-viewport {
  /* On OS X this is required in order for the scroll bar to appear fully opaque */
  background-color: #000;
  overflow-y: scroll;
  cursor: default;
  position: absolute;
  right: -20px;
  left: 0;
  top: 0;
  bottom: 0;
  margin-top: auto;
}

.xterm-viewport::-webkit-scrollbar {
  background-color: var(--dark);
  width: 5px;
}

.xterm-viewport::-webkit-scrollbar-thumb {
  background: var(--highlight);
}

.xterm .xterm-screen {
  position: relative;
  width: 100% !important;
  height: 100% !important;
}

.xterm .xterm-screen canvas {
  position: absolute;
  left: 0;
  top: 0;
  width: 100% !important;
  height: 100% !important;
}

.xterm .xterm-scroll-area {
  visibility: hidden;
}

.xterm-char-measure-element {
  display: inline-block;
  visibility: hidden;
  position: absolute;
  top: 0;
  left: -9999em;
  line-height: normal;
}

.xterm {
  cursor: text;
}

.xterm.enable-mouse-events {
  /* When mouse events are enabled (eg. tmux), revert to the standard pointer cursor */
  cursor: default;
}

.xterm.xterm-cursor-pointer {
  cursor: pointer;
}

.xterm.column-select.focus {
  /* Column selection mode */
  cursor: crosshair;
}

.xterm .xterm-accessibility,
.xterm .xterm-message {
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  right: 0;
  z-index: 10;
  color: transparent;
}

.xterm .live-region {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.xterm-dim {
  opacity: 0.5;
}

.xterm-underline {
  text-decoration: underline;
}
<script src="https://cdn.jsdelivr.net/npm/xterm@4.15.0/lib/xterm.min.js"></script>

<div class="table-responsive codeRunCon" id="codeRunCon">
  <div id="terminal"></div>
</div>

>Solution :

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

look into css in .codeRunCon #terminal and change top: 20px; into bottom: 0. Adding body {margin: 0;} should help too.

var term = new Terminal({
  cursorBlink: "block"
});

var curr_line = '';
var entries = [];
var currPos = 0;
var pos = 0;

term.open(document.getElementById('terminal'));
term.prompt = () => {
  term.write('\n\r' + curr_line + '\r\n\u001b[32m~$>> \u001b[37m');
};
term.write('#Terminal');
term.prompt();

term.onKey(function(key) {
  const printable = !key.altKey && !key.altGraphKey && !key.ctrlKey && !key.metaKey &&
    !(key.key === ' ' && term._core.buffer.x < 6);
  if (key.key === '\r') { // Enter key
    if (curr_line.replace(/^\s+|\s+$/g, '').length != 0) { // Check if string is all whitespace
      entries.push(curr_line);
      currPos = entries.length - 1;
      term.prompt();
    } else {
      term.write('\n\33[2K\r\u001b[32m~$>> \u001b[37m');
    }
    curr_line = '';
  } else if (key.key === '\x7F') { // Backspace\
    if (term._core.buffer.x > 5) {
      curr_line = curr_line.slice(0, term._core.buffer.x - 6) + curr_line.slice(term._core.buffer.x - 5);
      pos = curr_line.length - term._core.buffer.x + 6;
      term.write('\33[2K\r\u001b[32m~$>> \u001b[37m' + curr_line);
      term.write('\033['.concat(pos.toString()).concat('D')); //term.write('\033[<N>D');
      if (term._core.buffer.x == 5 || term._core.buffer.x == curr_line.length + 6) {
        term.write('\033[1C')
      }
    }
  } else if (key.key === '\x1B[A') { // Up arrow
    if (entries.length > 0) {
      if (currPos > 0) {
        currPos -= 1;
      }
      curr_line = entries[currPos];
      term.write('\33[2K\r\u001b[32m~$>> \u001b[37m' + curr_line);
    }
  } else if (key.key === '\x1B[B') { // Down arrow
    currPos += 1;
    if (currPos === entries.length || entries.length === 0) {
      currPos -= 1;
      curr_line = '';
      term.write('\33[2K\r\u001b[32m~$>> \u001b[37m');
    } else {
      curr_line = entries[currPos];
      term.write('\33[2K\r\u001b[32m~$>> \u001b[37m' + curr_line);

    }
  } else if (printable && !(key.key === '\x1B[C' && term._core.buffer.x > curr_line.length + 4)) {
    if (key.key != '\x1B[D' && key.key != '\x1B[C') {
      var input = key.key;
      if (key.key == '\t') { // Tab
        input = "    ";
      }
      curr_line += input;
      term.write(input);
      // pos = curr_line.length - term._core.buffer.x + 4;
      // curr_line = [curr_line.slice(0, term._core.buffer.x - 5), input, curr_line.slice(term._core.buffer.x - 5)].join('');
      // term.write('\33[2K\r\u001b[32m~$>> \u001b[37m' + curr_line);
      // term.write('\033['.concat(pos.toString()).concat('D')); //term.write('\033[<N>D');
    } else {
      term.write(key.key);
    }
  }
});
html,
body {
  width: 100%;
  height: 100%;
  /*overflow: hidden; didn't work*/
  margin: 0; /* add this */
}

.codeRunCon {
  display: flex;
  position: fixed;
  right: 0%;
  bottom: 0%;
  width: 100%;
  height: 80%;
  background-color: inherit;
}

.codeRunCon #terminal {
  display: flex;
  position: absolute;
  /* top: 20px; */ /* change this */
  bottom: 0; /* to this */
  left: 0%;
  width: 100%;
  height: 100%;
  background-color: #000000;
}

.xterm {
  position: absolute;
  top: 0%;
  left: 0%;
  width: 100%;
  height: 100%;
  font-feature-settings: "liga" 0;
  position: relative;
  user-select: none;
  -ms-user-select: none;
  -webkit-user-select: none;
}

.xterm.focus,
.xterm:focus {
  outline: none;
}

.xterm .xterm-helpers {
  position: absolute;
  top: 0;
  /**
     * The z-index of the helpers must be higher than the canvases in order for
     * IMEs to appear on top.
     */
  z-index: 5;
}

.xterm .xterm-helper-textarea {
  /*
     * HACK: to fix IE's blinking cursor
     * Move textarea out of the screen to the far left, so that the cursor is not visible.
     */
  border: 0px;
  position: absolute;
  opacity: 0;
  left: -9999em;
  top: 0;
  width: 0;
  height: 0;
  z-index: -5;
  /** Prevent wrapping so the IME appears against the textarea at the correct position */
  white-space: nowrap;
  overflow: hidden;
  resize: none;
}

.xterm .composition-view {
  /* TODO: Composition position got messed up somewhere */
  background: #000;
  color: #FFF;
  display: none;
  position: absolute;
  white-space: nowrap;
  z-index: 1;
}

.xterm .composition-view.active {
  display: block;
}

.xterm .xterm-viewport {
  /* On OS X this is required in order for the scroll bar to appear fully opaque */
  background-color: #000;
  overflow-y: scroll;
  cursor: default;
  position: absolute;
  right: -20px;
  left: 0;
  top: 0;
  bottom: 0;
  margin-top: auto;
}

.xterm-viewport::-webkit-scrollbar {
  background-color: var(--dark);
  width: 5px;
}

.xterm-viewport::-webkit-scrollbar-thumb {
  background: var(--highlight);
}

.xterm .xterm-screen {
  position: relative;
  width: 100% !important;
  height: 100% !important;
}

.xterm .xterm-screen canvas {
  position: absolute;
  left: 0;
  top: 0;
  width: 100% !important;
  height: 100% !important;
}

.xterm .xterm-scroll-area {
  visibility: hidden;
}

.xterm-char-measure-element {
  display: inline-block;
  visibility: hidden;
  position: absolute;
  top: 0;
  left: -9999em;
  line-height: normal;
}

.xterm {
  cursor: text;
}

.xterm.enable-mouse-events {
  /* When mouse events are enabled (eg. tmux), revert to the standard pointer cursor */
  cursor: default;
}

.xterm.xterm-cursor-pointer {
  cursor: pointer;
}

.xterm.column-select.focus {
  /* Column selection mode */
  cursor: crosshair;
}

.xterm .xterm-accessibility,
.xterm .xterm-message {
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  right: 0;
  z-index: 10;
  color: transparent;
}

.xterm .live-region {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.xterm-dim {
  opacity: 0.5;
}

.xterm-underline {
  text-decoration: underline;
}
<script src="https://cdn.jsdelivr.net/npm/xterm@4.15.0/lib/xterm.min.js"></script>

<div class="table-responsive codeRunCon" id="codeRunCon">
  <div id="terminal"></div>
</div>
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading