Merging fixes from clone jeremywosborne-evennia-patch. Closes merge request issue 211. Thanks!

This commit is contained in:
Griatch 2012-02-21 08:27:30 +01:00
commit a923a9a061
4 changed files with 76 additions and 34 deletions

View file

@ -37,28 +37,28 @@ class TextToHTMLparser(object):
normalcode = '\033[0m' normalcode = '\033[0m'
tabstop = 4 tabstop = 4
re_string = re.compile(r'(?P<htmlchars>[<&>])|(?P<space>^[ \t]+)|(?P<lineend>\r\n|\r|\n)',#|(?P<protocol>(^|\s)((http|ftp)://.*?))(\s|$)', re_string = re.compile(r'(?P<htmlchars>[<&>])|(?P<space>^[ \t]+)|(?P<lineend>\r\n|\r|\n)', re.S|re.M|re.I)
re.S|re.M|re.I)
def re_color(self, text): def re_color(self, text):
"Replace ansi colors with html color tags" """Replace ansi colors with html color class names.
Let the client choose how it will display colors, if it wishes to."""
for colorname, code in self.colorcodes: for colorname, code in self.colorcodes:
regexp = "(?:%s)(.*?)(?:%s)" % (code, self.normalcode) regexp = "(?:%s)(.*?)(?:%s)" % (code, self.normalcode)
regexp = regexp.replace('[', r'\[') regexp = regexp.replace('[', r'\[')
text = re.sub(regexp, r'''<span style="color: %s">\1</span>''' % colorname, text) text = re.sub(regexp, r'''<span class="%s">\1</span>''' % colorname, text)
return text return text
def re_bold(self, text): def re_bold(self, text):
"Replace ansi hilight with bold text" "Replace ansi hilight with strong text element."
regexp = "(?:%s)(.*?)(?:%s)" % ('\033[1m', self.normalcode) regexp = "(?:%s)(.*?)(?:%s)" % ('\033[1m', self.normalcode)
regexp = regexp.replace('[', r'\[') regexp = regexp.replace('[', r'\[')
return re.sub(regexp, r'<span style="font-weight:bold">\1</span>', text) return re.sub(regexp, r'<strong>\1</strong>', text)
def re_underline(self, text): def re_underline(self, text):
"Replace ansi underline with html equivalent" "Replace ansi underline with html underline class name."
regexp = "(?:%s)(.*?)(?:%s)" % ('\033[4m', self.normalcode) regexp = "(?:%s)(.*?)(?:%s)" % ('\033[4m', self.normalcode)
regexp = regexp.replace('[', r'\[') regexp = regexp.replace('[', r'\[')
return re.sub(regexp, r'<span style="text-decoration: underline">\1</span>', text) return re.sub(regexp, r'<span class="underline">\1</span>', text)
def remove_bells(self, text): def remove_bells(self, text):
"Remove ansi specials" "Remove ansi specials"
@ -79,7 +79,9 @@ class TextToHTMLparser(object):
def convert_urls(self, text): def convert_urls(self, text):
"Replace urls (http://...) by valid HTML" "Replace urls (http://...) by valid HTML"
regexp = r"((ftp|www|http)(\W+\S+[^).,:;?\]\}(\<span\>) \r\n$]+))" regexp = r"((ftp|www|http)(\W+\S+[^).,:;?\]\}(\<span\>) \r\n$]+))"
return re.sub(regexp, r'<a href="\1">\1</a> ', text) # -> added target to output prevent the web browser from attempting to
# change pages (and losing our webclient session).
return re.sub(regexp, r'<a href="\1" target="_blank">\1</a>', text)
def do_sub(self, m): def do_sub(self, m):
"Helper method to be passed to re.sub." "Helper method to be passed to re.sub."
@ -94,20 +96,6 @@ class TextToHTMLparser(object):
t = m.group().replace('\t', '&nbsp;'*self.tabstop) t = m.group().replace('\t', '&nbsp;'*self.tabstop)
t = t.replace(' ', '&nbsp;') t = t.replace(' ', '&nbsp;')
return t return t
# else:
# return m.group('protocol') + ' '
# url = m.group('protocol')
# prefix, postfix = '',''
# if url.startswith(' '):
# prefix = ' '
# url = url[1:]
# if url.endswith(' '):
# postfix = ' '
# url = url[:-1]
# last = m.groups()[-1]
# if last in ['\n', '\r', '\r\n']:
# last = '<br>'
# return '%s%s%s' % (prefix, url, postfix)
def parse(self, text): def parse(self, text):
""" """

