Minor webclient enhancements

- Fixed window resize bug
- Improved history handling to be less destructive to text the user has
entered
- Made input area automatically resize to fit its contents
This commit is contained in:
NatePri 2016-04-10 04:58:01 -07:00 committed by Griatch
parent de177398aa
commit 2134d6dd4a
4 changed files with 138 additions and 47 deletions

View file

@ -8,7 +8,7 @@
--- */
/* Overall element look */
html, body { height: 100% }
html, body, #clientwrapper { height: 100% }
body {
margin: 0;
padding: 0;
@ -94,31 +94,54 @@ div {margin:0px;}
/* Main scrolling message area */
#messagewindow {
position: relative;
height: 90%;
position: absolute;
overflow: auto;
padding: 1em;
box-sizing: border-box;
top: 0;
left: 0;
right: 0;
bottom: 70px;
}
/* Input area containing input field and button */
#inputform {
position: absolute;
width: 100%;
padding: .8em 0;
bottom: -50px;
padding: 0;
bottom: 0;
margin: 0;
padding-bottom: 10px;
border-top: 1px solid #555;
}
#inputcontrol {
padding: 0 .8em;
overflow: auto
width: 100%;
padding: 0;
}
/* Input field */
#inputfield, #inputsend, #inputsizer {
display: block;
box-sizing: border-box;
min-height: 50px;
background: #000;
color: #fff;
padding: 0 .45em;
font-size: 1.1em;
font-family: 'DejaVu Sans Mono', Consolas, Inconsolata, 'Lucida Console', monospace;
}
#inputsizer {
margin-left: -9999px;
line-height: normal;
}
#inputfield {
float: left;
width: 93%;
height: 40px;
margin-right: .5em
width: 95%;
border: 0;
resize: none;
}
#inputfield:focus {
@ -127,27 +150,23 @@ div {margin:0px;}
/* Input 'send' button */
#inputsend {
float: left;
width: 4%
}
#inputfield, #inputsend {
height: 40px;
border: 1px solid #555;
background: #000;
color: #fff;
padding: .4em .45em;
font-size: 1.1em;
font-family: 'DejaVu Sans Mono', Consolas, Inconsolata, 'Lucida Console', monospace;
float: right;
width: 3%;
max-width: 25px;
margin-right: 10px;
border: 0;
background: #555;
}
/* prompt area above input field */
#prompt {
margin-top: .8em;
margin-top: 10px;
}
/* No javascript warning */
#connecting {
position: absolute;
width: 100%;
padding: .5em .9em
}

View file

