From 3c74b0bbd930ef84d5399991c03adda1558aadb8 Mon Sep 17 00:00:00 2001 From: Dries007 Date: Wed, 7 Feb 2018 20:56:27 +0100 Subject: [PATCH] Update terminal lib to new version, enabled autoscroll --- .../resources/static/css/jquery.terminal.css | 608 +- .../static/css/jquery.terminal.min.css | 8 +- .../resources/static/js/jquery.terminal.js | 5830 +++++++++++------ .../static/js/jquery.terminal.min.js | 11 +- .../resources/static/js/unix_formatting.js | 162 +- .../resources/templates/serverconsole.ftl | 9 +- 6 files changed, 4556 insertions(+), 2072 deletions(-) diff --git a/src/main/resources/static/css/jquery.terminal.css b/src/main/resources/static/css/jquery.terminal.css index 12c2e8f..9873474 100644 --- a/src/main/resources/static/css/jquery.terminal.css +++ b/src/main/resources/static/css/jquery.terminal.css @@ -4,15 +4,15 @@ * __ / // // // // // _ // _// // / / // _ // _// // // \/ // _ \/ / * / / // // // // // ___// / / // / / // ___// / / / / // // /\ // // / /__ * \___//____ \\___//____//_/ _\_ / /_//____//_/ /_/ /_//_//_/ /_/ \__\_\___/ - * \/ /____/ version 0.11.23 + * \/ /____/ version 1.11.4 * http://terminal.jcubic.pl * * This file is part of jQuery Terminal. * - * Copyright (c) 2011-2016 Jakub Jankiewicz + * Copyright (c) 2011-2018 Jakub Jankiewicz * Released under the MIT license * - * Date: Sun, 08 Jan 2017 11:44:40 +0000 + * Date: Sat, 27 Jan 2018 15:44:40 +0000 */ .terminal .terminal-output .format, .cmd .format, .cmd .prompt, .cmd .prompt div, .terminal .terminal-output div div{ @@ -36,100 +36,87 @@ position: absolute; left: -16px; top: 0; - width: 10px; + width: 20px; height: 16px; /* this seems to work after all on Android */ /*left: -99999px; clip: rect(1px,1px,1px,1px); /* on desktop textarea appear when paste */ - /* + /* opacity is needed for Edge and IE opacity: 0.01; filter: alpha(opacity = 0.01); - filter: progid:DXImageTransform.Microsoft.Alpha(opacity=0.01); - */ + filter: progid:DXImageTransform.Microsoft.Alpha(opacity=0.01);*/ background: transparent; border: none; color: transparent; outline: none; padding: 0; resize: none; - z-index: 0; + z-index: 1000; overflow: hidden; + white-space: pre; + text-indent: -9999em; /* better cursor hiding for Safari and IE */ +} +.terminal img, .terminal value, .terminal audio, .terminal object, .terminal canvas { + cursor: default; } .terminal .error { color: #f00; } .terminal { - padding: 10px; position: relative; /*overflow: hidden;*/ - overflow: auto; + overflow-y: auto; + overflow-x: hidden; +} +body.terminal { + height: 100vh; + margin: 0; +} +.terminal > div { + height: 100%; } .cmd { padding: 0; - height: 1.3em; position: relative; /*margin-top: 3px; */ + float: left; + padding-bottom: 3px; +} +.terminal a[tabindex="1000"], +.terminal a[tabindex="1000"]:active, +.terminal a[tabindex="1000"]:focus { + outline: none; } -.terminal .inverted, .cmd .inverted, .cmd .cursor.blink { +.terminal .inverted, .cmd .inverted { background-color: #aaa; color: #000; } +.cmd .cursor { + border-bottom: 3px solid transparent; + margin-bottom: -3px; + background-clip: content-box; +} .cmd .cursor.blink { -webkit-animation: terminal-blink 1s infinite steps(1, start); -moz-animation: terminal-blink 1s infinite steps(1, start); -ms-animation: terminal-blink 1s infinite steps(1, start); animation: terminal-blink 1s infinite steps(1, start); + border-left: 1px solid transparent; + margin-left: -1px; } -@-webkit-keyframes terminal-blink { - 0%, 100% { - background-color: #000; - color: #aaa; - } - 50% { - background-color: #bbb; - color: #000; - } -} - -@-ms-keyframes terminal-blink { - 0%, 100% { - background-color: #000; - color: #aaa; - } - 50% { - background-color: #bbb; - color: #000; - } -} - -@-moz-keyframes terminal-blink { - 0%, 100% { - background-color: #000; - color: #aaa; - } - 50% { - background-color: #bbb; - color: #000; - } -} -@keyframes terminal-blink { - 0%, 100% { - background-color: #000; - color: #aaa; - } - 50% { - background-color: #bbb; /* not #aaa because it's seems there is Google Chrome bug */ - color: #000; - } +.bar.terminal .inverted, .bar.cmd .inverted { + border-left-color: #aaa; } - .terminal .terminal-output div div, .cmd .prompt { display: block; line-height: 14px; height: auto; } -.cmd .prompt { +.terminal .terminal-output > div:not(.raw) div { + white-space: nowrap; +} +.cmd .prompt > span { float: left; } .terminal, .cmd { @@ -139,50 +126,43 @@ background-color: #000; font-size: 12px; line-height: 14px; + box-sizing: border-box; + cursor: text; +} +.cmd div { + clear: both; } -.terminal-output > div { - /*padding-top: 3px;*/ +.cmd .prompt + div { + clear: right; +} +.terminal-output > div > div { min-height: 14px; } -.terminal-output > div > div * { - word-wrap: break-word; /* when echo html */ +terminal .terminal-output > div { + margin-top: -1px; +} +.terminal-output > div.raw > div * { + overflow-wrap: break-word; + word-wrap: break-word; +} +.terminal .font { + position: absolute; + font-size: inherit; + width: 1em; + height: 1em; + top: -100%; + left: 0; + margin-bottom: 1px; } .terminal .terminal-output div span { display: inline-block; } -.cmd span { +.cmd > span:not(.prompt) { float: left; - /*display: inline-block; */ -} -/* fix double style of selecting text in terminal */ -.terminal-output span, .terminal-output a, .cmd div, .cmd span, .terminal td, -.terminal pre, .terminal h1, .terminal h2, .terminal h3, .terminal h4, -.terminal h5, .terminal h6 { - -webkit-touch-callout: initial; - -webkit-user-select: initial; - -khtml-user-select: initial; - -moz-user-select: initial; - -ms-user-select: initial; - user-select: initial; -} -.terminal, .terminal-output, .terminal-output div { - -webkit-touch-callout: none; - -webkit-user-select: none; - -khtml-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; -} -/* firefox hack */ -@-moz-document url-prefix() { - .terminal, .terminal-output, .terminal-output div { - -webkit-touch-callout: initial; - -webkit-user-select: initial; - -khtml-user-select: initial; - -moz-user-select: initial; - -ms-user-select: initial; - user-select: initial; - } +} +.cmd .prompt span.line { + display: block; + float: none; } .terminal table { border-collapse: collapse; @@ -201,8 +181,12 @@ .terminal .terminal-output div div::-moz-selection, .terminal .terminal-output div span::-moz-selection, .terminal .terminal-output div div a::-moz-selection, +.terminal .terminal-output .raw div::-moz-selection, .cmd div::-moz-selection, .cmd > span::-moz-selection, +.cmd > span span::-moz-selection, +.cmd > div::-moz-selection, +.cmd > div span::-moz-selection, .cmd .prompt span::-moz-selection { background-color: #aaa; color: #000; @@ -226,10 +210,18 @@ .terminal .terminal-output div div::selection, .terminal .terminal-output div div a::selection, .terminal .terminal-output div span::selection, +.terminal .terminal-output .raw div::selection, .cmd div::selection, .cmd > span::selection, +.cmd > span span::selection, +.cmd > div::selection, +.cmd > div span::selection, .cmd .prompt span::selection { - background-color: #aaa; + /* + * use rgba to fix transparent selection in chrome + * http://stackoverflow.com/questions/7224445/css3-selection-behaves-differently-in-ff-chrome + */ + background-color: rgba(170, 170, 170, 0.99); color: #000; } .terminal .terminal-output div.error, .terminal .terminal-output div.error div { @@ -242,12 +234,442 @@ width: 100%; z-index: 1100; } +.ui-dialog-content .terminal { + width: 100%; + height: 100%; + box-sizing: border-box; +} +.ui-dialog .ui-dialog-content.dterm { + padding: 0; +} .clear { clear: both; } .terminal a { color: #0F60FF; + color: var(--link-color, #0F60FF); } .terminal a:hover { - color: red; + background: #0F60FF; + background: var(--link-color, #0F60FF); + color: var(--background, #000); + text-decoration: none; +} +.terminal .terminal-fill { + position: absolute; + left: 0; + top: -100%; + width: 100%; + height: 100%; + margin: 1px 0 0; + border: none; + opacity: 0; + pointer-events: none; + box-sizing: border-box; +} +.terminal, .terminal .terminal-fill { + padding: 10px; +} +@-webkit-keyframes terminal-blink { + 0%, 100% { + background-color: #000; + color: #aaa; + } + 50% { + background-color: #bbb; + color: #000; + } +} + +@-ms-keyframes terminal-blink { + 0%, 100% { + background-color: #000; + color: #aaa; + } + 50% { + background-color: #bbb; + color: #000; + } +} + +@-moz-keyframes terminal-blink { + 0%, 100% { + background-color: #000; + color: #aaa; + } + 50% { + background-color: #bbb; + color: #000; + } +} +@keyframes terminal-blink { + 0%, 100% { + background-color: #000; + color: #aaa; + } + 50% { + background-color: #bbb; /* not #aaa because it's seems there is Google Chrome bug */ + color: #000; + } +} +@-webkit-keyframes terminal-bar { + 0%, 100% { + border-left-color: #aaa; + } + 50% { + border-left-color: #000; + } +} +@-ms-keyframes terminal-bar { + 0%, 100% { + border-left-color: #aaa; + } + 50% { + border-left-color: #000; + } +} +@-moz-keyframes terminal-bar { + 0%, 100% { + border-left-color: #aaa; + } + 50% { + border-left-color: #000; + } +} +@keyframes terminal-bar { + 0%, 100% { + border-left-color: #aaa; + } + 50% { + border-left-color: #000; + } +} +@-webkit-keyframes terminal-underline { + 0%, 100% { + border-bottom-color: #aaa; + position: relative; + line-height: 12px; + margin-top: 1px; + border-left: none; + margin-left: 0; + } + 50% { + border-bottom-color: #000; + position: relative; + line-height: 12px; + margin-top: 1px; + border-left: none; + margin-left: 0; + } +} +@-ms-keyframes terminal-underline { + 0%, 100% { + border-bottom-color: #aaa; + position: relative; + line-height: 12px; + margin-top: 1px; + border-left: none; + margin-left: 0; + } + 50% { + border-bottom-color: #000; + position: relative; + line-height: 12px; + margin-top: 1px; + border-left: none; + margin-left: 0; + } +} +@-moz-keyframes terminal-underline { + 0%, 100% { + border-bottom-color: #aaa; + position: relative; + line-height: 12px; + margin-top: 1px; + border-left: none; + margin-left: 0; + } + 50% { + border-bottom-color: #000; + position: relative; + line-height: 12px; + margin-top: 1px; + border-left: none; + margin-left: 0; + } +} +@keyframes terminal-underline { + 0%, 100% { + border-bottom-color: #aaa; + position: relative; + line-height: 12px; + margin-top: 1px; + border-left: none; + margin-left: 0; + } + 50% { + border-bottom-color: #000; + position: relative; + line-height: 12px; + margin-top: 1px; + border-left: none; + margin-left: 0; + } +} +/* shorthand classes for IE */ +.underline-animation .cursor.blink { + border-left: none; + -webkit-animation-name: terminal-underline; + -moz-animation-name: terminal-underline; + -ms-animation-name: terminal-underline; + animation-name: terminal-underline; +} +.bar-animation .cursor.blink { + -webkit-animation-name: terminal-bar; + -moz-animation-name: terminal-bar; + -ms-animation-name: terminal-bar; + animation-name: terminal-bar; +} +@supports (--css: variables) { + .terminal, .cmd { + color: var(--color, #aaa); + background-color: var(--background, #000); + } + .terminal .font { + width: calc(var(--size, 1) * 1em); + height: calc(var(--size, 1) * 1em); + } + .terminal span[style*="--length"] { + width: calc(var(--length, 1) * var(--char-width) * 1px); + display: inline-block; + } + .terminal, .cmd, .terminal .terminal-output > div > div, .cmd .prompt { + font-size: calc(var(--size, 1) * 12px); + line-height: calc(var(--size, 1) * 14px); + } + .terminal .terminal-output > div > div { + min-height: calc(var(--size, 1) * 14px); + } + .terminal .inverted, .cmd .inverted { + background-color: var(--color, #aaa); + color: var(--background, #000); + } + .cmd .cursor.blink { + -webkit-animation: var(--animation, terminal-blink) 1s infinite steps(1, start); + -moz-animation: var(--animation, terminal-blink) 1s infinite steps(1, start); + -ms-animation: var(--animation, terminal-blink) 1s infinite steps(1, start); + animation: var(--animation, terminal-blink) 1s infinite steps(1, start); + color: var(--color, #aaa); + background-color: var(--background, #000); + } + .terminal h1::-moz-selection, + .terminal h2::-moz-selection, + .terminal h3::-moz-selection, + .terminal h4::-moz-selection, + .terminal h5::-moz-selection, + .terminal h6::-moz-selection, + .terminal pre::-moz-selection, + .terminal td::-moz-selection, + .terminal .terminal-output div div::-moz-selection, + .terminal .terminal-output div span::-moz-selection, + .terminal .terminal-output div div a::-moz-selection, + .cmd div::-moz-selection, + .cmd > span::-moz-selection, + .cmd > span span::-moz-selection, + .cmd > div::-moz-selection, + .cmd > div span::-moz-selection, + .cmd .prompt span::-moz-selection { + background-color: var(--color, #aaa); + color: var(--background, #000); + } + .terminal h1::selection, + .terminal h2::selection, + .terminal h3::selection, + .terminal h4::selection, + .terminal h5::selection, + .terminal h6::selection, + .terminal pre::selection, + .terminal td::selection, + .terminal .terminal-output div div::selection, + .terminal .terminal-output div div a::selection, + .terminal .terminal-output div span::selection, + .cmd div::selection, + .cmd > span::selection, + .cmd > span span::selection, + .cmd > div::selection, + .cmd > div span::selection, + .cmd .prompt span::selection { + background-color: var(--color, rgba(170, 170, 170, 0.99)); + color: var(--background, #000); + } + @-webkit-keyframes terminal-blink { + 0%, 100% { + background-color: var(--background, #000); + color: var(--color, #aaa); + } + 50% { + background-color: var(--color, #aaa); + color: var(--background, #000); + } + } + + @-ms-keyframes terminal-blink { + 0%, 100% { + background-color: var(--background, #000); + color: var(--color, #aaa); + } + 50% { + background-color: var(--color, #aaa); + color: var(--background, #000); + } + } + @-moz-keyframes terminal-blink { + 0%, 100% { + background-color: var(--background, #000); + color: var(--color, #aaa); + } + 50% { + background-color: var(--color, #aaa); + color: var(--background, #000); + } + } + @keyframes terminal-blink { + 0%, 100% { + background-color: var(--background, #000); + color: var(--color, #aaa); + } + 50% { + background-color: var(--color, #aaa); + color: var(--background, #000); + } + } + @-webkit-keyframes terminal-bar { + 0%, 100% { + border-left-color: var(--background, #000); + } + 50% { + border-left-color: var(--color, #aaa); + } + } + @-ms-keyframes terminal-bar { + 0%, 100% { + border-left-color: var(--background, #000); + } + 50% { + border-left-color: var(--color, #aaa); + } + } + @-moz-keyframes terminal-bar { + 0%, 100% { + border-left-color: var(--background, #000); + } + 50% { + border-left-color: var(--color, #aaa); + } + } + @keyframes terminal-bar { + 0%, 100% { + border-left-color: var(--background, #000); + } + 50% { + border-left-color: var(--color, #aaa); + } + } + @-webkit-keyframes terminal-underline { + 0%, 100% { + border-bottom-color: var(--color, #aaa); + position: relative; + line-height: calc(var(--size, 1) * 12px); + margin-top: calc(var(--size, 1) * 1px); + border-left: none; + margin-left: 0; + } + 50% { + border-bottom-color: var(--background, #000); + position: relative; + line-height: calc(var(--size, 1) * 12px); + margin-top: calc(var(--size, 1) * 1px); + border-left: none; + margin-left: 0; + } + } + @-ms-keyframes terminal-underline { + 0%, 100% { + border-bottom-color: var(--background, #000); + position: relative; + line-height: calc(var(--size, 1) * 12px); + margin-top: calc(var(--size, 1) * 1px); + border-left: none; + margin-left: 0; + } + 50% { + border-bottom-color: var(--color, #aaa); + position: relative; + line-height: calc(var(--size, 1) * 12px); + margin-top: calc(var(--size, 1) * 1px); + border-left: none; + margin-left: 0; + } + } + @-moz-keyframes terminal-underline { + 0%, 100% { + border-bottom-color: var(--background, #000); + position: relative; + line-height: calc(var(--size, 1) * 12px); + margin-top: calc(var(--size, 1) * 1px); + border-left: none; + margin-left: 0; + } + 50% { + border-bottom-color: var(--color, #aaa); + position: relative; + line-height: calc(var(--size, 1) * 12px); + margin-top: calc(var(--size, 1) * 1px); + border-left: none; + margin-left: 0; + } + } + @keyframes terminal-underline { + 0%, 100% { + border-bottom-color: var(--background, #000); + position: relative; + line-height: calc(var(--size, 1) * 12px); + margin-top: calc(var(--size, 1) * 1px); + border-left: none; + margin-left: 0; + } + 50% { + border-bottom-color: var(--color, #aaa); + position: relative; + line-height: calc(var(--size, 1) * 12px); + margin-top: calc(var(--size, 1) * 1px); + border-left: none; + margin-left: 0; + } + } +} +/* + * overwrite css variables that don't work with selection in Edge + */ +@supports (-ms-ime-align:auto) { + .terminal h1::selection, + .terminal h2::selection, + .terminal h3::selection, + .terminal h4::selection, + .terminal h5::selection, + .terminal h6::selection, + .terminal pre::selection, + .terminal td::selection, + .terminal .terminal-output div div::selection, + .terminal .terminal-output div div a::selection, + .terminal .terminal-output div span::selection, + .cmd div::selection, + .cmd > span::selection, + .cmd > span span::selection, + .cmd > div::selection, + .cmd > div span::selection, + .cmd .prompt span::selection { + background-color: rgba(170, 170, 170, 0.99); + color: #000; + } } diff --git a/src/main/resources/static/css/jquery.terminal.min.css b/src/main/resources/static/css/jquery.terminal.min.css index 3609d45..6a30e85 100644 --- a/src/main/resources/static/css/jquery.terminal.min.css +++ b/src/main/resources/static/css/jquery.terminal.min.css @@ -4,13 +4,13 @@ * __ / // // // // // _ // _// // / / // _ // _// // // \/ // _ \/ / * / / // // // // // ___// / / // / / // ___// / / / / // // /\ // // / /__ * \___//____ \\___//____//_/ _\_ / /_//____//_/ /_/ /_//_//_/ /_/ \__\_\___/ - * \/ /____/ version 0.11.23 + * \/ /____/ version 1.11.4 * http://terminal.jcubic.pl * * This file is part of jQuery Terminal. * - * Copyright (c) 2011-2016 Jakub Jankiewicz + * Copyright (c) 2011-2018 Jakub Jankiewicz * Released under the MIT license * - * Date: Sun, 08 Jan 2017 11:44:40 +0000 - */.terminal .terminal-output .format,.cmd .format,.cmd .prompt,.cmd .prompt div,.terminal .terminal-output div div{display:inline-block}.terminal h1,.terminal h2,.terminal h3,.terminal h4,.terminal h5,.terminal h6,.terminal pre,.cmd{margin:0}.terminal h1,.terminal h2,.terminal h3,.terminal h4,.terminal h5,.terminal h6{line-height:1.2em}.cmd .clipboard{position:absolute;left:-16px;top:0;width:10px;height:16px;background:transparent;border:0;color:transparent;outline:0;padding:0;resize:none;z-index:0;overflow:hidden}.terminal .error{color:red}.terminal{padding:10px;position:relative;overflow:auto}.cmd{padding:0;height:1.3em;position:relative}.terminal .inverted,.cmd .inverted,.cmd .cursor.blink{background-color:#aaa;color:#000}.cmd .cursor.blink{-webkit-animation:terminal-blink 1s infinite steps(1,start);-moz-animation:terminal-blink 1s infinite steps(1,start);-ms-animation:terminal-blink 1s infinite steps(1,start);animation:terminal-blink 1s infinite steps(1,start)}@-webkit-keyframes terminal-blink{0%,100%{background-color:#000;color:#aaa}50%{background-color:#bbb;color:#000}}@-ms-keyframes terminal-blink{0%,100%{background-color:#000;color:#aaa}50%{background-color:#bbb;color:#000}}@-moz-keyframes terminal-blink{0%,100%{background-color:#000;color:#aaa}50%{background-color:#bbb;color:#000}}@keyframes terminal-blink{0%,100%{background-color:#000;color:#aaa}50%{background-color:#bbb;color:#000}}.terminal .terminal-output div div,.cmd .prompt{display:block;line-height:14px;height:auto}.cmd .prompt{float:left}.terminal,.cmd{font-family:monospace;color:#aaa;background-color:#000;font-size:12px;line-height:14px}.terminal-output>div{min-height:14px}.terminal-output>div>div *{word-wrap:break-word}.terminal .terminal-output div span{display:inline-block}.cmd span{float:left}.terminal-output span,.terminal-output a,.cmd div,.cmd span,.terminal td,.terminal pre,.terminal h1,.terminal h2,.terminal h3,.terminal h4,.terminal h5,.terminal h6{-webkit-touch-callout:initial;-webkit-user-select:initial;-khtml-user-select:initial;-moz-user-select:initial;-ms-user-select:initial;user-select:initial}.terminal,.terminal-output,.terminal-output div{-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}@-moz-document url-prefix(){.terminal,.terminal-output,.terminal-output div{-webkit-touch-callout:initial;-webkit-user-select:initial;-khtml-user-select:initial;-moz-user-select:initial;-ms-user-select:initial;user-select:initial}}.terminal table{border-collapse:collapse}.terminal td{border:1px solid #aaa}.terminal h1::-moz-selection,.terminal h2::-moz-selection,.terminal h3::-moz-selection,.terminal h4::-moz-selection,.terminal h5::-moz-selection,.terminal h6::-moz-selection,.terminal pre::-moz-selection,.terminal td::-moz-selection,.terminal .terminal-output div div::-moz-selection,.terminal .terminal-output div span::-moz-selection,.terminal .terminal-output div div a::-moz-selection,.cmd div::-moz-selection,.cmd>span::-moz-selection,.cmd .prompt span::-moz-selection{background-color:#aaa;color:#000}.terminal h1::selection,.terminal h2::selection,.terminal h3::selection,.terminal h4::selection,.terminal h5::selection,.terminal h6::selection,.terminal pre::selection,.terminal td::selection,.terminal .terminal-output div div::selection,.terminal .terminal-output div div a::selection,.terminal .terminal-output div span::selection,.cmd div::selection,.cmd>span::selection,.cmd .prompt span::selection{background-color:#aaa;color:#000}.terminal .terminal-output div.error,.terminal .terminal-output div.error div{color:red}.tilda{position:fixed;top:0;left:0;width:100%;z-index:1100}.clear{clear:both}.terminal a{color:#0f60ff}.terminal a:hover{color:red} \ No newline at end of file + * Date: Sat, 27 Jan 2018 15:44:40 +0000 + */.cmd .format,.cmd .prompt,.cmd .prompt div,.terminal .terminal-output .format,.terminal .terminal-output div div{display:inline-block}.cmd,.terminal h1,.terminal h2,.terminal h3,.terminal h4,.terminal h5,.terminal h6,.terminal pre{margin:0}.terminal h1,.terminal h2,.terminal h3,.terminal h4,.terminal h5,.terminal h6{line-height:1.2em}.cmd .clipboard{position:absolute;left:-16px;top:0;width:20px;height:16px;background:transparent;border:none;color:transparent;outline:none;padding:0;resize:none;z-index:1;overflow:hidden;white-space:pre;text-indent:-9999em}.terminal audio,.terminal canvas,.terminal img,.terminal object,.terminal value{cursor:default}.terminal .error{color:red}.terminal{position:relative;overflow-y:auto;overflow-x:hidden}body.terminal{height:100vh;margin:0}.terminal>div{height:100%}.cmd{padding:0;position:relative;float:left;padding-bottom:3px}.terminal a[tabindex="1000"],.terminal a[tabindex="1000"]:active,.terminal a[tabindex="1000"]:focus{outline:none}.cmd .inverted,.terminal .inverted{background-color:#aaa;color:#000}.cmd .cursor{border-bottom:3px solid transparent;margin-bottom:-3px;background-clip:content-box}.cmd .cursor.blink{-webkit-animation:a 1s infinite step-start;animation:a 1s infinite step-start;border-left:1px solid transparent;margin-left:-1px}.bar.cmd .inverted,.bar.terminal .inverted{border-left-color:#aaa}.cmd .prompt,.terminal .terminal-output div div{display:block;line-height:14px;height:auto}.terminal .terminal-output>div:not(.raw) div{white-space:nowrap}.cmd .prompt>span{float:left}.cmd,.terminal{font-family:monospace;color:#aaa;background-color:#000;font-size:12px;line-height:14px;box-sizing:border-box;cursor:text}.cmd div{clear:both}.cmd .prompt+div{clear:right}.terminal-output>div>div{min-height:14px}terminal .terminal-output>div{margin-top:-1px}.terminal-output>div.raw>div *{overflow-wrap:break-word;word-wrap:break-word}.terminal .font{position:absolute;font-size:inherit;width:1em;height:1em;top:-100%;left:0;margin-bottom:1px}.terminal .terminal-output div span{display:inline-block}.cmd>span:not(.prompt){float:left}.cmd .prompt span.line{display:block;float:none}.terminal table{border-collapse:collapse}.terminal td{border:1px solid #aaa}.cmd .prompt span::-moz-selection,.cmd>div::-moz-selection,.cmd>div span::-moz-selection,.cmd>span::-moz-selection,.cmd>span span::-moz-selection,.cmd div::-moz-selection,.terminal .terminal-output .raw div::-moz-selection,.terminal .terminal-output div div::-moz-selection,.terminal .terminal-output div div a::-moz-selection,.terminal .terminal-output div span::-moz-selection,.terminal h1::-moz-selection,.terminal h2::-moz-selection,.terminal h3::-moz-selection,.terminal h4::-moz-selection,.terminal h5::-moz-selection,.terminal h6::-moz-selection,.terminal pre::-moz-selection,.terminal td::-moz-selection{background-color:#aaa;color:#000}.cmd .prompt span::selection,.cmd>div::selection,.cmd>div span::selection,.cmd>span::selection,.cmd>span span::selection,.cmd div::selection,.terminal .terminal-output .raw div::selection,.terminal .terminal-output div div::selection,.terminal .terminal-output div div a::selection,.terminal .terminal-output div span::selection,.terminal h1::selection,.terminal h2::selection,.terminal h3::selection,.terminal h4::selection,.terminal h5::selection,.terminal h6::selection,.terminal pre::selection,.terminal td::selection{background-color:hsla(0,0%,67%,.99);color:#000}.terminal .terminal-output div.error,.terminal .terminal-output div.error div{color:red}.tilda{position:fixed;top:0;left:0;width:100%;z-index:2}.ui-dialog-content .terminal{width:100%;height:100%;box-sizing:border-box}.ui-dialog .ui-dialog-content.dterm{padding:0}.clear{clear:both}.terminal a{color:#0f60ff;color:var(--link-color,#0f60ff)}.terminal a:hover{background:#0f60ff;background:var(--link-color,#0f60ff);color:var(--background,#000);text-decoration:none}.terminal .terminal-fill{position:absolute;left:0;top:-100%;width:100%;height:100%;margin:1px 0 0;border:none;opacity:0;pointer-events:none;box-sizing:border-box}.terminal,.terminal .terminal-fill{padding:10px}@-webkit-keyframes a{0%,to{background-color:#000;color:#aaa}50%{background-color:#bbb;color:#000}}@keyframes a{0%,to{background-color:#000;color:#aaa}50%{background-color:#bbb;color:#000}}@-webkit-keyframes b{0%,to{border-left-color:#aaa}50%{border-left-color:#000}}@keyframes b{0%,to{border-left-color:#aaa}50%{border-left-color:#000}}@-webkit-keyframes c{0%,to{border-bottom-color:#aaa;position:relative;line-height:12px;margin-top:1px;border-left:none;margin-left:0}50%{border-bottom-color:#000;position:relative;line-height:12px;margin-top:1px;border-left:none;margin-left:0}}@keyframes c{0%,to{border-bottom-color:#aaa;position:relative;line-height:12px;margin-top:1px;border-left:none;margin-left:0}50%{border-bottom-color:#000;position:relative;line-height:12px;margin-top:1px;border-left:none;margin-left:0}}.underline-animation .cursor.blink{border-left:none;-webkit-animation-name:c;animation-name:c}.bar-animation .cursor.blink{-webkit-animation-name:b;animation-name:b}@supports (--css:variables){.cmd,.terminal{color:var(--color,#aaa);background-color:var(--background,#000)}.terminal .font{width:calc(var(--size, 1) * 1em);height:calc(var(--size, 1) * 1em)}.terminal span[style*="--length"]{width:calc(var(--length, 1) * var(--char-width) * 1px);display:inline-block}.cmd,.cmd .prompt,.terminal,.terminal .terminal-output>div>div{font-size:calc(var(--size, 1) * 12px);line-height:calc(var(--size, 1) * 14px)}.terminal .terminal-output>div>div{min-height:calc(var(--size, 1) * 14px)}.cmd .inverted,.terminal .inverted{background-color:var(--color,#aaa);color:var(--background,#000)}.cmd .cursor.blink{-webkit-animation:var(--animation,a) 1s infinite step-start;animation:var(--animation,a) 1s infinite step-start;color:var(--color,#aaa);background-color:var(--background,#000)}.cmd .prompt span::-moz-selection,.cmd>div::-moz-selection,.cmd>div span::-moz-selection,.cmd>span::-moz-selection,.cmd>span span::-moz-selection,.cmd div::-moz-selection,.terminal .terminal-output div div::-moz-selection,.terminal .terminal-output div div a::-moz-selection,.terminal .terminal-output div span::-moz-selection,.terminal h1::-moz-selection,.terminal h2::-moz-selection,.terminal h3::-moz-selection,.terminal h4::-moz-selection,.terminal h5::-moz-selection,.terminal h6::-moz-selection,.terminal pre::-moz-selection,.terminal td::-moz-selection{background-color:var(--color,#aaa);color:var(--background,#000)}.cmd .prompt span::selection,.cmd>div::selection,.cmd>div span::selection,.cmd>span::selection,.cmd>span span::selection,.cmd div::selection,.terminal .terminal-output div div::selection,.terminal .terminal-output div div a::selection,.terminal .terminal-output div span::selection,.terminal h1::selection,.terminal h2::selection,.terminal h3::selection,.terminal h4::selection,.terminal h5::selection,.terminal h6::selection,.terminal pre::selection,.terminal td::selection{background-color:var(--color,hsla(0,0%,67%,.99));color:var(--background,#000)}@-webkit-keyframes a{0%,to{background-color:var(--background,#000);color:var(--color,#aaa)}50%{background-color:var(--color,#aaa);color:var(--background,#000)}}@keyframes a{0%,to{background-color:var(--background,#000);color:var(--color,#aaa)}50%{background-color:var(--color,#aaa);color:var(--background,#000)}}@-webkit-keyframes b{0%,to{border-left-color:var(--background,#000)}50%{border-left-color:var(--color,#aaa)}}@keyframes b{0%,to{border-left-color:var(--background,#000)}50%{border-left-color:var(--color,#aaa)}}@-webkit-keyframes c{0%,to{border-bottom-color:var(--color,#aaa);position:relative;line-height:calc(var(--size, 1) * 12px);margin-top:calc(var(--size, 1) * 1px);border-left:none;margin-left:0}50%{border-bottom-color:var(--background,#000);position:relative;line-height:calc(var(--size, 1) * 12px);margin-top:calc(var(--size, 1) * 1px);border-left:none;margin-left:0}}@keyframes c{0%,to{border-bottom-color:var(--background,#000);position:relative;line-height:calc(var(--size, 1) * 12px);margin-top:calc(var(--size, 1) * 1px);border-left:none;margin-left:0}50%{border-bottom-color:var(--color,#aaa);position:relative;line-height:calc(var(--size, 1) * 12px);margin-top:calc(var(--size, 1) * 1px);border-left:none;margin-left:0}}}@supports (-ms-ime-align:auto){.cmd .prompt span::selection,.cmd>div::selection,.cmd>div span::selection,.cmd>span::selection,.cmd>span span::selection,.cmd div::selection,.terminal .terminal-output div div::selection,.terminal .terminal-output div div a::selection,.terminal .terminal-output div span::selection,.terminal h1::selection,.terminal h2::selection,.terminal h3::selection,.terminal h4::selection,.terminal h5::selection,.terminal h6::selection,.terminal pre::selection,.terminal td::selection{background-color:hsla(0,0%,67%,.99);color:#000}} \ No newline at end of file diff --git a/src/main/resources/static/js/jquery.terminal.js b/src/main/resources/static/js/jquery.terminal.js index a00b175..a352d81 100644 --- a/src/main/resources/static/js/jquery.terminal.js +++ b/src/main/resources/static/js/jquery.terminal.js @@ -4,16 +4,17 @@ * __ / // // // // // _ // _// // / / // _ // _// // // \/ // _ \/ / * / / // // // // // ___// / / // / / // ___// / / / / // // /\ // // / /__ * \___//____ \\___//____//_/ _\_ / /_//____//_/ /_/ /_//_//_/ /_/ \__\_\___/ - * \/ /____/ version 0.11.23 + * \/ /____/ version 1.11.4 * * This file is part of jQuery Terminal. http://terminal.jcubic.pl * - * Copyright (c) 2010-2016 Jakub Jankiewicz + * Copyright (c) 2010-2018 Jakub Jankiewicz * Released under the MIT license * * Contains: * * Storage plugin Distributed under the MIT License + * modified to work from Data URIs that block storage and cookies in Chrome * Copyright (c) 2010 Dave Schindler * * jQuery Timers licenced with the WTFPL @@ -31,7 +32,7 @@ * Copyright (c) 2007-2013 Alexandru Marasteanu * licensed under 3 clause BSD license * - * Date: Sun, 08 Jan 2017 11:44:38 +0000 + * Date: Sat, 27 Jan 2018 15:44:36 +0000 */ /* TODO: @@ -47,8 +48,10 @@ * NOTE: json-rpc don't need promises and delegate resume/pause because only * exec can call it and exec call interpreter that work with resume/pause */ - -/* jshint ignore:start */ +/* global location, jQuery, setTimeout, window, global, localStorage, sprintf, + setImmediate, IntersectionObserver, MutationObserver, ResizeObserver, + wcwidth, module, require, define */ +/* eslint-disable */ (function(ctx) { var sprintf = function() { if (!sprintf.cache.hasOwnProperty(arguments[0])) { @@ -82,7 +85,7 @@ arg = argv[cursor++]; } - if (/[^s]/.test(match[8]) && (get_type(arg) != 'number')) { + if (/[^s]/.test(match[8]) && (get_type(arg) !== 'number')) { throw(sprintf('[sprintf] expecting number but found %s', get_type(arg))); } switch (match[8]) { @@ -97,8 +100,8 @@ case 'x': arg = arg.toString(16); break; case 'X': arg = arg.toString(16).toUpperCase(); break; } - arg = (/[def]/.test(match[8]) && match[3] && arg >= 0 ? '+'+ arg : arg); - pad_character = match[4] ? match[4] == '0' ? '0' : match[4].charAt(1) : ' '; + arg = (/[def]/.test(match[8]) && match[3] && arg >= 0 ? ' +' + arg : arg); + pad_character = match[4] ? match[4] === '0' ? '0' : match[4].charAt(1) : ' '; pad_length = match[6] - String(arg).length; pad = match[6] ? str_repeat(pad_character, pad_length) : ''; output.push(match[5] ? arg + pad : pad + arg); @@ -180,10 +183,55 @@ */ ctx.sprintf = sprintf; ctx.vsprintf = vsprintf; -})(typeof global != "undefined" ? global : window); -/* jshint ignore:end */ -(function($, undefined) { - "use strict"; +})(typeof global !== "undefined" ? global : window); +/* eslint-enable */ +// UMD taken from https://github.com/umdjs/umd +(function(factory) { + if (typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module. + define(['jquery'], factory); + } else if (typeof module === 'object' && module.exports) { + // Node/CommonJS + module.exports = function(root, jQuery) { + if (jQuery === undefined) { + // require('jQuery') returns a factory that requires window to + // build a jQuery instance, we normalize how we use modules + // that require this pattern but the window provided is a noop + // if it's defined (how jquery works) + if (typeof window !== 'undefined') { + jQuery = require('jquery'); + } + else { + jQuery = require('jquery')(root); + } + } + factory(jQuery); + return jQuery; + }; + } else { + // Browser globals + factory(jQuery); + } +})(function($, undefined) { + 'use strict'; + // ----------------------------------------------------------------------- + // :: Replacemenet for jQuery 2 deferred objects + // ----------------------------------------------------------------------- + function DelayQueue() { + var callbacks = $.Callbacks(); + var resolved = false; + this.resolve = function() { + callbacks.fire(); + resolved = true; + }; + this.add = function(fn) { + if (resolved) { + fn(); + } else { + callbacks.add(fn); + } + }; + } // ----------------------------------------------------------------------- // :: map object to object // ----------------------------------------------------------------------- @@ -194,10 +242,20 @@ }); return result; }; + $.fn.text_length = function() { + return this.map(function() { + return $(this).text().length; + }).get().reduce(function(a, b) { + return a + b; + }, 0); + }; + // ----------------------------------------------------------------------- + // :: Deep clone of objects and arrays + // ----------------------------------------------------------------------- var Clone = { clone_object: function(object) { var tmp = {}; - if (typeof object == 'object') { + if (typeof object === 'object') { if ($.isArray(object)) { return this.clone_array(object); } else if (object === null) { @@ -206,7 +264,7 @@ for (var key in object) { if ($.isArray(object[key])) { tmp[key] = this.clone_array(object[key]); - } else if (typeof object[key] == 'object') { + } else if (typeof object[key] === 'object') { tmp[key] = this.clone_object(object[key]); } else { tmp[key] = object[key]; @@ -218,11 +276,11 @@ }, clone_array: function(array) { if (!$.isFunction(Array.prototype.map)) { - throw new Error("You'r browser don't support ES5 array map " + - "use es5-shim"); + throw new Error("Your browser don't support ES5 array map " + + 'use es5-shim'); } return array.slice(0).map(function(item) { - if (typeof item == 'object') { + if (typeof item === 'object') { return this.clone_object(item); } else { return item; @@ -234,21 +292,28 @@ return Clone.clone_object(object); }; - var hasLS = function () { - var testKey = 'test', storage = window.localStorage; - try { - storage.setItem(testKey, '1'); - storage.removeItem(testKey); - return true; - } catch (error) { - return false; - } - }; - - /* jshint ignore:start */ + /* eslint-disable */ // ----------------------------------------------------------------------- // :: Storage plugin // ----------------------------------------------------------------------- + var hasLS = function() { + try { + var testKey = 'test', storage = window.localStorage; + storage.setItem(testKey, '1'); + storage.removeItem(testKey); + return true; + } catch (error) { + return false; + } + }; + var hasCookies = function() { + try { + document.cookie.split(';'); + return true; + } catch (e) { + return false; + } + }; // Private data var isLS = hasLS(); // Private functions @@ -316,13 +381,28 @@ * $.Storage.get("name") * $.Storage.remove("name") */ - $.extend({ - Storage: { - set: isLS ? wls : wc, - get: isLS ? rls : rc, - remove: isLS ? dls : dc + var localStorage; + if (!hasCookies() && !isLS) { + localStorage = {}; + $.extend({ + Storage: { + set: wls, + get: rls, + remove: dls + } + }); + } else { + if (isLS) { + localStorage = window.localStorage; } - }); + $.extend({ + Storage: { + set: isLS ? wls : wc, + get: isLS ? rls : rc, + remove: isLS ? dls : dc + } + }); + } // ----------------------------------------------------------------------- // :: jQuery Timers // ----------------------------------------------------------------------- @@ -480,9 +560,8 @@ } } }); - if (/(msie) ([\w.]+)/.exec(navigator.userAgent.toLowerCase())) { - jQuery(window).one('unload', function() { + $(window).one('unload', function() { var global = jQuery.timer.global; for (var label in global) { if (global.hasOwnProperty(label)) { @@ -509,7 +588,7 @@ compliantExecNpcg = /()??/.exec("")[1] === undef, // NPCG: nonparticipating capturing group self; - self = function (str, separator, limit) { + self = function(str, separator, limit) { // If `separator` is not a regex, use `nativeSplit` if (Object.prototype.toString.call(separator) !== "[object RegExp]") { return nativeSplit.call(str, separator, limit); @@ -545,7 +624,7 @@ // Fix browsers whose `exec` methods don't consistently return `undefined` for // nonparticipating capturing groups if (!compliantExecNpcg && match.length > 1) { - match[0].replace(separator2, function () { + match[0].replace(separator2, function() { for (var i = 1; i < arguments.length - 2; i++) { if (arguments[i] === undef) { match[i] = undef; @@ -577,7 +656,7 @@ }; // For convenience - String.prototype.split = function (separator, limit) { + String.prototype.split = function(separator, limit) { return self(this, separator, limit); }; @@ -591,7 +670,7 @@ var target = this[0]; var isContentEditable = target.contentEditable === 'true'; //get - if (arguments.length == 0) { + if (arguments.length === 0) { //HTML5 if (window.getSelection) { //contenteditable @@ -630,7 +709,7 @@ return 0; } //set - if (pos == -1) + if (pos === -1) pos = this[isContentEditable? 'text' : 'val']().length; //HTML5 if (window.getSelection) { @@ -651,40 +730,201 @@ range.collapse(true); range.select(); } - if (!isContentEditable) + if (!isContentEditable && !this.is(':focus')) { target.focus(); + } return pos; }; - /* jshint ignore:end */ + /* eslint-enable */ + var requestAnimationFrame = + window.requestAnimationFrame || + window.mozRequestAnimationFrame || + window.webkitRequestAnimationFrame || + function(fn) { + return setTimeout(fn, 20); + }; // ----------------------------------------------------------------------- - // :: Split string to array of strings with the same length + // :: Cross-browser resize element plugin + // :: Taken from ResizeSensor.js file from marcj/css-element-queries (MIT license) + // :: not all jQuerifided // ----------------------------------------------------------------------- - function str_parts(str, length) { - var result = []; - var len = str.length; - if (len < length) { - return [str]; - } else if (length < 0) { - throw new Error('str_parts: length can\'t be negative'); // ' + $.fn.resizer = function(callback) { + var unbind = arguments[0] === "unbind"; + if (!unbind && !$.isFunction(callback)) { + throw new Error( + 'Invalid argument, it need to a function or string "unbind".' + ); } - for (var i = 0; i < len; i += length) { - result.push(str.substring(i, i + length)); + if (unbind) { + callback = $.isFunction(arguments[1]) ? arguments[1] : null; + } + return this.each(function() { + var $this = $(this); + var callbacks; + if (unbind) { + callbacks = $this.data('callbacks'); + if (callback && callbacks) { + callbacks.remove(callback); + if (!callbacks.has()) { + callbacks = null; + } + } else { + callbacks = null; + } + if (!callbacks) { + $this.removeData('callbacks'); + if (window.ResizeObserver) { + var observer = $this.data('observer'); + if (observer) { + observer.unobserve(this); + $this.removeData('observer'); + } + } else { + $this.find('.resizer').remove(); + } + } + } else if ($this.data('callbacks')) { + $(this).data('callbacks').add(callback); + } else { + callbacks = $.Callbacks(); + callbacks.add(callback); + $this.data('callbacks', callbacks); + var resizer; + var first = true; + if (window.ResizeObserver) { + resizer = new ResizeObserver(function() { + if (!first) { + var callbacks = $this.data('callbacks'); + callbacks.fire(); + } + first = false; + }); + resizer.observe(this); + $this.data('observer', resizer); + return; + } + var self = this; + resizer = $('
').addClass('resizer').appendTo(this)[0]; + var style = + 'position: absolute; left: 0; top: 0; right: 0; bottom: 0; ' + + 'overflow: hidden; z-index: -1; visibility: hidden;'; + var styleChild = 'position: absolute; left: 0; top: 0; transition: 0s;'; + resizer.style.cssText = style; + resizer.innerHTML = + '
' + + '
' + "
" + + '
' + + '
' + + "
"; + + var expand = resizer.childNodes[0]; + var expandChild = expand.childNodes[0]; + var shrink = resizer.childNodes[1]; + var dirty, rafId, newWidth, newHeight; + var lastWidth = self.offsetWidth; + var lastHeight = self.offsetHeight; + + var reset = function() { + expandChild.style.width = '100000px'; + expandChild.style.height = '100000px'; + + expand.scrollLeft = 100000; + expand.scrollTop = 100000; + + shrink.scrollLeft = 100000; + shrink.scrollTop = 100000; + }; + + reset(); + + var onResized = function() { + rafId = 0; + + if (!dirty) { + return; + } + + lastWidth = newWidth; + lastHeight = newHeight; + callbacks.fire(); + }; + + var onScroll = function() { + newWidth = self.offsetWidth; + newHeight = self.offsetHeight; + dirty = newWidth !== lastWidth || newHeight !== lastHeight; + + if (dirty && !rafId) { + rafId = requestAnimationFrame(onResized); + } + + reset(); + }; + $(expand).on("scroll", onScroll); + $(shrink).on("scroll", onScroll); + } + }); + }; + // ----------------------------------------------------------------------- + // :: hide elements from screen readers + // ----------------------------------------------------------------------- + function a11y_hide(element) { + element.attr({ + role: 'presentation', + 'aria-hidden': 'true' + }); + } + // --------------------------------------------------------------------- + // :: alert only first exception of type + // --------------------------------------------------------------------- + var excepctions = []; + function alert_exception(label, e) { + var message = (label ? label + ': ' : '') + exception_message(e); + if (excepctions.indexOf(message) === -1) { + excepctions.push(message); + alert(message + (e.stack ? '\n' + e.stack : '')); + } + } + // --------------------------------------------------------------------- + // :; detect if mouse event happen on scrollbar + // --------------------------------------------------------------------- + function scrollbar_event(e, node) { + var left = node.offset().left; + return node.outerWidth() <= e.clientX - left; + } + // --------------------------------------------------------------------- + // :: Return exception message as string + // --------------------------------------------------------------------- + function exception_message(e) { + if (typeof e === 'string') { + return e; + } else if (typeof e.fileName === 'string') { + return e.fileName + ': ' + e.message; + } else { + return e.message; } - return result; } // ----------------------------------------------------------------------- // :: CYCLE DATA STRUCTURE // ----------------------------------------------------------------------- - function Cycle(init) { - var data = init ? [init] : []; + function Cycle() { + var data = [].slice.call(arguments); var pos = 0; $.extend(this, { get: function() { return data; }, - rotate: function() { - if (!data.filter(Boolean).length) { - return; + index: function() { + return pos; + }, + rotate: function(skip) { + if (!skip) { + var defined = data.filter(function(item) { + return typeof item !== 'undefined'; + }); + if (!defined.length) { + return; + } } if (data.length === 1) { return data[0]; @@ -694,10 +934,10 @@ } else { ++pos; } - if (data[pos]) { + if (typeof data[pos] !== 'undefined') { return data[pos]; } else { - return this.rotate(); + return this.rotate(true); } } }, @@ -715,6 +955,7 @@ } } this.append(item); + pos = data.length - 1; }, front: function() { if (data.length) { @@ -733,6 +974,12 @@ return data[index]; } }, + map: function(fn) { + return data.filter(Boolean).map(fn); + }, + forEach: function(fn) { + data.filter(Boolean).forEach(fn); + }, append: function(item) { data.push(item); } @@ -789,35 +1036,43 @@ data = []; } else { data = $.Storage.get(storage_key); - data = data ? $.parseJSON(data) : []; + data = data ? JSON.parse(data) : []; } - var pos = data.length-1; + var pos = data.length - 1; $.extend(this, { append: function(item) { if (enabled) { - if (data[data.length-1] !== item) { + if (data[data.length - 1] !== item) { data.push(item); if (size && data.length > size) { data = data.slice(-size); } - pos = data.length-1; + pos = data.length - 1; if (!memory) { $.Storage.set(storage_key, JSON.stringify(data)); } } } }, + set: function(new_data) { + if (new_data instanceof Array) { + data = new_data; + if (!memory) { + $.Storage.set(storage_key, JSON.stringify(data)); + } + } + }, data: function() { return data; }, reset: function() { - pos = data.length-1; + pos = data.length - 1; }, last: function() { - return data[data.length-1]; + return data[data.length - 1]; }, end: function() { - return pos === data.length-1; + return pos === data.length - 1; }, position: function() { return pos; @@ -826,10 +1081,11 @@ return data[pos]; }, next: function() { - if (pos < data.length-1) { + var old = pos; + if (pos < data.length - 1) { ++pos; } - if (pos !== -1) { + if (old !== pos) { return data[pos]; } }, @@ -838,7 +1094,7 @@ if (pos > 0) { --pos; } - if (old !== -1) { + if (old !== pos) { return data[pos]; } }, @@ -862,35 +1118,35 @@ } }); } - // ----------------------------------------------------------------------- - var is_paste_supported = (function() { - var el = document.createElement('div'); - el.setAttribute('onpaste', 'return;'); - return typeof el.onpaste == "function"; - })(); - var first_cmd = true; // ------------------------------------------------------------------------- // :: COMMAND LINE PLUGIN // ------------------------------------------------------------------------- + var cmd_index = 0; $.fn.cmd = function(options) { var self = this; var maybe_data = self.data('cmd'); if (maybe_data) { return maybe_data; } + var id = cmd_index++; self.addClass('cmd'); - self.append('' + - ' '); + self.append(''); + self.append('
' + + '' + + ' ' + + '' + + '
'); + // a11y: don't read command it's in textarea that's in focus + a11y_hide(self.find('.cursor-line')); // on mobile the only way to hide textarea on desktop it's needed because // textarea show up after focus //self.append(''); var clip = $('