View file

@ -39,6 +39,23 @@ a:hover, a:active { color: #ccc }
/* Error messages (red) */ /* Error messages (red) */
.err { color: #f00 } .err { color: #f00 }
/* Style specific classes corresponding to formatted, narative text. */
.white { color: white; }
.cyan { color: #00FFFF; }
.blue { color: blue; }
.red { color: red; }
.magenta { color: #FF00FF; }
.lime { color: lime; }
.yellow { color: yellow; }
.gray { color: gray; }
.teal { color: teal; }
.navy { color: navy; }
.maroon { color: maroon; }
.purple { color: purple; }
.green { color: green; }
.olive { color: olive; }
.underline { text-decoration: underline; }
/* Container surrounding entire chat */ /* Container surrounding entire chat */
#wrapper { #wrapper {
position: relative; position: relative;

View file

@ -35,6 +35,46 @@ contain the 'mode' of the request to be handled by the protocol:
// jQuery must be imported by the calling html page before this script // jQuery must be imported by the calling html page before this script
// There are plenty of help on using the jQuery library on http://jquery.com/ // There are plenty of help on using the jQuery library on http://jquery.com/
$.fn.appendCaret = function() {
/* jQuery extension that will forward the caret to the end of the input, and
won't harm other elements (although calling this on multiple inputs might
not have the expected consequences).
Thanks to
http://stackoverflow.com/questions/499126/jquery-set-cursor-position-in-text-area
for the good starting point. */
return this.each(function() {
var range,
// Index at where to place the caret.
end,
self = this;
if (self.setSelectionRange) {
// other browsers
end = self.value.length;
self.focus();
// NOTE: Need to delay the caret movement until after the callstack.
setTimeout(function() {
self.setSelectionRange(end, end);
}, 0);
}
else if (self.createTextRange) {
// IE
end = self.value.length - 1;
range = self.createTextRange();
range.collapse(true);
range.moveEnd('character', end);
range.moveStart('character', end);
// NOTE: I haven't tested to see if IE has the same problem as
// W3C browsers seem to have in this context (needing to fire
// select after callstack).
range.select();
}
});
};
// Server communications // Server communications
var CLIENT_HASH = '0'; // variable holding the client id var CLIENT_HASH = '0'; // variable holding the client id
@ -192,10 +232,12 @@ function history_add(input) {
// Catching keyboard shortcuts // Catching keyboard shortcuts
$(document).keydown( function(event) { $(document).keydown( function(event) {
// Get the pressed key // Get the pressed key (normalized by jQuery)
var code = event.keyCode ? event.keyCode : event.which; var code = event.which,
inputField = $("#inputfield");
// always focus input field no matter which key is pressed // always focus input field no matter which key is pressed
$("#inputfield")[0].focus(); inputField.focus();
// Special keys recognized by client // Special keys recognized by client
@ -204,18 +246,13 @@ $(document).keydown( function(event) {
if (code == 13) { // Enter Key if (code == 13) { // Enter Key
webclient_input(); webclient_input();
event.preventDefault(); event.preventDefault();
return false;
} }
else { else {
if (code == 38) { // arrow up 38 if (code == 38) { // arrow up 38
$("#inputfield").val(function(index, value){ inputField.val(history_step_back()).appendCaret();
return history_step_back();
});
} }
else if (code == 40) { // arrow down 40 else if (code == 40) { // arrow down 40
$("#inputfield").val(function(index, value){ inputField.val(history_step_fwd()).appendCaret();
return history_step_fwd();
});
} }
} }
}); });

View file

@ -36,7 +36,7 @@
to the local copy.</p> to the local copy.</p>
</div> </div>
</div> </div>
<form id="inputform"> <form id="inputform" action="javascript:void(0);">
<div id="playercount">Logged in Players: {{num_players_connected}}</div> <div id="playercount">Logged in Players: {{num_players_connected}}</div>
<div id="inputcontrol"><input type="text" id="inputfield" autocomplete="off"><input id="inputsend" type="button" value="send" onClick="webclient_input()" /></div> <div id="inputcontrol"><input type="text" id="inputfield" autocomplete="off"><input id="inputsend" type="button" value="send" onClick="webclient_input()" /></div>
</form> </form>