@ -25,29 +25,46 @@ var input_history = function() {
history[0] = ''; // the very latest input is empty for new entry.
var back = function () {
var back = function (scratchInput) {
// step backwards in history stack
history_pos = Math.min(++history_pos, history.length - 1);
return history[history.length - 1 - history_pos];
};
var fwd = function () {
var fwd = function (scratchInput) {
// step forwards in history stack
history_pos = Math.max(--history_pos, 0);
return history[history.length -1 - history_pos];
return history[history.length - 1 - history_pos];
};
var add = function (input) {
// add a new entry to history, don't repeat latest
if (input && input != history[history.length-1]) {
if (input && input != history[history.length-2]) {
if (history.length >= history_max) {
history.shift(); // kill oldest entry
}
history[history.length-1] = input;
history[history.length] = '';
};
// reset the position to the last history entry
history_pos = 0;
};
var end = function () {
// move to the end of the history stack
history_pos = 0;
return history[history.length -1];
}
var scratch = function (input) {
// Put the input into the last history entry (which is normally empty)
// without making the array larger as with add.
// Allows for in-progress editing to be saved.
history[history.length-1] = input;
}
return {back: back,
fwd: fwd,
add: add}
add: add,
end: end,
scratch: scratch}
}();
//
@ -57,6 +74,7 @@ var input_history = function() {
// Grab text from inputline and send to Evennia
function doSendText() {
inputfield = $("#inputfield");
isInputDirty = false;
var outtext = inputfield.val();
if (outtext.length > 7 && outtext.substr(0, 7) == "##send ") {
// send a specific oob instruction
@ -76,29 +94,84 @@ function doSendText() {
// catch all keyboard input, handle special chars
function onKeydown (event) {
var code = event.which;
var history_entry = null;
inputfield = $("#inputfield");
inputfield.focus();
if (code === 13) { // Enter key sends text
doSendText();
event.preventDefault();
}
else if (code === 38) { // Arrow up
inputfield.val(input_history.back());
}
else if (inputfield[0].selectionStart == inputfield.val().length) {
// Only process up/down arrow if cursor is at the end of the line.
if (code === 38) { // Arrow up
history_entry = input_history.back();
}
else if (code === 40) { // Arrow down
history_entry = input_history.fwd();
}
}
if (history_entry !== null) {
// Doing a history navigation; replace the text in the input.
inputfield.val(history_entry);
event.preventDefault();
}
else if (code === 40) { // Arrow down
inputfield.val(input_history.fwd());
event.preventDefault();
else {
// Save the current contents of the input to the history scratch area.
setTimeout(function () {
// Need to wait until after the key-up to capture the value.
input_history.scratch(inputfield.val());
input_history.end();
}, 0);
}
};
var resizeInputField = function () {
var min_height = 50;
var max_height = 300;
var prev_text_len = 0;
// Check to see if we should change the height of the input area
return function () {
inputfield = $("#inputfield");
var scrollh = inputfield.prop("scrollHeight");
var clienth = inputfield.prop("clientHeight");
var newh = 0;
var curr_text_len = inputfield.val().length;
if (scrollh > clienth && scrollh <= max_height) {
// Need to make it bigger
newh = scrollh;
}
else if (curr_text_len < prev_text_len) {
// There is less text in the field; try to make it smaller
// To avoid repaints, we draw the text in an offscreen element and
// determine its dimensions.
var sizer = $('#inputsizer')
.css("width", inputfield.prop("clientWidth"))
.text(inputfield.val());
newh = sizer.prop("scrollHeight");
}
if (newh != 0) {
newh = Math.min(newh, max_height);
if (clienth != newh) {
inputfield.css("height", newh + "px");
doWindowResize();
}
}
prev_text_len = curr_text_len;
}
}();
// Handle resizing of client
function doWindowResize() {
var winh = $(document).height();
var formh = $('#inputform').outerHeight(true);
$("#messagewindow").css({'height': winh - formh - 1});
$("#inputform").css({'bottom': JSON.stringify(-$("#inputform").height()-10)+"px"});
var message_scrollh = $("#messagewindow").prop("scrollHeight");
$("#messagewindow")
.css({"bottom": formh}) // leave space for the input form
.scrollTop(message_scrollh); // keep the output window scrolled to the bottom
}
// Handle text coming from the server
@ -143,8 +216,11 @@ function onDefault(cmdname, args, kwargs) {
$(window).bind("resize", doWindowResize);
$("#inputfield").bind("resize", doWindowResize);
// Evenit when any key is pressed
$(document).keydown(onKeydown);
// Event when any key is pressed
$(document).keydown(onKeydown)
.bind("keyup", resizeInputField)
.bind("paste", resizeInputField)
.bind("cut", resizeInputField);
// Event when client finishes loading
$(document).ready(function() {

View file

@ -56,18 +56,14 @@ JQuery available.
{% endblock %}
</div>
<div id="noscript" class="err">
<noscript class="err">
<h3>Javascript Error: The Evennia MUD client requires that you
have Javascript activated.</h3>
<p>Turn off eventual script blockers and/or switch to a
web browser supporting javascript. <p>
This error could also be due to not being able to access
the online jQuery javascript library.</p>
<!-- This is will only fire if javascript is actually active -->
<script language="javascript" type="text/javascript">
$('#noscript').remove();
</script>
</div>
</noscript>
<!-- main client -->
<div id=clientwrapper>

View file

@ -14,12 +14,12 @@
<div id="inputform">
<div id="prompt"></div>
<div id="inputcontrol">
<textarea id="inputfield" type="text"> </textarea>
<textarea id="inputfield" type="text"></textarea>
<input id="inputsend" type="button" onClick="doSendText()" value="&gt;"/>
</div>
</div>
<div id="inputsizer"></div>
</div>
{% endblock %}