Added an optional on-screen keyboard. Must be activated by the user by selecting the option in the context-menu.
git-svn-id: https://shellinabox.googlecode.com/svn/trunk@221 0da03de8-d603-11dd-86c2-0f8696b7b6f9
This commit is contained in:
parent
13d0448fc6
commit
2c262e1077
16 changed files with 2026 additions and 481 deletions
|
@ -1,3 +1,8 @@
|
||||||
|
2010-09-04 Markus Gutschke <markus@shellinabox.com>
|
||||||
|
|
||||||
|
* Added an optional on-screen keyboard. Must be activated by the
|
||||||
|
user by selecting the option in the context-menu.
|
||||||
|
|
||||||
2010-09-03 Markus Gutschke <markus@shellinabox.com>
|
2010-09-03 Markus Gutschke <markus@shellinabox.com>
|
||||||
|
|
||||||
* Fix some scaling related issues. This fix is thanks to some
|
* Fix some scaling related issues. This fix is thanks to some
|
||||||
|
|
31
Makefile.am
31
Makefile.am
|
@ -32,6 +32,7 @@ EXTRA_DIST = INSTALL.Debian \
|
||||||
demo/demo.jspp \
|
demo/demo.jspp \
|
||||||
demo/demo.xml \
|
demo/demo.xml \
|
||||||
demo/enabled.gif \
|
demo/enabled.gif \
|
||||||
|
demo/keyboard.png \
|
||||||
demo/styles.css \
|
demo/styles.css \
|
||||||
demo/print-styles.css \
|
demo/print-styles.css \
|
||||||
demo/vt100.js \
|
demo/vt100.js \
|
||||||
|
@ -106,6 +107,8 @@ shellinaboxd_SOURCES = shellinabox/shellinaboxd.c \
|
||||||
shellinabox/print-styles.css \
|
shellinabox/print-styles.css \
|
||||||
shellinabox/enabled.gif \
|
shellinabox/enabled.gif \
|
||||||
shellinabox/favicon.ico \
|
shellinabox/favicon.ico \
|
||||||
|
shellinabox/keyboard.png \
|
||||||
|
shellinabox/keyboard-layout.html \
|
||||||
shellinabox/beep.wav \
|
shellinabox/beep.wav \
|
||||||
config.h
|
config.h
|
||||||
shellinaboxd_LDADD = liblogging.la \
|
shellinaboxd_LDADD = liblogging.la \
|
||||||
|
@ -148,7 +151,9 @@ libtool: $(LIBTOOL_DEPS)
|
||||||
|
|
||||||
${top_srcdir}/demo/demo.js: ${top_srcdir}/demo/beep.wav \
|
${top_srcdir}/demo/demo.js: ${top_srcdir}/demo/beep.wav \
|
||||||
${top_srcdir}/demo/demo.jspp \
|
${top_srcdir}/demo/demo.jspp \
|
||||||
|
${top_srcdir}/demo/enabled.gif \
|
||||||
${top_srcdir}/demo/favicon.ico \
|
${top_srcdir}/demo/favicon.ico \
|
||||||
|
${top_srcdir}/demo/keyboard.png \
|
||||||
${top_srcdir}/demo/styles.css \
|
${top_srcdir}/demo/styles.css \
|
||||||
${top_srcdir}/demo/print-styles.css \
|
${top_srcdir}/demo/print-styles.css \
|
||||||
${top_srcdir}/demo/vt100.js \
|
${top_srcdir}/demo/vt100.js \
|
||||||
|
@ -169,6 +174,10 @@ ${top_srcdir}/demo/favicon.ico: ${top_srcdir}/shellinabox/favicon.ico
|
||||||
@rm -f "$@"
|
@rm -f "$@"
|
||||||
ln "$?" "$@"
|
ln "$?" "$@"
|
||||||
|
|
||||||
|
${top_srcdir}/demo/keyboard.png: ${top_srcdir}/shellinabox/keyboard.png
|
||||||
|
@rm -f "$@"
|
||||||
|
ln "$?" "$@"
|
||||||
|
|
||||||
${top_srcdir}/demo/styles.css: ${top_srcdir}/shellinabox/styles.css
|
${top_srcdir}/demo/styles.css: ${top_srcdir}/shellinabox/styles.css
|
||||||
@rm -f "$@"
|
@rm -f "$@"
|
||||||
sed -e '/\[if DEFINES_COLORS\]/,/\[endif DEFINES_COLORS\]/d' "$?" >"$@"
|
sed -e '/\[if DEFINES_COLORS\]/,/\[endif DEFINES_COLORS\]/d' "$?" >"$@"
|
||||||
|
@ -197,7 +206,8 @@ ${top_srcdir}/demo/vt100.js: ${top_srcdir}/shellinabox/vt100.js
|
||||||
@rm -f "$@"
|
@rm -f "$@"
|
||||||
ln "$?" "$@"
|
ln "$?" "$@"
|
||||||
|
|
||||||
shellinaboxd.1: shellinabox/shellinaboxd.man.in config.h
|
shellinaboxd.1: ${top_srcdir}/shellinabox/shellinaboxd.man.in \
|
||||||
|
${top_srcdir}/config.h
|
||||||
@src="${top_srcdir}/shellinabox/shellinaboxd.man.in"; \
|
@src="${top_srcdir}/shellinabox/shellinaboxd.man.in"; \
|
||||||
echo preprocess "$$src" '>'"$@"; \
|
echo preprocess "$$src" '>'"$@"; \
|
||||||
if sed -e 's/^#define \([^ ]*\).*/\1/' -e t -e d config.h | \
|
if sed -e 's/^#define \([^ ]*\).*/\1/' -e t -e d config.h | \
|
||||||
|
@ -253,6 +263,13 @@ clean-local:
|
||||||
$(OBJCOPY) --add-section .note.GNU-stack=GNU-stack "$@"; \
|
$(OBJCOPY) --add-section .note.GNU-stack=GNU-stack "$@"; \
|
||||||
rm -f GNU-stack
|
rm -f GNU-stack
|
||||||
|
|
||||||
|
.png.o:
|
||||||
|
@echo $(OBJCOPY) "$<" "$@"
|
||||||
|
@$(OBJCOPY) -I binary `$(objcopyflags)` `echo "$<" | $(renamesymbols)`\
|
||||||
|
"$<" "$@"
|
||||||
|
@-printf '\000' >GNU-stack && \
|
||||||
|
$(OBJCOPY) --add-section .note.GNU-stack=GNU-stack "$@"; \
|
||||||
|
rm -f GNU-stack
|
||||||
|
|
||||||
.html.o:
|
.html.o:
|
||||||
@echo $(OBJCOPY) "$<" "$@"
|
@echo $(OBJCOPY) "$<" "$@"
|
||||||
|
@ -272,15 +289,23 @@ clean-local:
|
||||||
rm -f GNU-stack
|
rm -f GNU-stack
|
||||||
|
|
||||||
|
|
||||||
shellinabox/shell_in_a_box.o: shellinabox/shell_in_a_box.js config.h
|
shellinabox/shell_in_a_box.o: ${top_srcdir}/shellinabox/shell_in_a_box.js \
|
||||||
|
${top_srcdir}/config.h
|
||||||
|
|
||||||
|
${top_srcdir}/shellinabox/vt100.js: ${top_srcdir}/shellinabox/vt100.jspp \
|
||||||
|
${top_srcdir}/shellinabox/keyboard-layout.html
|
||||||
|
|
||||||
.jspp.js:
|
.jspp.js:
|
||||||
@echo preprocess "$<" "$@"
|
@echo preprocess "$<" "$@"
|
||||||
@sed -e "`sed -e 's/^#define *\([^ ]*\) *\(.*\)/\/^[^#]\/s\/\1\/\2 \\\\\/* \1 *\\\\\/\/g/' \
|
@kbd=`while read i; do \
|
||||||
|
printf '%s' "\`echo "$$i" | sed 's/&/\\\\\\&/g'\`"; \
|
||||||
|
done <${top_srcdir}/shellinabox/keyboard-layout.html`; \
|
||||||
|
sed -e "`sed -e 's/^#define *\([^ ]*\) *\(.*\)/\/^[^#]\/s\/\1\/\2 \\\\\/* \1 *\\\\\/\/g/' \
|
||||||
-e t \
|
-e t \
|
||||||
-e d "$<"`" \
|
-e d "$<"`" \
|
||||||
-e "s/^#/\/\/ #/" \
|
-e "s/^#/\/\/ #/" \
|
||||||
-e "s/VERSION/\"@VERSION@ (revision @VCS_REVISION@)\"/g" \
|
-e "s/VERSION/\"@VERSION@ (revision @VCS_REVISION@)\"/g" \
|
||||||
|
-e "s%KEYBOARD%'$${kbd}'%" \
|
||||||
"$<" >"$@"
|
"$<" >"$@"
|
||||||
|
|
||||||
.js.o:
|
.js.o:
|
||||||
|
|
42
Makefile.in
42
Makefile.in
|
@ -82,6 +82,8 @@ am_shellinaboxd_OBJECTS = shellinaboxd.$(OBJEXT) \
|
||||||
shellinabox/styles.$(OBJEXT) \
|
shellinabox/styles.$(OBJEXT) \
|
||||||
shellinabox/print-styles.$(OBJEXT) \
|
shellinabox/print-styles.$(OBJEXT) \
|
||||||
shellinabox/enabled.$(OBJEXT) shellinabox/favicon.$(OBJEXT) \
|
shellinabox/enabled.$(OBJEXT) shellinabox/favicon.$(OBJEXT) \
|
||||||
|
shellinabox/keyboard.$(OBJEXT) \
|
||||||
|
shellinabox/keyboard-layout.$(OBJEXT) \
|
||||||
shellinabox/beep.$(OBJEXT)
|
shellinabox/beep.$(OBJEXT)
|
||||||
shellinaboxd_OBJECTS = $(am_shellinaboxd_OBJECTS)
|
shellinaboxd_OBJECTS = $(am_shellinaboxd_OBJECTS)
|
||||||
shellinaboxd_DEPENDENCIES = liblogging.la libhttp.la
|
shellinaboxd_DEPENDENCIES = liblogging.la libhttp.la
|
||||||
|
@ -288,6 +290,7 @@ EXTRA_DIST = INSTALL.Debian \
|
||||||
demo/demo.jspp \
|
demo/demo.jspp \
|
||||||
demo/demo.xml \
|
demo/demo.xml \
|
||||||
demo/enabled.gif \
|
demo/enabled.gif \
|
||||||
|
demo/keyboard.png \
|
||||||
demo/styles.css \
|
demo/styles.css \
|
||||||
demo/print-styles.css \
|
demo/print-styles.css \
|
||||||
demo/vt100.js \
|
demo/vt100.js \
|
||||||
|
@ -366,6 +369,8 @@ shellinaboxd_SOURCES = shellinabox/shellinaboxd.c \
|
||||||
shellinabox/print-styles.css \
|
shellinabox/print-styles.css \
|
||||||
shellinabox/enabled.gif \
|
shellinabox/enabled.gif \
|
||||||
shellinabox/favicon.ico \
|
shellinabox/favicon.ico \
|
||||||
|
shellinabox/keyboard.png \
|
||||||
|
shellinabox/keyboard-layout.html \
|
||||||
shellinabox/beep.wav \
|
shellinabox/beep.wav \
|
||||||
config.h
|
config.h
|
||||||
|
|
||||||
|
@ -407,7 +412,7 @@ all: config.h
|
||||||
$(MAKE) $(AM_MAKEFLAGS) all-am
|
$(MAKE) $(AM_MAKEFLAGS) all-am
|
||||||
|
|
||||||
.SUFFIXES:
|
.SUFFIXES:
|
||||||
.SUFFIXES: .c .css .gif .html .ico .js .jspp .lo .o .obj .wav
|
.SUFFIXES: .c .css .gif .html .ico .js .jspp .lo .o .obj .png .wav
|
||||||
am--refresh:
|
am--refresh:
|
||||||
@:
|
@:
|
||||||
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
|
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
|
||||||
|
@ -537,6 +542,10 @@ shellinabox/enabled.$(OBJEXT): shellinabox/$(am__dirstamp) \
|
||||||
shellinabox/$(DEPDIR)/$(am__dirstamp)
|
shellinabox/$(DEPDIR)/$(am__dirstamp)
|
||||||
shellinabox/favicon.$(OBJEXT): shellinabox/$(am__dirstamp) \
|
shellinabox/favicon.$(OBJEXT): shellinabox/$(am__dirstamp) \
|
||||||
shellinabox/$(DEPDIR)/$(am__dirstamp)
|
shellinabox/$(DEPDIR)/$(am__dirstamp)
|
||||||
|
shellinabox/keyboard.$(OBJEXT): shellinabox/$(am__dirstamp) \
|
||||||
|
shellinabox/$(DEPDIR)/$(am__dirstamp)
|
||||||
|
shellinabox/keyboard-layout.$(OBJEXT): shellinabox/$(am__dirstamp) \
|
||||||
|
shellinabox/$(DEPDIR)/$(am__dirstamp)
|
||||||
shellinabox/beep.$(OBJEXT): shellinabox/$(am__dirstamp) \
|
shellinabox/beep.$(OBJEXT): shellinabox/$(am__dirstamp) \
|
||||||
shellinabox/$(DEPDIR)/$(am__dirstamp)
|
shellinabox/$(DEPDIR)/$(am__dirstamp)
|
||||||
shellinaboxd$(EXEEXT): $(shellinaboxd_OBJECTS) $(shellinaboxd_DEPENDENCIES)
|
shellinaboxd$(EXEEXT): $(shellinaboxd_OBJECTS) $(shellinaboxd_DEPENDENCIES)
|
||||||
|
@ -549,6 +558,8 @@ mostlyclean-compile:
|
||||||
-rm -f shellinabox/cgi_root.$(OBJEXT)
|
-rm -f shellinabox/cgi_root.$(OBJEXT)
|
||||||
-rm -f shellinabox/enabled.$(OBJEXT)
|
-rm -f shellinabox/enabled.$(OBJEXT)
|
||||||
-rm -f shellinabox/favicon.$(OBJEXT)
|
-rm -f shellinabox/favicon.$(OBJEXT)
|
||||||
|
-rm -f shellinabox/keyboard-layout.$(OBJEXT)
|
||||||
|
-rm -f shellinabox/keyboard.$(OBJEXT)
|
||||||
-rm -f shellinabox/print-styles.$(OBJEXT)
|
-rm -f shellinabox/print-styles.$(OBJEXT)
|
||||||
-rm -f shellinabox/root_page.$(OBJEXT)
|
-rm -f shellinabox/root_page.$(OBJEXT)
|
||||||
-rm -f shellinabox/shell_in_a_box.$(OBJEXT)
|
-rm -f shellinabox/shell_in_a_box.$(OBJEXT)
|
||||||
|
@ -1162,7 +1173,9 @@ libtool: $(LIBTOOL_DEPS)
|
||||||
|
|
||||||
${top_srcdir}/demo/demo.js: ${top_srcdir}/demo/beep.wav \
|
${top_srcdir}/demo/demo.js: ${top_srcdir}/demo/beep.wav \
|
||||||
${top_srcdir}/demo/demo.jspp \
|
${top_srcdir}/demo/demo.jspp \
|
||||||
|
${top_srcdir}/demo/enabled.gif \
|
||||||
${top_srcdir}/demo/favicon.ico \
|
${top_srcdir}/demo/favicon.ico \
|
||||||
|
${top_srcdir}/demo/keyboard.png \
|
||||||
${top_srcdir}/demo/styles.css \
|
${top_srcdir}/demo/styles.css \
|
||||||
${top_srcdir}/demo/print-styles.css \
|
${top_srcdir}/demo/print-styles.css \
|
||||||
${top_srcdir}/demo/vt100.js \
|
${top_srcdir}/demo/vt100.js \
|
||||||
|
@ -1183,6 +1196,10 @@ ${top_srcdir}/demo/favicon.ico: ${top_srcdir}/shellinabox/favicon.ico
|
||||||
@rm -f "$@"
|
@rm -f "$@"
|
||||||
ln "$?" "$@"
|
ln "$?" "$@"
|
||||||
|
|
||||||
|
${top_srcdir}/demo/keyboard.png: ${top_srcdir}/shellinabox/keyboard.png
|
||||||
|
@rm -f "$@"
|
||||||
|
ln "$?" "$@"
|
||||||
|
|
||||||
${top_srcdir}/demo/styles.css: ${top_srcdir}/shellinabox/styles.css
|
${top_srcdir}/demo/styles.css: ${top_srcdir}/shellinabox/styles.css
|
||||||
@rm -f "$@"
|
@rm -f "$@"
|
||||||
sed -e '/\[if DEFINES_COLORS\]/,/\[endif DEFINES_COLORS\]/d' "$?" >"$@"
|
sed -e '/\[if DEFINES_COLORS\]/,/\[endif DEFINES_COLORS\]/d' "$?" >"$@"
|
||||||
|
@ -1211,7 +1228,8 @@ ${top_srcdir}/demo/vt100.js: ${top_srcdir}/shellinabox/vt100.js
|
||||||
@rm -f "$@"
|
@rm -f "$@"
|
||||||
ln "$?" "$@"
|
ln "$?" "$@"
|
||||||
|
|
||||||
shellinaboxd.1: shellinabox/shellinaboxd.man.in config.h
|
shellinaboxd.1: ${top_srcdir}/shellinabox/shellinaboxd.man.in \
|
||||||
|
${top_srcdir}/config.h
|
||||||
@src="${top_srcdir}/shellinabox/shellinaboxd.man.in"; \
|
@src="${top_srcdir}/shellinabox/shellinaboxd.man.in"; \
|
||||||
echo preprocess "$$src" '>'"$@"; \
|
echo preprocess "$$src" '>'"$@"; \
|
||||||
if sed -e 's/^#define \([^ ]*\).*/\1/' -e t -e d config.h | \
|
if sed -e 's/^#define \([^ ]*\).*/\1/' -e t -e d config.h | \
|
||||||
|
@ -1267,6 +1285,14 @@ clean-local:
|
||||||
$(OBJCOPY) --add-section .note.GNU-stack=GNU-stack "$@"; \
|
$(OBJCOPY) --add-section .note.GNU-stack=GNU-stack "$@"; \
|
||||||
rm -f GNU-stack
|
rm -f GNU-stack
|
||||||
|
|
||||||
|
.png.o:
|
||||||
|
@echo $(OBJCOPY) "$<" "$@"
|
||||||
|
@$(OBJCOPY) -I binary `$(objcopyflags)` `echo "$<" | $(renamesymbols)`\
|
||||||
|
"$<" "$@"
|
||||||
|
@-printf '\000' >GNU-stack && \
|
||||||
|
$(OBJCOPY) --add-section .note.GNU-stack=GNU-stack "$@"; \
|
||||||
|
rm -f GNU-stack
|
||||||
|
|
||||||
.html.o:
|
.html.o:
|
||||||
@echo $(OBJCOPY) "$<" "$@"
|
@echo $(OBJCOPY) "$<" "$@"
|
||||||
@$(OBJCOPY) -I binary `$(objcopyflags)` `echo "$<" | $(renamesymbols)`\
|
@$(OBJCOPY) -I binary `$(objcopyflags)` `echo "$<" | $(renamesymbols)`\
|
||||||
|
@ -1283,15 +1309,23 @@ clean-local:
|
||||||
$(OBJCOPY) --add-section .note.GNU-stack=GNU-stack "$@"; \
|
$(OBJCOPY) --add-section .note.GNU-stack=GNU-stack "$@"; \
|
||||||
rm -f GNU-stack
|
rm -f GNU-stack
|
||||||
|
|
||||||
shellinabox/shell_in_a_box.o: shellinabox/shell_in_a_box.js config.h
|
shellinabox/shell_in_a_box.o: ${top_srcdir}/shellinabox/shell_in_a_box.js \
|
||||||
|
${top_srcdir}/config.h
|
||||||
|
|
||||||
|
${top_srcdir}/shellinabox/vt100.js: ${top_srcdir}/shellinabox/vt100.jspp \
|
||||||
|
${top_srcdir}/shellinabox/keyboard-layout.html
|
||||||
|
|
||||||
.jspp.js:
|
.jspp.js:
|
||||||
@echo preprocess "$<" "$@"
|
@echo preprocess "$<" "$@"
|
||||||
@sed -e "`sed -e 's/^#define *\([^ ]*\) *\(.*\)/\/^[^#]\/s\/\1\/\2 \\\\\/* \1 *\\\\\/\/g/' \
|
@kbd=`while read i; do \
|
||||||
|
printf '%s' "\`echo "$$i" | sed 's/&/\\\\\\&/g'\`"; \
|
||||||
|
done <${top_srcdir}/shellinabox/keyboard-layout.html`; \
|
||||||
|
sed -e "`sed -e 's/^#define *\([^ ]*\) *\(.*\)/\/^[^#]\/s\/\1\/\2 \\\\\/* \1 *\\\\\/\/g/' \
|
||||||
-e t \
|
-e t \
|
||||||
-e d "$<"`" \
|
-e d "$<"`" \
|
||||||
-e "s/^#/\/\/ #/" \
|
-e "s/^#/\/\/ #/" \
|
||||||
-e "s/VERSION/\"@VERSION@ (revision @VCS_REVISION@)\"/g" \
|
-e "s/VERSION/\"@VERSION@ (revision @VCS_REVISION@)\"/g" \
|
||||||
|
-e "s%KEYBOARD%'$${kbd}'%" \
|
||||||
"$<" >"$@"
|
"$<" >"$@"
|
||||||
|
|
||||||
.js.o:
|
.js.o:
|
||||||
|
|
2
config.h
2
config.h
|
@ -153,7 +153,7 @@
|
||||||
#define STDC_HEADERS 1
|
#define STDC_HEADERS 1
|
||||||
|
|
||||||
/* Most recent revision number in the version control system */
|
/* Most recent revision number in the version control system */
|
||||||
#define VCS_REVISION "220"
|
#define VCS_REVISION "221"
|
||||||
|
|
||||||
/* Version number of package */
|
/* Version number of package */
|
||||||
#define VERSION "2.10"
|
#define VERSION "2.10"
|
||||||
|
|
2
configure
vendored
2
configure
vendored
|
@ -2328,7 +2328,7 @@ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $
|
||||||
ac_compiler_gnu=$ac_cv_c_compiler_gnu
|
ac_compiler_gnu=$ac_cv_c_compiler_gnu
|
||||||
|
|
||||||
|
|
||||||
VCS_REVISION=220
|
VCS_REVISION=221
|
||||||
|
|
||||||
|
|
||||||
cat >>confdefs.h <<_ACEOF
|
cat >>confdefs.h <<_ACEOF
|
||||||
|
|
|
@ -2,7 +2,7 @@ AC_PREREQ(2.57)
|
||||||
|
|
||||||
dnl This is the one location where the authoritative version number is stored
|
dnl This is the one location where the authoritative version number is stored
|
||||||
AC_INIT(shellinabox, 2.10, markus@shellinabox.com)
|
AC_INIT(shellinabox, 2.10, markus@shellinabox.com)
|
||||||
VCS_REVISION=220
|
VCS_REVISION=221
|
||||||
AC_SUBST(VCS_REVISION)
|
AC_SUBST(VCS_REVISION)
|
||||||
AC_DEFINE_UNQUOTED(VCS_REVISION, "${VCS_REVISION}",
|
AC_DEFINE_UNQUOTED(VCS_REVISION, "${VCS_REVISION}",
|
||||||
[Most recent revision number in the version control system])
|
[Most recent revision number in the version control system])
|
||||||
|
|
BIN
demo/keyboard.png
Normal file
BIN
demo/keyboard.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 808 B |
215
demo/styles.css
215
demo/styles.css
|
@ -1,156 +1,233 @@
|
||||||
#vt100 a {
|
#vt100 a {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
color: inherit;
|
color: inherit;
|
||||||
}
|
}
|
||||||
|
|
||||||
#vt100 a:hover {
|
#vt100 a:hover {
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
}
|
}
|
||||||
|
|
||||||
#vt100 #reconnect {
|
#vt100 #reconnect {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
#vt100 #reconnect input {
|
#vt100 #reconnect input {
|
||||||
padding: 1ex;
|
padding: 1ex;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
font-size: x-large;
|
font-size: x-large;
|
||||||
}
|
}
|
||||||
|
|
||||||
#vt100 #cursize {
|
#vt100 #cursize {
|
||||||
background: #EEEEEE;
|
background: #EEEEEE;
|
||||||
border: 1px solid black;
|
border: 1px solid black;
|
||||||
font-family: sans-serif;
|
font-family: sans-serif;
|
||||||
font-size: large;
|
font-size: large;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
padding: 1ex;
|
padding: 1ex;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
#vt100 pre {
|
#vt100 pre {
|
||||||
margin: 0px;
|
margin: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#vt100 pre pre {
|
#vt100 pre pre {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
#vt100 #scrollable {
|
#vt100 #scrollable {
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
overflow-y: scroll;
|
overflow-y: scroll;
|
||||||
position: relative;
|
position: relative;
|
||||||
padding: 1px;
|
padding: 1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#vt100 #console, #vt100 #alt_console, #vt100 #cursor, #vt100 #lineheight, #vt100 .hidden pre {
|
#vt100 #console, #vt100 #alt_console, #vt100 #cursor, #vt100 #lineheight, #vt100 .hidden pre {
|
||||||
font-family: "DejaVu Sans Mono", "Everson Mono", FreeMono, "Andale Mono", "Lucida Console", monospace;
|
font-family: "DejaVu Sans Mono", "Everson Mono", FreeMono, "Andale Mono", "Lucida Console", monospace;
|
||||||
}
|
}
|
||||||
|
|
||||||
#vt100 #lineheight {
|
#vt100 #lineheight {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
#vt100 #cursor {
|
#vt100 #cursor {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 0px;
|
left: 0px;
|
||||||
top: 0px;
|
top: 0px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#vt100 #cursor.bright {
|
#vt100 #cursor.bright {
|
||||||
background-color: #e60000;
|
background-color: #e60000;
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
#vt100 #cursor.dim {
|
#vt100 #cursor.dim {
|
||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
#vt100 #cursor.inactive {
|
#vt100 #cursor.inactive {
|
||||||
border: 1px solid #e60000;
|
border: 1px solid #e60000;
|
||||||
margin: -1px;
|
margin: -1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#vt100 #padding {
|
#vt100 #padding {
|
||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
width: 1px;
|
width: 1px;
|
||||||
height: 0px;
|
height: 0px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
#vt100 .hidden {
|
#vt100 .hidden {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: -10000px;
|
top: -10000px;
|
||||||
left: -10000px;
|
left: -10000px;
|
||||||
width: 0px;
|
width: 0px;
|
||||||
height: 0px;
|
height: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#vt100 #menu {
|
#vt100 #menu {
|
||||||
overflow: visible;
|
overflow: visible;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: 3;
|
z-index: 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
#vt100 #menu .popup {
|
#vt100 #menu .popup {
|
||||||
background-color: #EEEEEE;
|
background-color: #EEEEEE;
|
||||||
border: 1px solid black;
|
border: 1px solid black;
|
||||||
font-family: sans-serif;
|
font-family: sans-serif;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
}
|
}
|
||||||
|
|
||||||
#vt100 #menu .popup ul {
|
#vt100 #menu .popup ul {
|
||||||
list-style-type: none;
|
list-style-type: none;
|
||||||
padding: 0px;
|
padding: 0px;
|
||||||
margin: 0px;
|
margin: 0px;
|
||||||
min-width: 10em;
|
min-width: 10em;
|
||||||
}
|
}
|
||||||
|
|
||||||
#vt100 #menu .popup li {
|
#vt100 #menu .popup li {
|
||||||
padding: 3px 0.5ex 3px 0.5ex;
|
padding: 3px 0.5ex 3px 0.5ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
#vt100 #menu .popup li.hover {
|
#vt100 #menu .popup li.hover {
|
||||||
background-color: #444444;
|
background-color: #444444;
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
#vt100 #menu .popup li.disabled {
|
#vt100 #menu .popup li.disabled {
|
||||||
color: #AAAAAA;
|
color: #AAAAAA;
|
||||||
}
|
}
|
||||||
|
|
||||||
#vt100 #menu .popup hr {
|
#vt100 #menu .popup hr {
|
||||||
margin: 0.5ex 0px 0.5ex 0px;
|
margin: 0.5ex 0px 0.5ex 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#vt100 #menu img {
|
#vt100 #menu img {
|
||||||
margin-right: 0.5ex;
|
margin-right: 0.5ex;
|
||||||
width: 1ex;
|
width: 1ex;
|
||||||
height: 1ex;
|
height: 1ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
#vt100 #scrollable.inverted { color: #ffffff;
|
#vt100 #scrollable.inverted { color: #ffffff;
|
||||||
background-color: #000000; }
|
background-color: #000000; }
|
||||||
|
|
||||||
|
#vt100 #kbd_button {
|
||||||
|
float: left;
|
||||||
|
position: fixed;
|
||||||
|
z-index: 0;
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
#vt100 #keyboard {
|
||||||
|
z-index: 3;
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
|
||||||
|
#vt100 #keyboard .box {
|
||||||
|
font-family: sans-serif;
|
||||||
|
background-color: #cccccc;
|
||||||
|
padding: .8em;
|
||||||
|
float: left;
|
||||||
|
position: absolute;
|
||||||
|
border-radius: 10px;
|
||||||
|
-moz-border-radius: 10px;
|
||||||
|
box-shadow: 4px 4px 6px #222222;
|
||||||
|
-webkit-box-shadow: 4px 4px 6px #222222;
|
||||||
|
/* Don't set the -moz-box-shadow. It doesn't properly scale when CSS
|
||||||
|
* transforms are in effect. Once Firefox supports box-shadow, it should
|
||||||
|
* automatically do the right thing. Until then, leave shadows disabled
|
||||||
|
* for Firefox.
|
||||||
|
*/
|
||||||
|
opacity: 0.85;
|
||||||
|
-moz-opacity: 0.85;
|
||||||
|
filter: alpha(opacity=85);
|
||||||
|
}
|
||||||
|
|
||||||
|
#vt100 #keyboard .box * {
|
||||||
|
vertical-align: top;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
#vt100 #keyboard b, #vt100 #keyboard i, #vt100 #keyboard s, #vt100 #keyboard u {
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: bold;
|
||||||
|
border-radius: 5px;
|
||||||
|
-moz-border-radius: 5px;
|
||||||
|
background-color: #555555;
|
||||||
|
color: #eeeeee;
|
||||||
|
box-shadow: 2px 2px 3px #222222;
|
||||||
|
-webkit-box-shadow: 2px 2px 3px #222222;
|
||||||
|
padding: 4px;
|
||||||
|
margin: 2px;
|
||||||
|
height: 2ex;
|
||||||
|
display: inline-block;
|
||||||
|
text-align: center;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#vt100 #keyboard b, #vt100 #keyboard s {
|
||||||
|
width: 2ex;
|
||||||
|
}
|
||||||
|
|
||||||
|
#vt100 #keyboard u, #vt100 #keyboard s {
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
#vt100 #keyboard .shifted {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#vt100 #keyboard .selected {
|
||||||
|
color: #888888;
|
||||||
|
background-color: #eeeeee;
|
||||||
|
box-shadow: 0px 0px 3px #222222;
|
||||||
|
-webkit-box-shadow: 0px 0px 3px #222222;
|
||||||
|
position: relative;
|
||||||
|
top: 1px;
|
||||||
|
left: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@media print {
|
@media print {
|
||||||
#vt100 .scrollback {
|
#vt100 .scrollback {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
#vt100 #reconnect, #vt100 #cursor, #vt100 #menu {
|
#vt100 #reconnect, #vt100 #cursor, #vt100 #menu, #vt100 #kbd_button, #vt100 #keyboard {
|
||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
#vt100 #scrollable {
|
#vt100 #scrollable {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
#vt100 #console, #vt100 #alt_console {
|
#vt100 #console, #vt100 #alt_console {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
width: 1000000ex;
|
width: 1000000ex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
643
demo/vt100.js
643
demo/vt100.js
|
@ -238,22 +238,16 @@ VT100.prototype.reset = function(clearHistory) {
|
||||||
this.enableAlternateScreen(false);
|
this.enableAlternateScreen(false);
|
||||||
|
|
||||||
var wasCompressed = false;
|
var wasCompressed = false;
|
||||||
var styles = [ 'transform',
|
var transform = this.getTransformName();
|
||||||
'WebkitTransform',
|
if (transform) {
|
||||||
'MozTransform',
|
for (var i = 0; i < 2; ++i) {
|
||||||
'filter' ];
|
wasCompressed |= this.console[i].style[transform] != '';
|
||||||
for (var i = 0; i < styles.length; ++i) {
|
this.console[i].style[transform] = '';
|
||||||
if (typeof this.console[0].style[styles[i]] != 'undefined') {
|
}
|
||||||
for (var j = 0; j < 1; ++j) {
|
this.cursor.style[transform] = '';
|
||||||
wasCompressed |= this.console[j].style[styles[i]] != '';
|
this.space.style[transform] = '';
|
||||||
this.console[j].style[styles[i]] = '';
|
if (transform == 'filter') {
|
||||||
}
|
this.console[this.currentScreen].style.width = '';
|
||||||
this.cursor.style[styles[i]] = '';
|
|
||||||
this.space.style[styles[i]] = '';
|
|
||||||
if (styles[i] == 'filter') {
|
|
||||||
this.console[this.currentScreen].style.width = '';
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.scale = 1.0;
|
this.scale = 1.0;
|
||||||
|
@ -270,10 +264,13 @@ VT100.prototype.reset = function(clearHistory) {
|
||||||
};
|
};
|
||||||
|
|
||||||
VT100.prototype.addListener = function(elem, event, listener) {
|
VT100.prototype.addListener = function(elem, event, listener) {
|
||||||
if (elem.addEventListener) {
|
try {
|
||||||
elem.addEventListener(event, listener, false);
|
if (elem.addEventListener) {
|
||||||
} else {
|
elem.addEventListener(event, listener, false);
|
||||||
elem.attachEvent('on' + event, listener);
|
} else {
|
||||||
|
elem.attachEvent('on' + event, listener);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -281,11 +278,12 @@ VT100.prototype.getUserSettings = function() {
|
||||||
// Compute hash signature to identify the entries in the userCSS menu.
|
// Compute hash signature to identify the entries in the userCSS menu.
|
||||||
// If the menu is unchanged from last time, default values can be
|
// If the menu is unchanged from last time, default values can be
|
||||||
// looked up in a cookie associated with this page.
|
// looked up in a cookie associated with this page.
|
||||||
this.signature = 2;
|
this.signature = 3;
|
||||||
this.utfPreferred = true;
|
this.utfPreferred = true;
|
||||||
this.visualBell = typeof suppressAllAudio != 'undefined' &&
|
this.visualBell = typeof suppressAllAudio != 'undefined' &&
|
||||||
suppressAllAudio;
|
suppressAllAudio;
|
||||||
this.autoprint = true;
|
this.autoprint = true;
|
||||||
|
this.softKeyboard = false;
|
||||||
this.blinkingCursor = true;
|
this.blinkingCursor = true;
|
||||||
if (this.visualBell) {
|
if (this.visualBell) {
|
||||||
this.signature = Math.floor(16807*this.signature + 1) %
|
this.signature = Math.floor(16807*this.signature + 1) %
|
||||||
|
@ -311,15 +309,16 @@ VT100.prototype.getUserSettings = function() {
|
||||||
if (settings >= 0) {
|
if (settings >= 0) {
|
||||||
settings = document.cookie.substr(settings + key.length).
|
settings = document.cookie.substr(settings + key.length).
|
||||||
replace(/([0-1]*).*/, "$1");
|
replace(/([0-1]*).*/, "$1");
|
||||||
if (settings.length == 3 + (typeof userCSSList == 'undefined' ?
|
if (settings.length == 5 + (typeof userCSSList == 'undefined' ?
|
||||||
0 : userCSSList.length)) {
|
0 : userCSSList.length)) {
|
||||||
this.utfPreferred = settings.charAt(0) != '0';
|
this.utfPreferred = settings.charAt(0) != '0';
|
||||||
this.visualBell = settings.charAt(1) != '0';
|
this.visualBell = settings.charAt(1) != '0';
|
||||||
this.autoprint = settings.charAt(2) != '0';
|
this.autoprint = settings.charAt(2) != '0';
|
||||||
this.blinkingCursor = settings.charAt(3) != '0';
|
this.softKeyboard = settings.charAt(3) != '0';
|
||||||
|
this.blinkingCursor = settings.charAt(4) != '0';
|
||||||
if (typeof userCSSList != 'undefined') {
|
if (typeof userCSSList != 'undefined') {
|
||||||
for (var i = 0; i < userCSSList.length; ++i) {
|
for (var i = 0; i < userCSSList.length; ++i) {
|
||||||
userCSSList[i][2] = settings.charAt(i + 3) != '0';
|
userCSSList[i][2] = settings.charAt(i + 5) != '0';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -332,6 +331,7 @@ VT100.prototype.storeUserSettings = function() {
|
||||||
(this.utfEnabled ? '1' : '0') +
|
(this.utfEnabled ? '1' : '0') +
|
||||||
(this.visualBell ? '1' : '0') +
|
(this.visualBell ? '1' : '0') +
|
||||||
(this.autoprint ? '1' : '0') +
|
(this.autoprint ? '1' : '0') +
|
||||||
|
(this.softKeyboard ? '1' : '0') +
|
||||||
(this.blinkingCursor ? '1' : '0');
|
(this.blinkingCursor ? '1' : '0');
|
||||||
if (typeof userCSSList != 'undefined') {
|
if (typeof userCSSList != 'undefined') {
|
||||||
for (var i = 0; i < userCSSList.length; ++i) {
|
for (var i = 0; i < userCSSList.length; ++i) {
|
||||||
|
@ -413,7 +413,7 @@ VT100.prototype.initializeUserCSSStyles = function() {
|
||||||
label.textContent= label.textContent;
|
label.textContent= label.textContent;
|
||||||
}
|
}
|
||||||
|
|
||||||
// User style sheets are number sequentially
|
// User style sheets are numbered sequentially
|
||||||
var sheet = document.getElementById(
|
var sheet = document.getElementById(
|
||||||
'usercss-' + i);
|
'usercss-' + i);
|
||||||
if (i == current) {
|
if (i == current) {
|
||||||
|
@ -470,6 +470,328 @@ VT100.prototype.initializeUserCSSStyles = function() {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
VT100.prototype.resetLastSelectedKey = function(e) {
|
||||||
|
var key = this.lastSelectedKey;
|
||||||
|
if (!key) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var position = this.mousePosition(e);
|
||||||
|
|
||||||
|
// We don't get all the necessary events to reliably reselect a key
|
||||||
|
// if we moved away from it and then back onto it. We approximate the
|
||||||
|
// behavior by remembering the key until either we release the mouse
|
||||||
|
// button (we might never get this event if the mouse has since left
|
||||||
|
// the window), or until we move away too far.
|
||||||
|
var box = this.keyboard.firstChild;
|
||||||
|
if (position[0] < box.offsetLeft + key.offsetWidth ||
|
||||||
|
position[1] < box.offsetTop + key.offsetHeight ||
|
||||||
|
position[0] >= box.offsetLeft + box.offsetWidth - key.offsetWidth ||
|
||||||
|
position[1] >= box.offsetTop + box.offsetHeight - key.offsetHeight ||
|
||||||
|
position[0] < box.offsetLeft + key.offsetLeft - key.offsetWidth ||
|
||||||
|
position[1] < box.offsetTop + key.offsetTop - key.offsetHeight ||
|
||||||
|
position[0] >= box.offsetLeft + key.offsetLeft + 2*key.offsetWidth ||
|
||||||
|
position[1] >= box.offsetTop + key.offsetTop + 2*key.offsetHeight) {
|
||||||
|
if (this.lastSelectedKey.className) log.console('reset: deselecting');
|
||||||
|
this.lastSelectedKey.className = '';
|
||||||
|
this.lastSelectedKey = undefined;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
VT100.prototype.showShiftState = function(state) {
|
||||||
|
var style = document.getElementById('shift_state');
|
||||||
|
if (state) {
|
||||||
|
this.setTextContentRaw(style,
|
||||||
|
'#vt100 #keyboard .shifted {' +
|
||||||
|
'display: inline }' +
|
||||||
|
'#vt100 #keyboard .unshifted {' +
|
||||||
|
'display: none }');
|
||||||
|
} else {
|
||||||
|
this.setTextContentRaw(style, '');
|
||||||
|
}
|
||||||
|
var elems = this.keyboard.getElementsByTagName('I');
|
||||||
|
for (var i = 0; i < elems.length; ++i) {
|
||||||
|
if (elems[i].id == '16') {
|
||||||
|
elems[i].className = state ? 'selected' : '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
VT100.prototype.showCtrlState = function(state) {
|
||||||
|
var ctrl = this.getChildById(this.keyboard, '17' /* Ctrl */);
|
||||||
|
if (ctrl) {
|
||||||
|
ctrl.className = state ? 'selected' : '';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
VT100.prototype.showAltState = function(state) {
|
||||||
|
var alt = this.getChildById(this.keyboard, '18' /* Alt */);
|
||||||
|
if (alt) {
|
||||||
|
alt.className = state ? 'selected' : '';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
VT100.prototype.clickedKeyboard = function(e, elem, ch, key, shift, ctrl, alt){
|
||||||
|
var fake = [ ];
|
||||||
|
fake.charCode = ch;
|
||||||
|
fake.keyCode = key;
|
||||||
|
fake.ctrlKey = ctrl;
|
||||||
|
fake.shiftKey = shift;
|
||||||
|
fake.altKey = alt;
|
||||||
|
fake.metaKey = alt;
|
||||||
|
return this.handleKey(fake);
|
||||||
|
};
|
||||||
|
|
||||||
|
VT100.prototype.addKeyBinding = function(elem, ch, key, CH, KEY) {
|
||||||
|
if (elem == undefined) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (ch == '\u00A0') {
|
||||||
|
// should be treated as a regular space character.
|
||||||
|
ch = ' ';
|
||||||
|
}
|
||||||
|
if (ch != undefined && CH == undefined) {
|
||||||
|
// For letter keys, we automatically compute the uppercase character code
|
||||||
|
// from the lowercase one.
|
||||||
|
CH = ch.toUpperCase();
|
||||||
|
}
|
||||||
|
if (KEY == undefined && key != undefined) {
|
||||||
|
// Most keys have identically key codes for both lowercase and uppercase
|
||||||
|
// keypresses. Normally, only function keys would have distinct key codes,
|
||||||
|
// whereas regular keys have character codes.
|
||||||
|
KEY = key;
|
||||||
|
} else if (KEY == undefined && CH != undefined) {
|
||||||
|
// For regular keys, copy the character code to the key code.
|
||||||
|
KEY = CH.charCodeAt(0);
|
||||||
|
}
|
||||||
|
if (key == undefined && ch != undefined) {
|
||||||
|
// For regular keys, copy the character code to the key code.
|
||||||
|
key = ch.charCodeAt(0);
|
||||||
|
}
|
||||||
|
// Convert characters to numeric character codes. If the character code
|
||||||
|
// is undefined (i.e. this is a function key), set it to zero.
|
||||||
|
ch = ch ? ch.charCodeAt(0) : 0;
|
||||||
|
CH = CH ? CH.charCodeAt(0) : 0;
|
||||||
|
|
||||||
|
// Mouse down events high light the key. We also set lastSelectedKey. This
|
||||||
|
// is needed to that mouseout/mouseover can keep track of the key that
|
||||||
|
// is currently being clicked.
|
||||||
|
this.addListener(elem, 'mousedown',
|
||||||
|
function(vt100, elem, key) { return function(e) {
|
||||||
|
if ((e.which || e.button) == 1) {
|
||||||
|
if (vt100.lastSelectedKey) {
|
||||||
|
vt100.lastSelectedKey.className= '';
|
||||||
|
}
|
||||||
|
// Highlight the key while the mouse button is held down.
|
||||||
|
if (key == 16 /* Shift */) {
|
||||||
|
if (!elem.className != vt100.isShift) {
|
||||||
|
vt100.showShiftState(!vt100.isShift);
|
||||||
|
}
|
||||||
|
} else if (key == 17 /* Ctrl */) {
|
||||||
|
if (!elem.className != vt100.isCtrl) {
|
||||||
|
vt100.showCtrlState(!vt100.isCtrl);
|
||||||
|
}
|
||||||
|
} else if (key == 18 /* Alt */) {
|
||||||
|
if (!elem.className != vt100.isAlt) {
|
||||||
|
vt100.showAltState(!vt100.isAlt);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
elem.className = 'selected';
|
||||||
|
}
|
||||||
|
vt100.lastSelectedKey = elem;
|
||||||
|
}
|
||||||
|
return false; }; }(this, elem, key));
|
||||||
|
var clicked =
|
||||||
|
// Modifier keys update the state of the keyboard, but do not generate
|
||||||
|
// any key clicks that get forwarded to the application.
|
||||||
|
key >= 16 /* Shift */ && key <= 18 /* Alt */ ?
|
||||||
|
function(vt100, elem) { return function(e) {
|
||||||
|
if (elem == vt100.lastSelectedKey) {
|
||||||
|
if (key == 16 /* Shift */) {
|
||||||
|
// The user clicked the Shift key
|
||||||
|
vt100.isShift = !vt100.isShift;
|
||||||
|
vt100.showShiftState(vt100.isShift);
|
||||||
|
} else if (key == 17 /* Ctrl */) {
|
||||||
|
vt100.isCtrl = !vt100.isCtrl;
|
||||||
|
vt100.showCtrlState(vt100.isCtrl);
|
||||||
|
} else if (key == 18 /* Alt */) {
|
||||||
|
vt100.isAlt = !vt100.isAlt;
|
||||||
|
vt100.showAltState(vt100.isAlt);
|
||||||
|
}
|
||||||
|
vt100.lastSelectedKey = undefined;
|
||||||
|
}
|
||||||
|
if (vt100.lastSelectedKey) {
|
||||||
|
vt100.lastSelectedKey.className = '';
|
||||||
|
vt100.lastSelectedKey = undefined;
|
||||||
|
}
|
||||||
|
return false; }; }(this, elem) :
|
||||||
|
// Regular keys generate key clicks, when the mouse button is released or
|
||||||
|
// when a mouse click event is received.
|
||||||
|
function(vt100, elem, ch, key, CH, KEY) { return function(e) {
|
||||||
|
if (vt100.lastSelectedKey) {
|
||||||
|
if (elem == vt100.lastSelectedKey) {
|
||||||
|
// The user clicked a key.
|
||||||
|
if (vt100.isShift) {
|
||||||
|
vt100.clickedKeyboard(e, elem, CH, KEY,
|
||||||
|
true, vt100.isCtrl, vt100.isAlt);
|
||||||
|
} else {
|
||||||
|
vt100.clickedKeyboard(e, elem, ch, key,
|
||||||
|
false, vt100.isCtrl, vt100.isAlt);
|
||||||
|
}
|
||||||
|
vt100.isShift = false;
|
||||||
|
vt100.showShiftState(false);
|
||||||
|
vt100.isCtrl = false;
|
||||||
|
vt100.showCtrlState(false);
|
||||||
|
vt100.isAlt = false;
|
||||||
|
vt100.showAltState(false);
|
||||||
|
}
|
||||||
|
vt100.lastSelectedKey.className = '';
|
||||||
|
vt100.lastSelectedKey = undefined;
|
||||||
|
}
|
||||||
|
elem.className = '';
|
||||||
|
return false; }; }(this, elem, ch, key, CH, KEY);
|
||||||
|
this.addListener(elem, 'mouseup', clicked);
|
||||||
|
this.addListener(elem, 'click', clicked);
|
||||||
|
|
||||||
|
// When moving the mouse away from a key, check if any keys need to be
|
||||||
|
// deselected.
|
||||||
|
this.addListener(elem, 'mouseout',
|
||||||
|
function(vt100, elem, key) { return function(e) {
|
||||||
|
if (key == 16 /* Shift */) {
|
||||||
|
if (!elem.className == vt100.isShift) {
|
||||||
|
vt100.showShiftState(vt100.isShift);
|
||||||
|
}
|
||||||
|
} else if (key == 17 /* Ctrl */) {
|
||||||
|
if (!elem.className == vt100.isCtrl) {
|
||||||
|
vt100.showCtrlState(vt100.isCtrl);
|
||||||
|
}
|
||||||
|
} else if (key == 18 /* Alt */) {
|
||||||
|
if (!elem.className == vt100.isAlt) {
|
||||||
|
vt100.showAltState(vt100.isAlt);
|
||||||
|
}
|
||||||
|
} else if (elem.className) {
|
||||||
|
elem.className = '';
|
||||||
|
vt100.lastSelectedKey = elem;
|
||||||
|
} else if (vt100.lastSelectedKey) {
|
||||||
|
vt100.resetLastSelectedKey(e);
|
||||||
|
}
|
||||||
|
return false; }; }(this, elem, key));
|
||||||
|
|
||||||
|
// When moving the mouse over a key, select it if the user is still holding
|
||||||
|
// the mouse button down (i.e. elem == lastSelectedKey)
|
||||||
|
this.addListener(elem, 'mouseover',
|
||||||
|
function(vt100, elem, key) { return function(e) {
|
||||||
|
if (elem == vt100.lastSelectedKey) {
|
||||||
|
if (key == 16 /* Shift */) {
|
||||||
|
if (!elem.className != vt100.isShift) {
|
||||||
|
vt100.showShiftState(!vt100.isShift);
|
||||||
|
}
|
||||||
|
} else if (key == 17 /* Ctrl */) {
|
||||||
|
if (!elem.className != vt100.isCtrl) {
|
||||||
|
vt100.showCtrlState(!vt100.isCtrl);
|
||||||
|
}
|
||||||
|
} else if (key == 18 /* Alt */) {
|
||||||
|
if (!elem.className != vt100.isAlt) {
|
||||||
|
vt100.showAltState(!vt100.isAlt);
|
||||||
|
}
|
||||||
|
} else if (!elem.className) {
|
||||||
|
elem.className = 'selected';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
vt100.resetLastSelectedKey(e);
|
||||||
|
}
|
||||||
|
return false; }; }(this, elem, key));
|
||||||
|
};
|
||||||
|
|
||||||
|
VT100.prototype.initializeKeyBindings = function(elem) {
|
||||||
|
if (elem) {
|
||||||
|
if (elem.nodeName == "I" || elem.nodeName == "B") {
|
||||||
|
if (elem.id) {
|
||||||
|
// Function keys. The Javascript keycode is part of the "id"
|
||||||
|
var i = parseInt(elem.id);
|
||||||
|
if (i) {
|
||||||
|
// If the id does not parse as a number, it is not a keycode.
|
||||||
|
this.addKeyBinding(elem, undefined, i);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
var child = elem.firstChild;
|
||||||
|
if (child.nodeName == "#text") {
|
||||||
|
// If the key only has a text node as a child, then it is a letter.
|
||||||
|
// Automatically compute the lower and upper case version of the key.
|
||||||
|
this.addKeyBinding(elem, this.getTextContent(child).toLowerCase());
|
||||||
|
} else {
|
||||||
|
// If the key has two children, they are the lower and upper case
|
||||||
|
// character code, respectively.
|
||||||
|
this.addKeyBinding(elem, this.getTextContent(child), undefined,
|
||||||
|
this.getTextContent(child.nextSibling));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Recursively parse all other child nodes.
|
||||||
|
for (elem = elem.firstChild; elem; elem = elem.nextSibling) {
|
||||||
|
this.initializeKeyBindings(elem);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
VT100.prototype.initializeKeyboard = function() {
|
||||||
|
// Configure mouse event handlers for button that displays/hides keyboard
|
||||||
|
var box = this.keyboard.firstChild;
|
||||||
|
this.hideSoftKeyboard();
|
||||||
|
this.addListener(this.keyboardImage, 'click',
|
||||||
|
function(vt100) { return function(e) {
|
||||||
|
if (vt100.keyboard.style.display != '') {
|
||||||
|
if (vt100.reconnectBtn.style.visibility != '') {
|
||||||
|
vt100.showSoftKeyboard();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
vt100.hideSoftKeyboard();
|
||||||
|
vt100.input.focus();
|
||||||
|
}
|
||||||
|
return false; }; }(this));
|
||||||
|
|
||||||
|
// Enable button that displays keyboard
|
||||||
|
if (this.softKeyboard) {
|
||||||
|
this.keyboardImage.style.visibility = 'visible';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Configure mouse event handlers for on-screen keyboard
|
||||||
|
this.addListener(this.keyboard, 'click',
|
||||||
|
function(vt100) { return function(e) {
|
||||||
|
vt100.hideSoftKeyboard();
|
||||||
|
vt100.input.focus();
|
||||||
|
return false; }; }(this));
|
||||||
|
this.addListener(this.keyboard, 'selectstart', this.cancelEvent);
|
||||||
|
this.addListener(box, 'click', this.cancelEvent);
|
||||||
|
this.addListener(box, 'mouseup',
|
||||||
|
function(vt100) { return function(e) {
|
||||||
|
if (vt100.lastSelectedKey) {
|
||||||
|
vt100.lastSelectedKey.className = '';
|
||||||
|
vt100.lastSelectedKey = undefined;
|
||||||
|
}
|
||||||
|
return false; }; }(this));
|
||||||
|
this.addListener(box, 'mouseout',
|
||||||
|
function(vt100) { return function(e) {
|
||||||
|
return vt100.resetLastSelectedKey(e); }; }(this));
|
||||||
|
this.addListener(box, 'mouseover',
|
||||||
|
function(vt100) { return function(e) {
|
||||||
|
return vt100.resetLastSelectedKey(e); }; }(this));
|
||||||
|
|
||||||
|
// Configure SHIFT key behavior
|
||||||
|
var style = document.createElement('style');
|
||||||
|
var id = document.createAttribute('id');
|
||||||
|
id.nodeValue = 'shift_state';
|
||||||
|
style.setAttributeNode(id);
|
||||||
|
var type = document.createAttribute('type');
|
||||||
|
type.nodeValue = 'text/css';
|
||||||
|
style.setAttributeNode(type);
|
||||||
|
document.getElementsByTagName('head')[0].appendChild(style);
|
||||||
|
|
||||||
|
// Set up key bindings
|
||||||
|
this.initializeKeyBindings(box);
|
||||||
|
};
|
||||||
|
|
||||||
VT100.prototype.initializeElements = function(container) {
|
VT100.prototype.initializeElements = function(container) {
|
||||||
// If the necessary objects have not already been defined in the HTML
|
// If the necessary objects have not already been defined in the HTML
|
||||||
// page, create them now.
|
// page, create them now.
|
||||||
|
@ -483,6 +805,9 @@ VT100.prototype.initializeElements = function(container) {
|
||||||
|
|
||||||
if (!this.getChildById(this.container, 'reconnect') ||
|
if (!this.getChildById(this.container, 'reconnect') ||
|
||||||
!this.getChildById(this.container, 'menu') ||
|
!this.getChildById(this.container, 'menu') ||
|
||||||
|
!this.getChildById(this.container, 'keyboard') ||
|
||||||
|
!this.getChildById(this.container, 'kbd_button') ||
|
||||||
|
!this.getChildById(this.container, 'kbd_img') ||
|
||||||
!this.getChildById(this.container, 'scrollable') ||
|
!this.getChildById(this.container, 'scrollable') ||
|
||||||
!this.getChildById(this.container, 'console') ||
|
!this.getChildById(this.container, 'console') ||
|
||||||
!this.getChildById(this.container, 'alt_console') ||
|
!this.getChildById(this.container, 'alt_console') ||
|
||||||
|
@ -525,7 +850,15 @@ VT100.prototype.initializeElements = function(container) {
|
||||||
'<div id="cursize" style="visibility: hidden">' +
|
'<div id="cursize" style="visibility: hidden">' +
|
||||||
'</div>' +
|
'</div>' +
|
||||||
'<div id="menu"></div>' +
|
'<div id="menu"></div>' +
|
||||||
|
'<div id="keyboard" unselectable="on">' +
|
||||||
|
'<pre class="box"><div><i id="27">Esc</i><i id="112">F1</i><i id="113">F2</i><i id="114">F3</i><i id="115">F4</i><i id="116">F5</i><i id="117">F6</i><i id="118">F7</i><i id="119">F8</i><i id="120">F9</i><i id="121">F10</i><i id="122">F11</i><i id="123">F12</i><br /><b><span class="unshifted">`</span><span class="shifted">~</span></b><b><span class="unshifted">1</span><span class="shifted">!</span></b><b><span class="unshifted">2</span><span class="shifted">@</span></b><b><span class="unshifted">3</span><span class="shifted">#</span></b><b><span class="unshifted">4</span><span class="shifted">$</span></b><b><span class="unshifted">5</span><span class="shifted">%</span></b><b><span class="unshifted">6</span><span class="shifted">^</span></b><b><span class="unshifted">7</span><span class="shifted">&</span></b><b><span class="unshifted">8</span><span class="shifted">*</span></b><b><span class="unshifted">9</span><span class="shifted">(</span></b><b><span class="unshifted">0</span><span class="shifted">)</span></b><b><span class="unshifted">-</span><span class="shifted">_</span></b><b><span class="unshifted">=</span><span class="shifted">+</span></b><i id="8"> ← </i><br /><i id="9">Tab</i><b>Q</b><b>W</b><b>E</b><b>R</b><b>T</b><b>Y</b><b>U</b><b>I</b><b>O</b><b>P</b><b><span class="unshifted">[</span><span class="shifted">{</span></b><b><span class="unshifted">]</span><span class="shifted">}</span></b><b><span class="unshifted">\</span><span class="shifted">|</span></b><br /><u>Tab </u><b>A</b><b>S</b><b>D</b><b>F</b><b>G</b><b>H</b><b>J</b><b>K</b><b>L</b><b><span class="unshifted">;</span><span class="shifted">:</span></b><b><span class="unshifted">'</span><span class="shifted">"</span></b><i id="13">Enter</i><br /><u> </u><i id="16">Shift</i><b>Z</b><b>X</b><b>C</b><b>V</b><b>B</b><b>N</b><b>M</b><b><span class="unshifted">,</span><span class="shifted"><</span></b><b><span class="unshifted">.</span><span class="shifted">></span></b><b><span class="unshifted">/</span><span class="shifted">?</span></b><i id="16">Shift</i><br /><u>XXX</u><i id="17">Ctrl</i><i id="18">Alt</i><i style="width: 25ex"> </i></div> <div><i id="45">Ins</i><i id="46">Del</i><i id="36">Home</i><i id="35">End</i><br /><u> </u><br /><u> </u><br /><u>Ins</u><s> </s><b id="38">↑</b><s> </s><u> </u><b id="33">⇑</b><br /><u>Ins</u><b id="37">←</b><b id="40">↓</b><b id="39">→</b><u> </u><b id="34">⇓</b></div></pre>' +
|
||||||
|
'</div>' +
|
||||||
'<div id="scrollable">' +
|
'<div id="scrollable">' +
|
||||||
|
'<table id="kbd_button">' +
|
||||||
|
'<tr><td width="100%"> </td>' +
|
||||||
|
'<td><img id="kbd_img" src="keyboard.png" /></td>' +
|
||||||
|
'<td> </td></tr>' +
|
||||||
|
'</table>' +
|
||||||
'<pre id="lineheight"> </pre>' +
|
'<pre id="lineheight"> </pre>' +
|
||||||
'<pre id="console">' +
|
'<pre id="console">' +
|
||||||
'<pre></pre>' +
|
'<pre></pre>' +
|
||||||
|
@ -566,6 +899,8 @@ VT100.prototype.initializeElements = function(container) {
|
||||||
this.reconnectBtn = this.getChildById(this.container,'reconnect');
|
this.reconnectBtn = this.getChildById(this.container,'reconnect');
|
||||||
this.curSizeBox = this.getChildById(this.container, 'cursize');
|
this.curSizeBox = this.getChildById(this.container, 'cursize');
|
||||||
this.menu = this.getChildById(this.container, 'menu');
|
this.menu = this.getChildById(this.container, 'menu');
|
||||||
|
this.keyboard = this.getChildById(this.container, 'keyboard');
|
||||||
|
this.keyboardImage = this.getChildById(this.container, 'kbd_img');
|
||||||
this.scrollable = this.getChildById(this.container,
|
this.scrollable = this.getChildById(this.container,
|
||||||
'scrollable');
|
'scrollable');
|
||||||
this.lineheight = this.getChildById(this.container,
|
this.lineheight = this.getChildById(this.container,
|
||||||
|
@ -646,6 +981,9 @@ VT100.prototype.initializeElements = function(container) {
|
||||||
// Hide context menu
|
// Hide context menu
|
||||||
this.hideContextMenu();
|
this.hideContextMenu();
|
||||||
|
|
||||||
|
// Set up onscreen soft keyboard
|
||||||
|
this.initializeKeyboard();
|
||||||
|
|
||||||
// Add listener to reconnect button
|
// Add listener to reconnect button
|
||||||
this.addListener(this.reconnectBtn.firstChild, 'click',
|
this.addListener(this.reconnectBtn.firstChild, 'click',
|
||||||
function(vt100) {
|
function(vt100) {
|
||||||
|
@ -733,6 +1071,7 @@ VT100.prototype.reconnect = function() {
|
||||||
|
|
||||||
VT100.prototype.showReconnect = function(state) {
|
VT100.prototype.showReconnect = function(state) {
|
||||||
if (state) {
|
if (state) {
|
||||||
|
this.hideSoftKeyboard();
|
||||||
this.reconnectBtn.style.visibility = '';
|
this.reconnectBtn.style.visibility = '';
|
||||||
} else {
|
} else {
|
||||||
this.reconnectBtn.style.visibility = 'hidden';
|
this.reconnectBtn.style.visibility = 'hidden';
|
||||||
|
@ -766,6 +1105,9 @@ VT100.prototype.resized = function(w, h) {
|
||||||
};
|
};
|
||||||
|
|
||||||
VT100.prototype.resizer = function() {
|
VT100.prototype.resizer = function() {
|
||||||
|
// Hide onscreen soft keyboard
|
||||||
|
this.hideSoftKeyboard();
|
||||||
|
|
||||||
// The cursor can get corrupted if the print-preview is displayed in Firefox.
|
// The cursor can get corrupted if the print-preview is displayed in Firefox.
|
||||||
// Recreating it, will repair it.
|
// Recreating it, will repair it.
|
||||||
var newCursor = document.createElement('pre');
|
var newCursor = document.createElement('pre');
|
||||||
|
@ -945,6 +1287,17 @@ VT100.prototype.cancelEvent = function(event) {
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
VT100.prototype.mousePosition = function(event) {
|
||||||
|
var offsetX = this.container.offsetLeft;
|
||||||
|
var offsetY = this.container.offsetTop;
|
||||||
|
for (var e = this.container; e = e.offsetParent; ) {
|
||||||
|
offsetX += e.offsetLeft;
|
||||||
|
offsetY += e.offsetTop;
|
||||||
|
}
|
||||||
|
return [ event.clientX - offsetX,
|
||||||
|
event.clientY - offsetY ];
|
||||||
|
};
|
||||||
|
|
||||||
VT100.prototype.mouseEvent = function(event, type) {
|
VT100.prototype.mouseEvent = function(event, type) {
|
||||||
// If any text is currently selected, do not move the focus as that would
|
// If any text is currently selected, do not move the focus as that would
|
||||||
// invalidate the selection.
|
// invalidate the selection.
|
||||||
|
@ -954,15 +1307,10 @@ VT100.prototype.mouseEvent = function(event, type) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compute mouse position in characters.
|
// Compute mouse position in characters.
|
||||||
var offsetX = this.container.offsetLeft;
|
var position = this.mousePosition(event);
|
||||||
var offsetY = this.container.offsetTop;
|
var x = Math.floor(position[0] / this.cursorWidth);
|
||||||
for (var e = this.container; e = e.offsetParent; ) {
|
var y = Math.floor((position[1] + this.scrollable.scrollTop) /
|
||||||
offsetX += e.offsetLeft;
|
this.cursorHeight) - this.numScrollbackLines;
|
||||||
offsetY += e.offsetTop;
|
|
||||||
}
|
|
||||||
var x = (event.clientX - offsetX) / this.cursorWidth;
|
|
||||||
var y = ((event.clientY - offsetY) + this.scrollable.offsetTop) /
|
|
||||||
this.cursorHeight - this.numScrollbackLines;
|
|
||||||
var inside = true;
|
var inside = true;
|
||||||
if (x >= this.terminalWidth) {
|
if (x >= this.terminalWidth) {
|
||||||
x = this.terminalWidth - 1;
|
x = this.terminalWidth - 1;
|
||||||
|
@ -1022,7 +1370,7 @@ VT100.prototype.mouseEvent = function(event, type) {
|
||||||
// Bring up context menu.
|
// Bring up context menu.
|
||||||
if (button == 2 && !event.shiftKey) {
|
if (button == 2 && !event.shiftKey) {
|
||||||
if (type == 0 /* MOUSE_DOWN */) {
|
if (type == 0 /* MOUSE_DOWN */) {
|
||||||
this.showContextMenu(event.clientX - offsetX, event.clientY - offsetY);
|
this.showContextMenu(position[0], position[1]);
|
||||||
}
|
}
|
||||||
return this.cancelEvent(event);
|
return this.cancelEvent(event);
|
||||||
}
|
}
|
||||||
|
@ -1058,6 +1406,29 @@ VT100.prototype.getTextContent = function(elem) {
|
||||||
(typeof elem.textContent == 'undefined' ? elem.innerText : '');
|
(typeof elem.textContent == 'undefined' ? elem.innerText : '');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
VT100.prototype.setTextContentRaw = function(elem, s) {
|
||||||
|
// Updating the content of an element is an expensive operation. It actually
|
||||||
|
// pays off to first check whether the element is still unchanged.
|
||||||
|
if (typeof elem.textContent == 'undefined') {
|
||||||
|
if (elem.innerText != s) {
|
||||||
|
try {
|
||||||
|
elem.innerText = s;
|
||||||
|
} catch (e) {
|
||||||
|
// Very old versions of IE do not allow setting innerText. Instead,
|
||||||
|
// remove all children, by setting innerHTML and then set the text
|
||||||
|
// using DOM methods.
|
||||||
|
elem.innerHTML = '';
|
||||||
|
elem.appendChild(document.createTextNode(
|
||||||
|
this.replaceChar(s, ' ', '\u00A0')));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (elem.textContent != s) {
|
||||||
|
elem.textContent = s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
VT100.prototype.setTextContent = function(elem, s) {
|
VT100.prototype.setTextContent = function(elem, s) {
|
||||||
// Check if we find any URLs in the text. If so, automatically convert them
|
// Check if we find any URLs in the text. If so, automatically convert them
|
||||||
// to links.
|
// to links.
|
||||||
|
@ -1103,26 +1474,7 @@ VT100.prototype.setTextContent = function(elem, s) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Updating the content of an element is an expensive operation. It actually
|
this.setTextContentRaw(elem, s);
|
||||||
// pays off to first check whether the element is still unchanged.
|
|
||||||
if (typeof elem.textContent == 'undefined') {
|
|
||||||
if (elem.innerText != s) {
|
|
||||||
try {
|
|
||||||
elem.innerText = s;
|
|
||||||
} catch (e) {
|
|
||||||
// Very old versions of IE do not allow setting innerText. Instead,
|
|
||||||
// remove all children, by setting innerHTML and then set the text
|
|
||||||
// using DOM methods.
|
|
||||||
elem.innerHTML = '';
|
|
||||||
elem.appendChild(document.createTextNode(
|
|
||||||
this.replaceChar(s, ' ', '\u00A0')));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (elem.textContent != s) {
|
|
||||||
elem.textContent = s;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
VT100.prototype.insertBlankLine = function(y, color, style) {
|
VT100.prototype.insertBlankLine = function(y, color, style) {
|
||||||
|
@ -1578,27 +1930,21 @@ VT100.prototype.enableAlternateScreen = function(state) {
|
||||||
this.console[this.currentScreen].style.display = '';
|
this.console[this.currentScreen].style.display = '';
|
||||||
|
|
||||||
// Select appropriate character pitch.
|
// Select appropriate character pitch.
|
||||||
var styles = [ 'transform',
|
var transform = this.getTransformName();
|
||||||
'WebkitTransform',
|
if (transform) {
|
||||||
'MozTransform',
|
if (state) {
|
||||||
'filter' ];
|
// Upon enabling the alternate screen, we switch to 80 column mode. But
|
||||||
for (var i = 0; i < styles.length; ++i) {
|
// upon returning to the regular screen, we restore the mode that was
|
||||||
if (typeof this.console[0].style[styles[i]] != 'undefined') {
|
// in effect previously.
|
||||||
if (state) {
|
this.console[1].style[transform] = '';
|
||||||
// Upon enabling the alternate screen, we switch to 80 column mode. But
|
}
|
||||||
// upon returning to the regular screen, we restore the mode that was
|
var style =
|
||||||
// in effect previously.
|
this.console[this.currentScreen].style[transform];
|
||||||
this.console[1].style[styles[i]] = '';
|
this.cursor.style[transform] = style;
|
||||||
}
|
this.space.style[transform] = style;
|
||||||
var style =
|
this.scale = style == '' ? 1.0:1.65;
|
||||||
this.console[this.currentScreen].style[styles[i]];
|
if (transform == 'filter') {
|
||||||
this.cursor.style[styles[i]] = style;
|
this.console[this.currentScreen].style.width = style == '' ? '165%':'';
|
||||||
this.space.style[styles[i]] = style;
|
|
||||||
this.scale = style == '' ? 1.0:1.65;
|
|
||||||
if (styles[i] == 'filter') {
|
|
||||||
this.console[this.currentScreen].style.width = style == '' ? '165%':'';
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.resizer();
|
this.resizer();
|
||||||
|
@ -1969,12 +2315,76 @@ VT100.prototype.toggleBell = function() {
|
||||||
this.visualBell = !this.visualBell;
|
this.visualBell = !this.visualBell;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
VT100.prototype.toggleSoftKeyboard = function() {
|
||||||
|
this.softKeyboard = !this.softKeyboard;
|
||||||
|
this.keyboardImage.style.visibility = this.softKeyboard ? 'visible' : '';
|
||||||
|
};
|
||||||
|
|
||||||
|
VT100.prototype.deselectKeys = function(elem) {
|
||||||
|
if (elem && elem.className == 'selected') {
|
||||||
|
elem.className = '';
|
||||||
|
}
|
||||||
|
for (elem = elem.firstChild; elem; elem = elem.nextSibling) {
|
||||||
|
this.deselectKeys(elem);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
VT100.prototype.showSoftKeyboard = function() {
|
||||||
|
// Make sure no key is currently selected
|
||||||
|
this.lastSelectedKey = undefined;
|
||||||
|
this.deselectKeys(this.keyboard);
|
||||||
|
this.isShift = false;
|
||||||
|
this.showShiftState(false);
|
||||||
|
this.isCtrl = false;
|
||||||
|
this.showCtrlState(false);
|
||||||
|
this.isAlt = false;
|
||||||
|
this.showAltState(false);
|
||||||
|
|
||||||
|
this.keyboard.style.left = '0px';
|
||||||
|
this.keyboard.style.top = '0px';
|
||||||
|
this.keyboard.style.width = this.container.offsetWidth + 'px';
|
||||||
|
this.keyboard.style.height = this.container.offsetHeight + 'px';
|
||||||
|
this.keyboard.style.visibility = 'hidden';
|
||||||
|
this.keyboard.style.display = '';
|
||||||
|
|
||||||
|
var kbd = this.keyboard.firstChild;
|
||||||
|
var scale = 1.0;
|
||||||
|
var transform = this.getTransformName();
|
||||||
|
if (transform) {
|
||||||
|
kbd.style[transform] = '';
|
||||||
|
if (kbd.offsetWidth > 0.9 * this.container.offsetWidth) {
|
||||||
|
scale = (kbd.offsetWidth/
|
||||||
|
this.container.offsetWidth)/0.9;
|
||||||
|
}
|
||||||
|
if (kbd.offsetHeight > 0.9 * this.container.offsetHeight) {
|
||||||
|
scale = Math.max((kbd.offsetHeight/
|
||||||
|
this.container.offsetHeight)/0.9);
|
||||||
|
}
|
||||||
|
var style = this.getTransformStyle(transform,
|
||||||
|
scale > 1.0 ? scale : undefined);
|
||||||
|
kbd.style[transform] = style;
|
||||||
|
}
|
||||||
|
if (transform == 'filter') {
|
||||||
|
scale = 1.0;
|
||||||
|
}
|
||||||
|
kbd.style.left = ((this.container.offsetWidth -
|
||||||
|
kbd.offsetWidth/scale)/2) + 'px';
|
||||||
|
kbd.style.top = ((this.container.offsetHeight -
|
||||||
|
kbd.offsetHeight/scale)/2) + 'px';
|
||||||
|
|
||||||
|
this.keyboard.style.visibility = 'visible';
|
||||||
|
};
|
||||||
|
|
||||||
|
VT100.prototype.hideSoftKeyboard = function() {
|
||||||
|
this.keyboard.style.display = 'none';
|
||||||
|
};
|
||||||
|
|
||||||
VT100.prototype.toggleCursorBlinking = function() {
|
VT100.prototype.toggleCursorBlinking = function() {
|
||||||
this.blinkingCursor = !this.blinkingCursor;
|
this.blinkingCursor = !this.blinkingCursor;
|
||||||
};
|
};
|
||||||
|
|
||||||
VT100.prototype.about = function() {
|
VT100.prototype.about = function() {
|
||||||
alert("VT100 Terminal Emulator " + "2.10 (revision 220)" +
|
alert("VT100 Terminal Emulator " + "2.10 (revision 221)" +
|
||||||
"\nCopyright 2008-2010 by Markus Gutschke\n" +
|
"\nCopyright 2008-2010 by Markus Gutschke\n" +
|
||||||
"For more information check http://shellinabox.com");
|
"For more information check http://shellinabox.com");
|
||||||
};
|
};
|
||||||
|
@ -2007,6 +2417,9 @@ VT100.prototype.showContextMenu = function(x, y) {
|
||||||
'<li>' +
|
'<li>' +
|
||||||
(this.visualBell ? '<img src="enabled.gif" />' : '') +
|
(this.visualBell ? '<img src="enabled.gif" />' : '') +
|
||||||
'Visual Bell</li>'+
|
'Visual Bell</li>'+
|
||||||
|
'<li>' +
|
||||||
|
(this.softKeyboard ? '<img src="enabled.gif" />' : '') +
|
||||||
|
'Onscreen Keyboard</li>' +
|
||||||
'<li id="endconfig">' +
|
'<li id="endconfig">' +
|
||||||
(this.blinkingCursor ? '<img src="enabled.gif" />' : '') +
|
(this.blinkingCursor ? '<img src="enabled.gif" />' : '') +
|
||||||
'Blinking Cursor</li>'+
|
'Blinking Cursor</li>'+
|
||||||
|
@ -2038,6 +2451,7 @@ VT100.prototype.showContextMenu = function(x, y) {
|
||||||
// Actions for default items
|
// Actions for default items
|
||||||
var actions = [ this.copyLast, p, this.reset,
|
var actions = [ this.copyLast, p, this.reset,
|
||||||
this.toggleUTF, this.toggleBell,
|
this.toggleUTF, this.toggleBell,
|
||||||
|
this.toggleSoftKeyboard,
|
||||||
this.toggleCursorBlinking ];
|
this.toggleCursorBlinking ];
|
||||||
|
|
||||||
// Actions for user CSS styles (if any)
|
// Actions for user CSS styles (if any)
|
||||||
|
@ -2093,26 +2507,30 @@ VT100.prototype.showContextMenu = function(x, y) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Position menu next to the mouse pointer
|
// Position menu next to the mouse pointer
|
||||||
if (x + popup.clientWidth > this.container.offsetWidth) {
|
this.menu.style.left = '0px';
|
||||||
x = this.container.offsetWidth - popup.clientWidth;
|
this.menu.style.top = '0px';
|
||||||
|
this.menu.style.width = this.container.offsetWidth + 'px';
|
||||||
|
this.menu.style.height = this.container.offsetHeight + 'px';
|
||||||
|
popup.style.left = '0px';
|
||||||
|
popup.style.top = '0px';
|
||||||
|
|
||||||
|
var margin = 2;
|
||||||
|
if (x + popup.clientWidth >= this.container.offsetWidth - margin) {
|
||||||
|
x = this.container.offsetWidth-popup.clientWidth - margin - 1;
|
||||||
}
|
}
|
||||||
if (x < 0) {
|
if (x < margin) {
|
||||||
x = 0;
|
x = margin;
|
||||||
}
|
}
|
||||||
if (y + popup.clientHeight > this.container.offsetHeight) {
|
if (y + popup.clientHeight >= this.container.offsetHeight - margin) {
|
||||||
y = this.container.offsetHeight-popup.clientHeight;
|
y = this.container.offsetHeight-popup.clientHeight - margin - 1;
|
||||||
}
|
}
|
||||||
if (y < 0) {
|
if (y < margin) {
|
||||||
y = 0;
|
y = margin;
|
||||||
}
|
}
|
||||||
popup.style.left = x + 'px';
|
popup.style.left = x + 'px';
|
||||||
popup.style.top = y + 'px';
|
popup.style.top = y + 'px';
|
||||||
|
|
||||||
// Block all other interactions with the terminal emulator
|
// Block all other interactions with the terminal emulator
|
||||||
this.menu.style.left = '0px';
|
|
||||||
this.menu.style.top = '0px';
|
|
||||||
this.menu.style.width = this.container.offsetWidth + 'px';
|
|
||||||
this.menu.style.height = this.container.offsetHeight + 'px';
|
|
||||||
this.addListener(this.menu, 'click', function(vt100) {
|
this.addListener(this.menu, 'click', function(vt100) {
|
||||||
return function() {
|
return function() {
|
||||||
vt100.hideContextMenu();
|
vt100.hideContextMenu();
|
||||||
|
@ -2895,39 +3313,42 @@ VT100.prototype.restoreCursor = function() {
|
||||||
this.savedY[this.currentScreen]);
|
this.savedY[this.currentScreen]);
|
||||||
};
|
};
|
||||||
|
|
||||||
VT100.prototype.set80_132Mode = function(state) {
|
VT100.prototype.getTransformName = function() {
|
||||||
var transform = undefined;
|
var styles = [ 'transform', 'WebkitTransform', 'MozTransform', 'filter' ];
|
||||||
var styles = [ 'transform',
|
|
||||||
'WebkitTransform',
|
|
||||||
'MozTransform',
|
|
||||||
'filter'
|
|
||||||
];
|
|
||||||
for (var i = 0; i < styles.length; ++i) {
|
for (var i = 0; i < styles.length; ++i) {
|
||||||
if (typeof this.console[0].style[styles[i]] != 'undefined') {
|
if (typeof this.console[0].style[styles[i]] != 'undefined') {
|
||||||
transform = styles[i];
|
return styles[i];
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
VT100.prototype.getTransformStyle = function(transform, scale) {
|
||||||
|
return scale && scale != 1.0
|
||||||
|
? transform == 'filter'
|
||||||
|
? 'progid:DXImageTransform.Microsoft.Matrix(' +
|
||||||
|
'M11=' + (1.0/scale) + ',M12=0,M21=0,M22=1,' +
|
||||||
|
"sizingMethod='auto expand')"
|
||||||
|
: 'translateX(-50%) ' +
|
||||||
|
'scaleX(' + (1.0/scale) + ') ' +
|
||||||
|
'translateX(50%)'
|
||||||
|
: '';
|
||||||
|
};
|
||||||
|
|
||||||
|
VT100.prototype.set80_132Mode = function(state) {
|
||||||
|
var transform = this.getTransformName();
|
||||||
if (transform) {
|
if (transform) {
|
||||||
if ((this.console[this.currentScreen].style[transform] != '') == state) {
|
if ((this.console[this.currentScreen].style[transform] != '') == state) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var style =
|
var style = state ?
|
||||||
state ? transform == 'filter'
|
this.getTransformStyle(transform, 1.65):'';
|
||||||
? 'progid:DXImageTransform.Microsoft.Matrix(' +
|
|
||||||
'M11=0.606060606060606060606,M12=0,M21=0,M22=1,' +
|
|
||||||
"sizingMethod='auto expand')"
|
|
||||||
: 'translateX(-50%) ' +
|
|
||||||
'scaleX(0.606060606060606060606) ' +
|
|
||||||
'translateX(50%)'
|
|
||||||
: '';
|
|
||||||
this.console[this.currentScreen].style[transform] = style;
|
this.console[this.currentScreen].style[transform] = style;
|
||||||
this.cursor.style[transform] = style;
|
this.cursor.style[transform] = style;
|
||||||
this.space.style[transform] = style;
|
this.space.style[transform] = style;
|
||||||
this.scale = state ? 1.65 : 1.0;
|
this.scale = state ? 1.65 : 1.0;
|
||||||
if (transform == 'filter') {
|
if (transform == 'filter') {
|
||||||
this.console[this.currentScreen].style.width = state ? '165%' : '';
|
this.console[this.currentScreen].style.width = state ? '165%' : '';
|
||||||
}
|
}
|
||||||
this.resizer();
|
this.resizer();
|
||||||
}
|
}
|
||||||
|
|
59
shellinabox/keyboard-layout.html
Normal file
59
shellinabox/keyboard-layout.html
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
<pre class="box">
|
||||||
|
<div>
|
||||||
|
<i id="27">Esc</i><i id="112">F1</i><i id="113">F2</i><i id="114">F3</i>
|
||||||
|
<i id="115">F4</i><i id="116">F5</i><i id="117">F6</i><i id="118">F7</i>
|
||||||
|
<i id="119">F8</i><i id="120">F9</i><i id="121">F10</i><i id="122">F11</i>
|
||||||
|
<i id="123">F12</i><br />
|
||||||
|
<b><span class="unshifted">`</span><span class="shifted">~</span></b>
|
||||||
|
<b><span class="unshifted">1</span><span class="shifted">!</span></b>
|
||||||
|
<b><span class="unshifted">2</span><span class="shifted">@</span></b>
|
||||||
|
<b><span class="unshifted">3</span><span class="shifted">#</span></b>
|
||||||
|
<b><span class="unshifted">4</span><span class="shifted">$</span></b>
|
||||||
|
<b><span class="unshifted">5</span><span class="shifted">%</span></b>
|
||||||
|
<b><span class="unshifted">6</span><span class="shifted">^</span></b>
|
||||||
|
<b><span class="unshifted">7</span><span class="shifted">&</span></b>
|
||||||
|
<b><span class="unshifted">8</span><span class="shifted">*</span></b>
|
||||||
|
<b><span class="unshifted">9</span><span class="shifted">(</span></b>
|
||||||
|
<b><span class="unshifted">0</span><span class="shifted">)</span></b>
|
||||||
|
<b><span class="unshifted">-</span><span class="shifted">_</span></b>
|
||||||
|
<b><span class="unshifted">=</span><span class="shifted">+</span></b>
|
||||||
|
<i id="8"> ← </i>
|
||||||
|
<br />
|
||||||
|
<i id="9">Tab</i>
|
||||||
|
<b>Q</b><b>W</b><b>E</b><b>R</b><b>T</b><b>Y</b><b>U</b><b>I</b><b>O</b>
|
||||||
|
<b>P</b>
|
||||||
|
<b><span class="unshifted">[</span><span class="shifted">{</span></b>
|
||||||
|
<b><span class="unshifted">]</span><span class="shifted">}</span></b>
|
||||||
|
<b><span class="unshifted">\</span><span class="shifted">|</span></b>
|
||||||
|
<br />
|
||||||
|
<u>Tab </u>
|
||||||
|
<b>A</b><b>S</b><b>D</b><b>F</b><b>G</b><b>H</b><b>J</b><b>K</b><b>L</b>
|
||||||
|
<b><span class="unshifted">;</span><span class="shifted">:</span></b>
|
||||||
|
<b><span class="unshifted">'</span><span class="shifted">"</span></b>
|
||||||
|
<i id="13">Enter</i>
|
||||||
|
<br />
|
||||||
|
<u> </u>
|
||||||
|
<i id="16">Shift</i>
|
||||||
|
<b>Z</b><b>X</b><b>C</b><b>V</b><b>B</b><b>N</b><b>M</b>
|
||||||
|
<b><span class="unshifted">,</span><span class="shifted"><</span></b>
|
||||||
|
<b><span class="unshifted">.</span><span class="shifted">></span></b>
|
||||||
|
<b><span class="unshifted">/</span><span class="shifted">?</span></b>
|
||||||
|
<i id="16">Shift</i>
|
||||||
|
<br />
|
||||||
|
<u>XXX</u>
|
||||||
|
<i id="17">Ctrl</i>
|
||||||
|
<i id="18">Alt</i>
|
||||||
|
<i style="width: 25ex"> </i>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<i id="45">Ins</i><i id="46">Del</i><i id="36">Home</i><i id="35">End</i>
|
||||||
|
<br />
|
||||||
|
<u> </u><br />
|
||||||
|
<u> </u><br />
|
||||||
|
<u>Ins</u><s> </s><b id="38">↑</b><s> </s><u> </u>
|
||||||
|
<b id="33">⇑</b><br />
|
||||||
|
<u>Ins</u><b id="37">←</b><b id="40">↓</b>
|
||||||
|
<b id="39">→</b><u> </u><b id="34">⇓</b>
|
||||||
|
</div>
|
||||||
|
</pre>
|
BIN
shellinabox/keyboard.png
Normal file
BIN
shellinabox/keyboard.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 808 B |
|
@ -358,7 +358,7 @@ ShellInABox.prototype.extendContextMenu = function(entries, actions) {
|
||||||
};
|
};
|
||||||
|
|
||||||
ShellInABox.prototype.about = function() {
|
ShellInABox.prototype.about = function() {
|
||||||
alert("Shell In A Box version " + "2.10 (revision 220)" +
|
alert("Shell In A Box version " + "2.10 (revision 221)" +
|
||||||
"\nCopyright 2008-2010 by Markus Gutschke\n" +
|
"\nCopyright 2008-2010 by Markus Gutschke\n" +
|
||||||
"For more information check http://shellinabox.com" +
|
"For more information check http://shellinabox.com" +
|
||||||
(typeof serverSupportsSSL != 'undefined' && serverSupportsSSL ?
|
(typeof serverSupportsSSL != 'undefined' && serverSupportsSSL ?
|
||||||
|
|
|
@ -641,6 +641,11 @@ static int shellInABoxHttpHandler(HttpConnection *http, void *arg,
|
||||||
extern char faviconStart[];
|
extern char faviconStart[];
|
||||||
extern char faviconEnd[];
|
extern char faviconEnd[];
|
||||||
serveStaticFile(http, "image/x-icon", faviconStart, faviconEnd);
|
serveStaticFile(http, "image/x-icon", faviconStart, faviconEnd);
|
||||||
|
} else if (pathInfoLength == 12 && !memcmp(pathInfo, "keyboard.png", 11)) {
|
||||||
|
// Serve the keyboard icon
|
||||||
|
extern char keyboardStart[];
|
||||||
|
extern char keyboardEnd[];
|
||||||
|
serveStaticFile(http, "image/png", keyboardStart, keyboardEnd);
|
||||||
} else if (pathInfoLength == 14 && !memcmp(pathInfo, "ShellInABox.js", 14)) {
|
} else if (pathInfoLength == 14 && !memcmp(pathInfo, "ShellInABox.js", 14)) {
|
||||||
// Serve both vt100.js and shell_in_a_box.js in the same transaction.
|
// Serve both vt100.js and shell_in_a_box.js in the same transaction.
|
||||||
// Also, indicate to the client whether the server is SSL enabled.
|
// Also, indicate to the client whether the server is SSL enabled.
|
||||||
|
|
|
@ -1,140 +1,217 @@
|
||||||
#vt100 a {
|
#vt100 a {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
color: inherit;
|
color: inherit;
|
||||||
}
|
}
|
||||||
|
|
||||||
#vt100 a:hover {
|
#vt100 a:hover {
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
}
|
}
|
||||||
|
|
||||||
#vt100 #reconnect {
|
#vt100 #reconnect {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
#vt100 #reconnect input {
|
#vt100 #reconnect input {
|
||||||
padding: 1ex;
|
padding: 1ex;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
font-size: x-large;
|
font-size: x-large;
|
||||||
}
|
}
|
||||||
|
|
||||||
#vt100 #cursize {
|
#vt100 #cursize {
|
||||||
background: #EEEEEE;
|
background: #EEEEEE;
|
||||||
border: 1px solid black;
|
border: 1px solid black;
|
||||||
font-family: sans-serif;
|
font-family: sans-serif;
|
||||||
font-size: large;
|
font-size: large;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
padding: 1ex;
|
padding: 1ex;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
#vt100 pre {
|
#vt100 pre {
|
||||||
margin: 0px;
|
margin: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#vt100 pre pre {
|
#vt100 pre pre {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
#vt100 #scrollable {
|
#vt100 #scrollable {
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
overflow-y: scroll;
|
overflow-y: scroll;
|
||||||
position: relative;
|
position: relative;
|
||||||
padding: 1px;
|
padding: 1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#vt100 #console, #vt100 #alt_console, #vt100 #cursor, #vt100 #lineheight, #vt100 .hidden pre {
|
#vt100 #console, #vt100 #alt_console, #vt100 #cursor, #vt100 #lineheight, #vt100 .hidden pre {
|
||||||
font-family: "DejaVu Sans Mono", "Everson Mono", FreeMono, "Andale Mono", "Lucida Console", monospace;
|
font-family: "DejaVu Sans Mono", "Everson Mono", FreeMono, "Andale Mono", "Lucida Console", monospace;
|
||||||
}
|
}
|
||||||
|
|
||||||
#vt100 #lineheight {
|
#vt100 #lineheight {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
#vt100 #cursor {
|
#vt100 #cursor {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 0px;
|
left: 0px;
|
||||||
top: 0px;
|
top: 0px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#vt100 #cursor.bright {
|
#vt100 #cursor.bright {
|
||||||
background-color: #e60000;
|
background-color: #e60000;
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
#vt100 #cursor.dim {
|
#vt100 #cursor.dim {
|
||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
#vt100 #cursor.inactive {
|
#vt100 #cursor.inactive {
|
||||||
border: 1px solid #e60000;
|
border: 1px solid #e60000;
|
||||||
margin: -1px;
|
margin: -1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#vt100 #padding {
|
#vt100 #padding {
|
||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
width: 1px;
|
width: 1px;
|
||||||
height: 0px;
|
height: 0px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
#vt100 .hidden {
|
#vt100 .hidden {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: -10000px;
|
top: -10000px;
|
||||||
left: -10000px;
|
left: -10000px;
|
||||||
width: 0px;
|
width: 0px;
|
||||||
height: 0px;
|
height: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#vt100 #menu {
|
#vt100 #menu {
|
||||||
overflow: visible;
|
overflow: visible;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: 3;
|
z-index: 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
#vt100 #menu .popup {
|
#vt100 #menu .popup {
|
||||||
background-color: #EEEEEE;
|
background-color: #EEEEEE;
|
||||||
border: 1px solid black;
|
border: 1px solid black;
|
||||||
font-family: sans-serif;
|
font-family: sans-serif;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
}
|
}
|
||||||
|
|
||||||
#vt100 #menu .popup ul {
|
#vt100 #menu .popup ul {
|
||||||
list-style-type: none;
|
list-style-type: none;
|
||||||
padding: 0px;
|
padding: 0px;
|
||||||
margin: 0px;
|
margin: 0px;
|
||||||
min-width: 10em;
|
min-width: 10em;
|
||||||
}
|
}
|
||||||
|
|
||||||
#vt100 #menu .popup li {
|
#vt100 #menu .popup li {
|
||||||
padding: 3px 0.5ex 3px 0.5ex;
|
padding: 3px 0.5ex 3px 0.5ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
#vt100 #menu .popup li.hover {
|
#vt100 #menu .popup li.hover {
|
||||||
background-color: #444444;
|
background-color: #444444;
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
#vt100 #menu .popup li.disabled {
|
#vt100 #menu .popup li.disabled {
|
||||||
color: #AAAAAA;
|
color: #AAAAAA;
|
||||||
}
|
}
|
||||||
|
|
||||||
#vt100 #menu .popup hr {
|
#vt100 #menu .popup hr {
|
||||||
margin: 0.5ex 0px 0.5ex 0px;
|
margin: 0.5ex 0px 0.5ex 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#vt100 #menu img {
|
#vt100 #menu img {
|
||||||
margin-right: 0.5ex;
|
margin-right: 0.5ex;
|
||||||
width: 1ex;
|
width: 1ex;
|
||||||
height: 1ex;
|
height: 1ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
#vt100 #scrollable.inverted { color: #ffffff;
|
#vt100 #scrollable.inverted { color: #ffffff;
|
||||||
background-color: #000000; }
|
background-color: #000000; }
|
||||||
|
|
||||||
|
#vt100 #kbd_button {
|
||||||
|
float: left;
|
||||||
|
position: fixed;
|
||||||
|
z-index: 0;
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
#vt100 #keyboard {
|
||||||
|
z-index: 3;
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
|
||||||
|
#vt100 #keyboard .box {
|
||||||
|
font-family: sans-serif;
|
||||||
|
background-color: #cccccc;
|
||||||
|
padding: .8em;
|
||||||
|
float: left;
|
||||||
|
position: absolute;
|
||||||
|
border-radius: 10px;
|
||||||
|
-moz-border-radius: 10px;
|
||||||
|
box-shadow: 4px 4px 6px #222222;
|
||||||
|
-webkit-box-shadow: 4px 4px 6px #222222;
|
||||||
|
/* Don't set the -moz-box-shadow. It doesn't properly scale when CSS
|
||||||
|
* transforms are in effect. Once Firefox supports box-shadow, it should
|
||||||
|
* automatically do the right thing. Until then, leave shadows disabled
|
||||||
|
* for Firefox.
|
||||||
|
*/
|
||||||
|
opacity: 0.85;
|
||||||
|
-moz-opacity: 0.85;
|
||||||
|
filter: alpha(opacity=85);
|
||||||
|
}
|
||||||
|
|
||||||
|
#vt100 #keyboard .box * {
|
||||||
|
vertical-align: top;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
#vt100 #keyboard b, #vt100 #keyboard i, #vt100 #keyboard s, #vt100 #keyboard u {
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: bold;
|
||||||
|
border-radius: 5px;
|
||||||
|
-moz-border-radius: 5px;
|
||||||
|
background-color: #555555;
|
||||||
|
color: #eeeeee;
|
||||||
|
box-shadow: 2px 2px 3px #222222;
|
||||||
|
-webkit-box-shadow: 2px 2px 3px #222222;
|
||||||
|
padding: 4px;
|
||||||
|
margin: 2px;
|
||||||
|
height: 2ex;
|
||||||
|
display: inline-block;
|
||||||
|
text-align: center;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#vt100 #keyboard b, #vt100 #keyboard s {
|
||||||
|
width: 2ex;
|
||||||
|
}
|
||||||
|
|
||||||
|
#vt100 #keyboard u, #vt100 #keyboard s {
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
#vt100 #keyboard .shifted {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#vt100 #keyboard .selected {
|
||||||
|
color: #888888;
|
||||||
|
background-color: #eeeeee;
|
||||||
|
box-shadow: 0px 0px 3px #222222;
|
||||||
|
-webkit-box-shadow: 0px 0px 3px #222222;
|
||||||
|
position: relative;
|
||||||
|
top: 1px;
|
||||||
|
left: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
[if DEFINES_COLORS]
|
[if DEFINES_COLORS]
|
||||||
/* IE cannot properly handle "inherit" properties. So, the monochrome.css/
|
/* IE cannot properly handle "inherit" properties. So, the monochrome.css/
|
||||||
* color.css style sheets cannot work, if we define colors in styles.css.
|
* color.css style sheets cannot work, if we define colors in styles.css.
|
||||||
|
@ -177,19 +254,19 @@
|
||||||
|
|
||||||
@media print {
|
@media print {
|
||||||
#vt100 .scrollback {
|
#vt100 .scrollback {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
#vt100 #reconnect, #vt100 #cursor, #vt100 #menu {
|
#vt100 #reconnect, #vt100 #cursor, #vt100 #menu, #vt100 #kbd_button, #vt100 #keyboard {
|
||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
#vt100 #scrollable {
|
#vt100 #scrollable {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
#vt100 #console, #vt100 #alt_console {
|
#vt100 #console, #vt100 #alt_console {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
width: 1000000ex;
|
width: 1000000ex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -238,22 +238,16 @@ VT100.prototype.reset = function(clearHistory) {
|
||||||
this.enableAlternateScreen(false);
|
this.enableAlternateScreen(false);
|
||||||
|
|
||||||
var wasCompressed = false;
|
var wasCompressed = false;
|
||||||
var styles = [ 'transform',
|
var transform = this.getTransformName();
|
||||||
'WebkitTransform',
|
if (transform) {
|
||||||
'MozTransform',
|
for (var i = 0; i < 2; ++i) {
|
||||||
'filter' ];
|
wasCompressed |= this.console[i].style[transform] != '';
|
||||||
for (var i = 0; i < styles.length; ++i) {
|
this.console[i].style[transform] = '';
|
||||||
if (typeof this.console[0].style[styles[i]] != 'undefined') {
|
}
|
||||||
for (var j = 0; j < 1; ++j) {
|
this.cursor.style[transform] = '';
|
||||||
wasCompressed |= this.console[j].style[styles[i]] != '';
|
this.space.style[transform] = '';
|
||||||
this.console[j].style[styles[i]] = '';
|
if (transform == 'filter') {
|
||||||
}
|
this.console[this.currentScreen].style.width = '';
|
||||||
this.cursor.style[styles[i]] = '';
|
|
||||||
this.space.style[styles[i]] = '';
|
|
||||||
if (styles[i] == 'filter') {
|
|
||||||
this.console[this.currentScreen].style.width = '';
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.scale = 1.0;
|
this.scale = 1.0;
|
||||||
|
@ -270,10 +264,13 @@ VT100.prototype.reset = function(clearHistory) {
|
||||||
};
|
};
|
||||||
|
|
||||||
VT100.prototype.addListener = function(elem, event, listener) {
|
VT100.prototype.addListener = function(elem, event, listener) {
|
||||||
if (elem.addEventListener) {
|
try {
|
||||||
elem.addEventListener(event, listener, false);
|
if (elem.addEventListener) {
|
||||||
} else {
|
elem.addEventListener(event, listener, false);
|
||||||
elem.attachEvent('on' + event, listener);
|
} else {
|
||||||
|
elem.attachEvent('on' + event, listener);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -281,11 +278,12 @@ VT100.prototype.getUserSettings = function() {
|
||||||
// Compute hash signature to identify the entries in the userCSS menu.
|
// Compute hash signature to identify the entries in the userCSS menu.
|
||||||
// If the menu is unchanged from last time, default values can be
|
// If the menu is unchanged from last time, default values can be
|
||||||
// looked up in a cookie associated with this page.
|
// looked up in a cookie associated with this page.
|
||||||
this.signature = 2;
|
this.signature = 3;
|
||||||
this.utfPreferred = true;
|
this.utfPreferred = true;
|
||||||
this.visualBell = typeof suppressAllAudio != 'undefined' &&
|
this.visualBell = typeof suppressAllAudio != 'undefined' &&
|
||||||
suppressAllAudio;
|
suppressAllAudio;
|
||||||
this.autoprint = true;
|
this.autoprint = true;
|
||||||
|
this.softKeyboard = false;
|
||||||
this.blinkingCursor = true;
|
this.blinkingCursor = true;
|
||||||
if (this.visualBell) {
|
if (this.visualBell) {
|
||||||
this.signature = Math.floor(16807*this.signature + 1) %
|
this.signature = Math.floor(16807*this.signature + 1) %
|
||||||
|
@ -311,15 +309,16 @@ VT100.prototype.getUserSettings = function() {
|
||||||
if (settings >= 0) {
|
if (settings >= 0) {
|
||||||
settings = document.cookie.substr(settings + key.length).
|
settings = document.cookie.substr(settings + key.length).
|
||||||
replace(/([0-1]*).*/, "$1");
|
replace(/([0-1]*).*/, "$1");
|
||||||
if (settings.length == 3 + (typeof userCSSList == 'undefined' ?
|
if (settings.length == 5 + (typeof userCSSList == 'undefined' ?
|
||||||
0 : userCSSList.length)) {
|
0 : userCSSList.length)) {
|
||||||
this.utfPreferred = settings.charAt(0) != '0';
|
this.utfPreferred = settings.charAt(0) != '0';
|
||||||
this.visualBell = settings.charAt(1) != '0';
|
this.visualBell = settings.charAt(1) != '0';
|
||||||
this.autoprint = settings.charAt(2) != '0';
|
this.autoprint = settings.charAt(2) != '0';
|
||||||
this.blinkingCursor = settings.charAt(3) != '0';
|
this.softKeyboard = settings.charAt(3) != '0';
|
||||||
|
this.blinkingCursor = settings.charAt(4) != '0';
|
||||||
if (typeof userCSSList != 'undefined') {
|
if (typeof userCSSList != 'undefined') {
|
||||||
for (var i = 0; i < userCSSList.length; ++i) {
|
for (var i = 0; i < userCSSList.length; ++i) {
|
||||||
userCSSList[i][2] = settings.charAt(i + 3) != '0';
|
userCSSList[i][2] = settings.charAt(i + 5) != '0';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -332,6 +331,7 @@ VT100.prototype.storeUserSettings = function() {
|
||||||
(this.utfEnabled ? '1' : '0') +
|
(this.utfEnabled ? '1' : '0') +
|
||||||
(this.visualBell ? '1' : '0') +
|
(this.visualBell ? '1' : '0') +
|
||||||
(this.autoprint ? '1' : '0') +
|
(this.autoprint ? '1' : '0') +
|
||||||
|
(this.softKeyboard ? '1' : '0') +
|
||||||
(this.blinkingCursor ? '1' : '0');
|
(this.blinkingCursor ? '1' : '0');
|
||||||
if (typeof userCSSList != 'undefined') {
|
if (typeof userCSSList != 'undefined') {
|
||||||
for (var i = 0; i < userCSSList.length; ++i) {
|
for (var i = 0; i < userCSSList.length; ++i) {
|
||||||
|
@ -413,7 +413,7 @@ VT100.prototype.initializeUserCSSStyles = function() {
|
||||||
label.textContent= label.textContent;
|
label.textContent= label.textContent;
|
||||||
}
|
}
|
||||||
|
|
||||||
// User style sheets are number sequentially
|
// User style sheets are numbered sequentially
|
||||||
var sheet = document.getElementById(
|
var sheet = document.getElementById(
|
||||||
'usercss-' + i);
|
'usercss-' + i);
|
||||||
if (i == current) {
|
if (i == current) {
|
||||||
|
@ -470,6 +470,328 @@ VT100.prototype.initializeUserCSSStyles = function() {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
VT100.prototype.resetLastSelectedKey = function(e) {
|
||||||
|
var key = this.lastSelectedKey;
|
||||||
|
if (!key) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var position = this.mousePosition(e);
|
||||||
|
|
||||||
|
// We don't get all the necessary events to reliably reselect a key
|
||||||
|
// if we moved away from it and then back onto it. We approximate the
|
||||||
|
// behavior by remembering the key until either we release the mouse
|
||||||
|
// button (we might never get this event if the mouse has since left
|
||||||
|
// the window), or until we move away too far.
|
||||||
|
var box = this.keyboard.firstChild;
|
||||||
|
if (position[0] < box.offsetLeft + key.offsetWidth ||
|
||||||
|
position[1] < box.offsetTop + key.offsetHeight ||
|
||||||
|
position[0] >= box.offsetLeft + box.offsetWidth - key.offsetWidth ||
|
||||||
|
position[1] >= box.offsetTop + box.offsetHeight - key.offsetHeight ||
|
||||||
|
position[0] < box.offsetLeft + key.offsetLeft - key.offsetWidth ||
|
||||||
|
position[1] < box.offsetTop + key.offsetTop - key.offsetHeight ||
|
||||||
|
position[0] >= box.offsetLeft + key.offsetLeft + 2*key.offsetWidth ||
|
||||||
|
position[1] >= box.offsetTop + key.offsetTop + 2*key.offsetHeight) {
|
||||||
|
if (this.lastSelectedKey.className) log.console('reset: deselecting');
|
||||||
|
this.lastSelectedKey.className = '';
|
||||||
|
this.lastSelectedKey = undefined;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
VT100.prototype.showShiftState = function(state) {
|
||||||
|
var style = document.getElementById('shift_state');
|
||||||
|
if (state) {
|
||||||
|
this.setTextContentRaw(style,
|
||||||
|
'#vt100 #keyboard .shifted {' +
|
||||||
|
'display: inline }' +
|
||||||
|
'#vt100 #keyboard .unshifted {' +
|
||||||
|
'display: none }');
|
||||||
|
} else {
|
||||||
|
this.setTextContentRaw(style, '');
|
||||||
|
}
|
||||||
|
var elems = this.keyboard.getElementsByTagName('I');
|
||||||
|
for (var i = 0; i < elems.length; ++i) {
|
||||||
|
if (elems[i].id == '16') {
|
||||||
|
elems[i].className = state ? 'selected' : '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
VT100.prototype.showCtrlState = function(state) {
|
||||||
|
var ctrl = this.getChildById(this.keyboard, '17' /* Ctrl */);
|
||||||
|
if (ctrl) {
|
||||||
|
ctrl.className = state ? 'selected' : '';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
VT100.prototype.showAltState = function(state) {
|
||||||
|
var alt = this.getChildById(this.keyboard, '18' /* Alt */);
|
||||||
|
if (alt) {
|
||||||
|
alt.className = state ? 'selected' : '';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
VT100.prototype.clickedKeyboard = function(e, elem, ch, key, shift, ctrl, alt){
|
||||||
|
var fake = [ ];
|
||||||
|
fake.charCode = ch;
|
||||||
|
fake.keyCode = key;
|
||||||
|
fake.ctrlKey = ctrl;
|
||||||
|
fake.shiftKey = shift;
|
||||||
|
fake.altKey = alt;
|
||||||
|
fake.metaKey = alt;
|
||||||
|
return this.handleKey(fake);
|
||||||
|
};
|
||||||
|
|
||||||
|
VT100.prototype.addKeyBinding = function(elem, ch, key, CH, KEY) {
|
||||||
|
if (elem == undefined) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (ch == '\u00A0') {
|
||||||
|
// should be treated as a regular space character.
|
||||||
|
ch = ' ';
|
||||||
|
}
|
||||||
|
if (ch != undefined && CH == undefined) {
|
||||||
|
// For letter keys, we automatically compute the uppercase character code
|
||||||
|
// from the lowercase one.
|
||||||
|
CH = ch.toUpperCase();
|
||||||
|
}
|
||||||
|
if (KEY == undefined && key != undefined) {
|
||||||
|
// Most keys have identically key codes for both lowercase and uppercase
|
||||||
|
// keypresses. Normally, only function keys would have distinct key codes,
|
||||||
|
// whereas regular keys have character codes.
|
||||||
|
KEY = key;
|
||||||
|
} else if (KEY == undefined && CH != undefined) {
|
||||||
|
// For regular keys, copy the character code to the key code.
|
||||||
|
KEY = CH.charCodeAt(0);
|
||||||
|
}
|
||||||
|
if (key == undefined && ch != undefined) {
|
||||||
|
// For regular keys, copy the character code to the key code.
|
||||||
|
key = ch.charCodeAt(0);
|
||||||
|
}
|
||||||
|
// Convert characters to numeric character codes. If the character code
|
||||||
|
// is undefined (i.e. this is a function key), set it to zero.
|
||||||
|
ch = ch ? ch.charCodeAt(0) : 0;
|
||||||
|
CH = CH ? CH.charCodeAt(0) : 0;
|
||||||
|
|
||||||
|
// Mouse down events high light the key. We also set lastSelectedKey. This
|
||||||
|
// is needed to that mouseout/mouseover can keep track of the key that
|
||||||
|
// is currently being clicked.
|
||||||
|
this.addListener(elem, 'mousedown',
|
||||||
|
function(vt100, elem, key) { return function(e) {
|
||||||
|
if ((e.which || e.button) == 1) {
|
||||||
|
if (vt100.lastSelectedKey) {
|
||||||
|
vt100.lastSelectedKey.className= '';
|
||||||
|
}
|
||||||
|
// Highlight the key while the mouse button is held down.
|
||||||
|
if (key == 16 /* Shift */) {
|
||||||
|
if (!elem.className != vt100.isShift) {
|
||||||
|
vt100.showShiftState(!vt100.isShift);
|
||||||
|
}
|
||||||
|
} else if (key == 17 /* Ctrl */) {
|
||||||
|
if (!elem.className != vt100.isCtrl) {
|
||||||
|
vt100.showCtrlState(!vt100.isCtrl);
|
||||||
|
}
|
||||||
|
} else if (key == 18 /* Alt */) {
|
||||||
|
if (!elem.className != vt100.isAlt) {
|
||||||
|
vt100.showAltState(!vt100.isAlt);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
elem.className = 'selected';
|
||||||
|
}
|
||||||
|
vt100.lastSelectedKey = elem;
|
||||||
|
}
|
||||||
|
return false; }; }(this, elem, key));
|
||||||
|
var clicked =
|
||||||
|
// Modifier keys update the state of the keyboard, but do not generate
|
||||||
|
// any key clicks that get forwarded to the application.
|
||||||
|
key >= 16 /* Shift */ && key <= 18 /* Alt */ ?
|
||||||
|
function(vt100, elem) { return function(e) {
|
||||||
|
if (elem == vt100.lastSelectedKey) {
|
||||||
|
if (key == 16 /* Shift */) {
|
||||||
|
// The user clicked the Shift key
|
||||||
|
vt100.isShift = !vt100.isShift;
|
||||||
|
vt100.showShiftState(vt100.isShift);
|
||||||
|
} else if (key == 17 /* Ctrl */) {
|
||||||
|
vt100.isCtrl = !vt100.isCtrl;
|
||||||
|
vt100.showCtrlState(vt100.isCtrl);
|
||||||
|
} else if (key == 18 /* Alt */) {
|
||||||
|
vt100.isAlt = !vt100.isAlt;
|
||||||
|
vt100.showAltState(vt100.isAlt);
|
||||||
|
}
|
||||||
|
vt100.lastSelectedKey = undefined;
|
||||||
|
}
|
||||||
|
if (vt100.lastSelectedKey) {
|
||||||
|
vt100.lastSelectedKey.className = '';
|
||||||
|
vt100.lastSelectedKey = undefined;
|
||||||
|
}
|
||||||
|
return false; }; }(this, elem) :
|
||||||
|
// Regular keys generate key clicks, when the mouse button is released or
|
||||||
|
// when a mouse click event is received.
|
||||||
|
function(vt100, elem, ch, key, CH, KEY) { return function(e) {
|
||||||
|
if (vt100.lastSelectedKey) {
|
||||||
|
if (elem == vt100.lastSelectedKey) {
|
||||||
|
// The user clicked a key.
|
||||||
|
if (vt100.isShift) {
|
||||||
|
vt100.clickedKeyboard(e, elem, CH, KEY,
|
||||||
|
true, vt100.isCtrl, vt100.isAlt);
|
||||||
|
} else {
|
||||||
|
vt100.clickedKeyboard(e, elem, ch, key,
|
||||||
|
false, vt100.isCtrl, vt100.isAlt);
|
||||||
|
}
|
||||||
|
vt100.isShift = false;
|
||||||
|
vt100.showShiftState(false);
|
||||||
|
vt100.isCtrl = false;
|
||||||
|
vt100.showCtrlState(false);
|
||||||
|
vt100.isAlt = false;
|
||||||
|
vt100.showAltState(false);
|
||||||
|
}
|
||||||
|
vt100.lastSelectedKey.className = '';
|
||||||
|
vt100.lastSelectedKey = undefined;
|
||||||
|
}
|
||||||
|
elem.className = '';
|
||||||
|
return false; }; }(this, elem, ch, key, CH, KEY);
|
||||||
|
this.addListener(elem, 'mouseup', clicked);
|
||||||
|
this.addListener(elem, 'click', clicked);
|
||||||
|
|
||||||
|
// When moving the mouse away from a key, check if any keys need to be
|
||||||
|
// deselected.
|
||||||
|
this.addListener(elem, 'mouseout',
|
||||||
|
function(vt100, elem, key) { return function(e) {
|
||||||
|
if (key == 16 /* Shift */) {
|
||||||
|
if (!elem.className == vt100.isShift) {
|
||||||
|
vt100.showShiftState(vt100.isShift);
|
||||||
|
}
|
||||||
|
} else if (key == 17 /* Ctrl */) {
|
||||||
|
if (!elem.className == vt100.isCtrl) {
|
||||||
|
vt100.showCtrlState(vt100.isCtrl);
|
||||||
|
}
|
||||||
|
} else if (key == 18 /* Alt */) {
|
||||||
|
if (!elem.className == vt100.isAlt) {
|
||||||
|
vt100.showAltState(vt100.isAlt);
|
||||||
|
}
|
||||||
|
} else if (elem.className) {
|
||||||
|
elem.className = '';
|
||||||
|
vt100.lastSelectedKey = elem;
|
||||||
|
} else if (vt100.lastSelectedKey) {
|
||||||
|
vt100.resetLastSelectedKey(e);
|
||||||
|
}
|
||||||
|
return false; }; }(this, elem, key));
|
||||||
|
|
||||||
|
// When moving the mouse over a key, select it if the user is still holding
|
||||||
|
// the mouse button down (i.e. elem == lastSelectedKey)
|
||||||
|
this.addListener(elem, 'mouseover',
|
||||||
|
function(vt100, elem, key) { return function(e) {
|
||||||
|
if (elem == vt100.lastSelectedKey) {
|
||||||
|
if (key == 16 /* Shift */) {
|
||||||
|
if (!elem.className != vt100.isShift) {
|
||||||
|
vt100.showShiftState(!vt100.isShift);
|
||||||
|
}
|
||||||
|
} else if (key == 17 /* Ctrl */) {
|
||||||
|
if (!elem.className != vt100.isCtrl) {
|
||||||
|
vt100.showCtrlState(!vt100.isCtrl);
|
||||||
|
}
|
||||||
|
} else if (key == 18 /* Alt */) {
|
||||||
|
if (!elem.className != vt100.isAlt) {
|
||||||
|
vt100.showAltState(!vt100.isAlt);
|
||||||
|
}
|
||||||
|
} else if (!elem.className) {
|
||||||
|
elem.className = 'selected';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
vt100.resetLastSelectedKey(e);
|
||||||
|
}
|
||||||
|
return false; }; }(this, elem, key));
|
||||||
|
};
|
||||||
|
|
||||||
|
VT100.prototype.initializeKeyBindings = function(elem) {
|
||||||
|
if (elem) {
|
||||||
|
if (elem.nodeName == "I" || elem.nodeName == "B") {
|
||||||
|
if (elem.id) {
|
||||||
|
// Function keys. The Javascript keycode is part of the "id"
|
||||||
|
var i = parseInt(elem.id);
|
||||||
|
if (i) {
|
||||||
|
// If the id does not parse as a number, it is not a keycode.
|
||||||
|
this.addKeyBinding(elem, undefined, i);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
var child = elem.firstChild;
|
||||||
|
if (child.nodeName == "#text") {
|
||||||
|
// If the key only has a text node as a child, then it is a letter.
|
||||||
|
// Automatically compute the lower and upper case version of the key.
|
||||||
|
this.addKeyBinding(elem, this.getTextContent(child).toLowerCase());
|
||||||
|
} else {
|
||||||
|
// If the key has two children, they are the lower and upper case
|
||||||
|
// character code, respectively.
|
||||||
|
this.addKeyBinding(elem, this.getTextContent(child), undefined,
|
||||||
|
this.getTextContent(child.nextSibling));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Recursively parse all other child nodes.
|
||||||
|
for (elem = elem.firstChild; elem; elem = elem.nextSibling) {
|
||||||
|
this.initializeKeyBindings(elem);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
VT100.prototype.initializeKeyboard = function() {
|
||||||
|
// Configure mouse event handlers for button that displays/hides keyboard
|
||||||
|
var box = this.keyboard.firstChild;
|
||||||
|
this.hideSoftKeyboard();
|
||||||
|
this.addListener(this.keyboardImage, 'click',
|
||||||
|
function(vt100) { return function(e) {
|
||||||
|
if (vt100.keyboard.style.display != '') {
|
||||||
|
if (vt100.reconnectBtn.style.visibility != '') {
|
||||||
|
vt100.showSoftKeyboard();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
vt100.hideSoftKeyboard();
|
||||||
|
vt100.input.focus();
|
||||||
|
}
|
||||||
|
return false; }; }(this));
|
||||||
|
|
||||||
|
// Enable button that displays keyboard
|
||||||
|
if (this.softKeyboard) {
|
||||||
|
this.keyboardImage.style.visibility = 'visible';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Configure mouse event handlers for on-screen keyboard
|
||||||
|
this.addListener(this.keyboard, 'click',
|
||||||
|
function(vt100) { return function(e) {
|
||||||
|
vt100.hideSoftKeyboard();
|
||||||
|
vt100.input.focus();
|
||||||
|
return false; }; }(this));
|
||||||
|
this.addListener(this.keyboard, 'selectstart', this.cancelEvent);
|
||||||
|
this.addListener(box, 'click', this.cancelEvent);
|
||||||
|
this.addListener(box, 'mouseup',
|
||||||
|
function(vt100) { return function(e) {
|
||||||
|
if (vt100.lastSelectedKey) {
|
||||||
|
vt100.lastSelectedKey.className = '';
|
||||||
|
vt100.lastSelectedKey = undefined;
|
||||||
|
}
|
||||||
|
return false; }; }(this));
|
||||||
|
this.addListener(box, 'mouseout',
|
||||||
|
function(vt100) { return function(e) {
|
||||||
|
return vt100.resetLastSelectedKey(e); }; }(this));
|
||||||
|
this.addListener(box, 'mouseover',
|
||||||
|
function(vt100) { return function(e) {
|
||||||
|
return vt100.resetLastSelectedKey(e); }; }(this));
|
||||||
|
|
||||||
|
// Configure SHIFT key behavior
|
||||||
|
var style = document.createElement('style');
|
||||||
|
var id = document.createAttribute('id');
|
||||||
|
id.nodeValue = 'shift_state';
|
||||||
|
style.setAttributeNode(id);
|
||||||
|
var type = document.createAttribute('type');
|
||||||
|
type.nodeValue = 'text/css';
|
||||||
|
style.setAttributeNode(type);
|
||||||
|
document.getElementsByTagName('head')[0].appendChild(style);
|
||||||
|
|
||||||
|
// Set up key bindings
|
||||||
|
this.initializeKeyBindings(box);
|
||||||
|
};
|
||||||
|
|
||||||
VT100.prototype.initializeElements = function(container) {
|
VT100.prototype.initializeElements = function(container) {
|
||||||
// If the necessary objects have not already been defined in the HTML
|
// If the necessary objects have not already been defined in the HTML
|
||||||
// page, create them now.
|
// page, create them now.
|
||||||
|
@ -483,6 +805,9 @@ VT100.prototype.initializeElements = function(container) {
|
||||||
|
|
||||||
if (!this.getChildById(this.container, 'reconnect') ||
|
if (!this.getChildById(this.container, 'reconnect') ||
|
||||||
!this.getChildById(this.container, 'menu') ||
|
!this.getChildById(this.container, 'menu') ||
|
||||||
|
!this.getChildById(this.container, 'keyboard') ||
|
||||||
|
!this.getChildById(this.container, 'kbd_button') ||
|
||||||
|
!this.getChildById(this.container, 'kbd_img') ||
|
||||||
!this.getChildById(this.container, 'scrollable') ||
|
!this.getChildById(this.container, 'scrollable') ||
|
||||||
!this.getChildById(this.container, 'console') ||
|
!this.getChildById(this.container, 'console') ||
|
||||||
!this.getChildById(this.container, 'alt_console') ||
|
!this.getChildById(this.container, 'alt_console') ||
|
||||||
|
@ -525,7 +850,15 @@ VT100.prototype.initializeElements = function(container) {
|
||||||
'<div id="cursize" style="visibility: hidden">' +
|
'<div id="cursize" style="visibility: hidden">' +
|
||||||
'</div>' +
|
'</div>' +
|
||||||
'<div id="menu"></div>' +
|
'<div id="menu"></div>' +
|
||||||
|
'<div id="keyboard" unselectable="on">' +
|
||||||
|
'<pre class="box"><div><i id="27">Esc</i><i id="112">F1</i><i id="113">F2</i><i id="114">F3</i><i id="115">F4</i><i id="116">F5</i><i id="117">F6</i><i id="118">F7</i><i id="119">F8</i><i id="120">F9</i><i id="121">F10</i><i id="122">F11</i><i id="123">F12</i><br /><b><span class="unshifted">`</span><span class="shifted">~</span></b><b><span class="unshifted">1</span><span class="shifted">!</span></b><b><span class="unshifted">2</span><span class="shifted">@</span></b><b><span class="unshifted">3</span><span class="shifted">#</span></b><b><span class="unshifted">4</span><span class="shifted">$</span></b><b><span class="unshifted">5</span><span class="shifted">%</span></b><b><span class="unshifted">6</span><span class="shifted">^</span></b><b><span class="unshifted">7</span><span class="shifted">&</span></b><b><span class="unshifted">8</span><span class="shifted">*</span></b><b><span class="unshifted">9</span><span class="shifted">(</span></b><b><span class="unshifted">0</span><span class="shifted">)</span></b><b><span class="unshifted">-</span><span class="shifted">_</span></b><b><span class="unshifted">=</span><span class="shifted">+</span></b><i id="8"> ← </i><br /><i id="9">Tab</i><b>Q</b><b>W</b><b>E</b><b>R</b><b>T</b><b>Y</b><b>U</b><b>I</b><b>O</b><b>P</b><b><span class="unshifted">[</span><span class="shifted">{</span></b><b><span class="unshifted">]</span><span class="shifted">}</span></b><b><span class="unshifted">\</span><span class="shifted">|</span></b><br /><u>Tab </u><b>A</b><b>S</b><b>D</b><b>F</b><b>G</b><b>H</b><b>J</b><b>K</b><b>L</b><b><span class="unshifted">;</span><span class="shifted">:</span></b><b><span class="unshifted">'</span><span class="shifted">"</span></b><i id="13">Enter</i><br /><u> </u><i id="16">Shift</i><b>Z</b><b>X</b><b>C</b><b>V</b><b>B</b><b>N</b><b>M</b><b><span class="unshifted">,</span><span class="shifted"><</span></b><b><span class="unshifted">.</span><span class="shifted">></span></b><b><span class="unshifted">/</span><span class="shifted">?</span></b><i id="16">Shift</i><br /><u>XXX</u><i id="17">Ctrl</i><i id="18">Alt</i><i style="width: 25ex"> </i></div> <div><i id="45">Ins</i><i id="46">Del</i><i id="36">Home</i><i id="35">End</i><br /><u> </u><br /><u> </u><br /><u>Ins</u><s> </s><b id="38">↑</b><s> </s><u> </u><b id="33">⇑</b><br /><u>Ins</u><b id="37">←</b><b id="40">↓</b><b id="39">→</b><u> </u><b id="34">⇓</b></div></pre>' +
|
||||||
|
'</div>' +
|
||||||
'<div id="scrollable">' +
|
'<div id="scrollable">' +
|
||||||
|
'<table id="kbd_button">' +
|
||||||
|
'<tr><td width="100%"> </td>' +
|
||||||
|
'<td><img id="kbd_img" src="keyboard.png" /></td>' +
|
||||||
|
'<td> </td></tr>' +
|
||||||
|
'</table>' +
|
||||||
'<pre id="lineheight"> </pre>' +
|
'<pre id="lineheight"> </pre>' +
|
||||||
'<pre id="console">' +
|
'<pre id="console">' +
|
||||||
'<pre></pre>' +
|
'<pre></pre>' +
|
||||||
|
@ -566,6 +899,8 @@ VT100.prototype.initializeElements = function(container) {
|
||||||
this.reconnectBtn = this.getChildById(this.container,'reconnect');
|
this.reconnectBtn = this.getChildById(this.container,'reconnect');
|
||||||
this.curSizeBox = this.getChildById(this.container, 'cursize');
|
this.curSizeBox = this.getChildById(this.container, 'cursize');
|
||||||
this.menu = this.getChildById(this.container, 'menu');
|
this.menu = this.getChildById(this.container, 'menu');
|
||||||
|
this.keyboard = this.getChildById(this.container, 'keyboard');
|
||||||
|
this.keyboardImage = this.getChildById(this.container, 'kbd_img');
|
||||||
this.scrollable = this.getChildById(this.container,
|
this.scrollable = this.getChildById(this.container,
|
||||||
'scrollable');
|
'scrollable');
|
||||||
this.lineheight = this.getChildById(this.container,
|
this.lineheight = this.getChildById(this.container,
|
||||||
|
@ -646,6 +981,9 @@ VT100.prototype.initializeElements = function(container) {
|
||||||
// Hide context menu
|
// Hide context menu
|
||||||
this.hideContextMenu();
|
this.hideContextMenu();
|
||||||
|
|
||||||
|
// Set up onscreen soft keyboard
|
||||||
|
this.initializeKeyboard();
|
||||||
|
|
||||||
// Add listener to reconnect button
|
// Add listener to reconnect button
|
||||||
this.addListener(this.reconnectBtn.firstChild, 'click',
|
this.addListener(this.reconnectBtn.firstChild, 'click',
|
||||||
function(vt100) {
|
function(vt100) {
|
||||||
|
@ -733,6 +1071,7 @@ VT100.prototype.reconnect = function() {
|
||||||
|
|
||||||
VT100.prototype.showReconnect = function(state) {
|
VT100.prototype.showReconnect = function(state) {
|
||||||
if (state) {
|
if (state) {
|
||||||
|
this.hideSoftKeyboard();
|
||||||
this.reconnectBtn.style.visibility = '';
|
this.reconnectBtn.style.visibility = '';
|
||||||
} else {
|
} else {
|
||||||
this.reconnectBtn.style.visibility = 'hidden';
|
this.reconnectBtn.style.visibility = 'hidden';
|
||||||
|
@ -766,6 +1105,9 @@ VT100.prototype.resized = function(w, h) {
|
||||||
};
|
};
|
||||||
|
|
||||||
VT100.prototype.resizer = function() {
|
VT100.prototype.resizer = function() {
|
||||||
|
// Hide onscreen soft keyboard
|
||||||
|
this.hideSoftKeyboard();
|
||||||
|
|
||||||
// The cursor can get corrupted if the print-preview is displayed in Firefox.
|
// The cursor can get corrupted if the print-preview is displayed in Firefox.
|
||||||
// Recreating it, will repair it.
|
// Recreating it, will repair it.
|
||||||
var newCursor = document.createElement('pre');
|
var newCursor = document.createElement('pre');
|
||||||
|
@ -945,6 +1287,17 @@ VT100.prototype.cancelEvent = function(event) {
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
VT100.prototype.mousePosition = function(event) {
|
||||||
|
var offsetX = this.container.offsetLeft;
|
||||||
|
var offsetY = this.container.offsetTop;
|
||||||
|
for (var e = this.container; e = e.offsetParent; ) {
|
||||||
|
offsetX += e.offsetLeft;
|
||||||
|
offsetY += e.offsetTop;
|
||||||
|
}
|
||||||
|
return [ event.clientX - offsetX,
|
||||||
|
event.clientY - offsetY ];
|
||||||
|
};
|
||||||
|
|
||||||
VT100.prototype.mouseEvent = function(event, type) {
|
VT100.prototype.mouseEvent = function(event, type) {
|
||||||
// If any text is currently selected, do not move the focus as that would
|
// If any text is currently selected, do not move the focus as that would
|
||||||
// invalidate the selection.
|
// invalidate the selection.
|
||||||
|
@ -954,15 +1307,10 @@ VT100.prototype.mouseEvent = function(event, type) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compute mouse position in characters.
|
// Compute mouse position in characters.
|
||||||
var offsetX = this.container.offsetLeft;
|
var position = this.mousePosition(event);
|
||||||
var offsetY = this.container.offsetTop;
|
var x = Math.floor(position[0] / this.cursorWidth);
|
||||||
for (var e = this.container; e = e.offsetParent; ) {
|
var y = Math.floor((position[1] + this.scrollable.scrollTop) /
|
||||||
offsetX += e.offsetLeft;
|
this.cursorHeight) - this.numScrollbackLines;
|
||||||
offsetY += e.offsetTop;
|
|
||||||
}
|
|
||||||
var x = (event.clientX - offsetX) / this.cursorWidth;
|
|
||||||
var y = ((event.clientY - offsetY) + this.scrollable.offsetTop) /
|
|
||||||
this.cursorHeight - this.numScrollbackLines;
|
|
||||||
var inside = true;
|
var inside = true;
|
||||||
if (x >= this.terminalWidth) {
|
if (x >= this.terminalWidth) {
|
||||||
x = this.terminalWidth - 1;
|
x = this.terminalWidth - 1;
|
||||||
|
@ -1022,7 +1370,7 @@ VT100.prototype.mouseEvent = function(event, type) {
|
||||||
// Bring up context menu.
|
// Bring up context menu.
|
||||||
if (button == 2 && !event.shiftKey) {
|
if (button == 2 && !event.shiftKey) {
|
||||||
if (type == 0 /* MOUSE_DOWN */) {
|
if (type == 0 /* MOUSE_DOWN */) {
|
||||||
this.showContextMenu(event.clientX - offsetX, event.clientY - offsetY);
|
this.showContextMenu(position[0], position[1]);
|
||||||
}
|
}
|
||||||
return this.cancelEvent(event);
|
return this.cancelEvent(event);
|
||||||
}
|
}
|
||||||
|
@ -1058,6 +1406,29 @@ VT100.prototype.getTextContent = function(elem) {
|
||||||
(typeof elem.textContent == 'undefined' ? elem.innerText : '');
|
(typeof elem.textContent == 'undefined' ? elem.innerText : '');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
VT100.prototype.setTextContentRaw = function(elem, s) {
|
||||||
|
// Updating the content of an element is an expensive operation. It actually
|
||||||
|
// pays off to first check whether the element is still unchanged.
|
||||||
|
if (typeof elem.textContent == 'undefined') {
|
||||||
|
if (elem.innerText != s) {
|
||||||
|
try {
|
||||||
|
elem.innerText = s;
|
||||||
|
} catch (e) {
|
||||||
|
// Very old versions of IE do not allow setting innerText. Instead,
|
||||||
|
// remove all children, by setting innerHTML and then set the text
|
||||||
|
// using DOM methods.
|
||||||
|
elem.innerHTML = '';
|
||||||
|
elem.appendChild(document.createTextNode(
|
||||||
|
this.replaceChar(s, ' ', '\u00A0')));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (elem.textContent != s) {
|
||||||
|
elem.textContent = s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
VT100.prototype.setTextContent = function(elem, s) {
|
VT100.prototype.setTextContent = function(elem, s) {
|
||||||
// Check if we find any URLs in the text. If so, automatically convert them
|
// Check if we find any URLs in the text. If so, automatically convert them
|
||||||
// to links.
|
// to links.
|
||||||
|
@ -1103,26 +1474,7 @@ VT100.prototype.setTextContent = function(elem, s) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Updating the content of an element is an expensive operation. It actually
|
this.setTextContentRaw(elem, s);
|
||||||
// pays off to first check whether the element is still unchanged.
|
|
||||||
if (typeof elem.textContent == 'undefined') {
|
|
||||||
if (elem.innerText != s) {
|
|
||||||
try {
|
|
||||||
elem.innerText = s;
|
|
||||||
} catch (e) {
|
|
||||||
// Very old versions of IE do not allow setting innerText. Instead,
|
|
||||||
// remove all children, by setting innerHTML and then set the text
|
|
||||||
// using DOM methods.
|
|
||||||
elem.innerHTML = '';
|
|
||||||
elem.appendChild(document.createTextNode(
|
|
||||||
this.replaceChar(s, ' ', '\u00A0')));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (elem.textContent != s) {
|
|
||||||
elem.textContent = s;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
VT100.prototype.insertBlankLine = function(y, color, style) {
|
VT100.prototype.insertBlankLine = function(y, color, style) {
|
||||||
|
@ -1578,27 +1930,21 @@ VT100.prototype.enableAlternateScreen = function(state) {
|
||||||
this.console[this.currentScreen].style.display = '';
|
this.console[this.currentScreen].style.display = '';
|
||||||
|
|
||||||
// Select appropriate character pitch.
|
// Select appropriate character pitch.
|
||||||
var styles = [ 'transform',
|
var transform = this.getTransformName();
|
||||||
'WebkitTransform',
|
if (transform) {
|
||||||
'MozTransform',
|
if (state) {
|
||||||
'filter' ];
|
// Upon enabling the alternate screen, we switch to 80 column mode. But
|
||||||
for (var i = 0; i < styles.length; ++i) {
|
// upon returning to the regular screen, we restore the mode that was
|
||||||
if (typeof this.console[0].style[styles[i]] != 'undefined') {
|
// in effect previously.
|
||||||
if (state) {
|
this.console[1].style[transform] = '';
|
||||||
// Upon enabling the alternate screen, we switch to 80 column mode. But
|
}
|
||||||
// upon returning to the regular screen, we restore the mode that was
|
var style =
|
||||||
// in effect previously.
|
this.console[this.currentScreen].style[transform];
|
||||||
this.console[1].style[styles[i]] = '';
|
this.cursor.style[transform] = style;
|
||||||
}
|
this.space.style[transform] = style;
|
||||||
var style =
|
this.scale = style == '' ? 1.0:1.65;
|
||||||
this.console[this.currentScreen].style[styles[i]];
|
if (transform == 'filter') {
|
||||||
this.cursor.style[styles[i]] = style;
|
this.console[this.currentScreen].style.width = style == '' ? '165%':'';
|
||||||
this.space.style[styles[i]] = style;
|
|
||||||
this.scale = style == '' ? 1.0:1.65;
|
|
||||||
if (styles[i] == 'filter') {
|
|
||||||
this.console[this.currentScreen].style.width = style == '' ? '165%':'';
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.resizer();
|
this.resizer();
|
||||||
|
@ -1969,12 +2315,76 @@ VT100.prototype.toggleBell = function() {
|
||||||
this.visualBell = !this.visualBell;
|
this.visualBell = !this.visualBell;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
VT100.prototype.toggleSoftKeyboard = function() {
|
||||||
|
this.softKeyboard = !this.softKeyboard;
|
||||||
|
this.keyboardImage.style.visibility = this.softKeyboard ? 'visible' : '';
|
||||||
|
};
|
||||||
|
|
||||||
|
VT100.prototype.deselectKeys = function(elem) {
|
||||||
|
if (elem && elem.className == 'selected') {
|
||||||
|
elem.className = '';
|
||||||
|
}
|
||||||
|
for (elem = elem.firstChild; elem; elem = elem.nextSibling) {
|
||||||
|
this.deselectKeys(elem);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
VT100.prototype.showSoftKeyboard = function() {
|
||||||
|
// Make sure no key is currently selected
|
||||||
|
this.lastSelectedKey = undefined;
|
||||||
|
this.deselectKeys(this.keyboard);
|
||||||
|
this.isShift = false;
|
||||||
|
this.showShiftState(false);
|
||||||
|
this.isCtrl = false;
|
||||||
|
this.showCtrlState(false);
|
||||||
|
this.isAlt = false;
|
||||||
|
this.showAltState(false);
|
||||||
|
|
||||||
|
this.keyboard.style.left = '0px';
|
||||||
|
this.keyboard.style.top = '0px';
|
||||||
|
this.keyboard.style.width = this.container.offsetWidth + 'px';
|
||||||
|
this.keyboard.style.height = this.container.offsetHeight + 'px';
|
||||||
|
this.keyboard.style.visibility = 'hidden';
|
||||||
|
this.keyboard.style.display = '';
|
||||||
|
|
||||||
|
var kbd = this.keyboard.firstChild;
|
||||||
|
var scale = 1.0;
|
||||||
|
var transform = this.getTransformName();
|
||||||
|
if (transform) {
|
||||||
|
kbd.style[transform] = '';
|
||||||
|
if (kbd.offsetWidth > 0.9 * this.container.offsetWidth) {
|
||||||
|
scale = (kbd.offsetWidth/
|
||||||
|
this.container.offsetWidth)/0.9;
|
||||||
|
}
|
||||||
|
if (kbd.offsetHeight > 0.9 * this.container.offsetHeight) {
|
||||||
|
scale = Math.max((kbd.offsetHeight/
|
||||||
|
this.container.offsetHeight)/0.9);
|
||||||
|
}
|
||||||
|
var style = this.getTransformStyle(transform,
|
||||||
|
scale > 1.0 ? scale : undefined);
|
||||||
|
kbd.style[transform] = style;
|
||||||
|
}
|
||||||
|
if (transform == 'filter') {
|
||||||
|
scale = 1.0;
|
||||||
|
}
|
||||||
|
kbd.style.left = ((this.container.offsetWidth -
|
||||||
|
kbd.offsetWidth/scale)/2) + 'px';
|
||||||
|
kbd.style.top = ((this.container.offsetHeight -
|
||||||
|
kbd.offsetHeight/scale)/2) + 'px';
|
||||||
|
|
||||||
|
this.keyboard.style.visibility = 'visible';
|
||||||
|
};
|
||||||
|
|
||||||
|
VT100.prototype.hideSoftKeyboard = function() {
|
||||||
|
this.keyboard.style.display = 'none';
|
||||||
|
};
|
||||||
|
|
||||||
VT100.prototype.toggleCursorBlinking = function() {
|
VT100.prototype.toggleCursorBlinking = function() {
|
||||||
this.blinkingCursor = !this.blinkingCursor;
|
this.blinkingCursor = !this.blinkingCursor;
|
||||||
};
|
};
|
||||||
|
|
||||||
VT100.prototype.about = function() {
|
VT100.prototype.about = function() {
|
||||||
alert("VT100 Terminal Emulator " + "2.10 (revision 220)" +
|
alert("VT100 Terminal Emulator " + "2.10 (revision 221)" +
|
||||||
"\nCopyright 2008-2010 by Markus Gutschke\n" +
|
"\nCopyright 2008-2010 by Markus Gutschke\n" +
|
||||||
"For more information check http://shellinabox.com");
|
"For more information check http://shellinabox.com");
|
||||||
};
|
};
|
||||||
|
@ -2007,6 +2417,9 @@ VT100.prototype.showContextMenu = function(x, y) {
|
||||||
'<li>' +
|
'<li>' +
|
||||||
(this.visualBell ? '<img src="enabled.gif" />' : '') +
|
(this.visualBell ? '<img src="enabled.gif" />' : '') +
|
||||||
'Visual Bell</li>'+
|
'Visual Bell</li>'+
|
||||||
|
'<li>' +
|
||||||
|
(this.softKeyboard ? '<img src="enabled.gif" />' : '') +
|
||||||
|
'Onscreen Keyboard</li>' +
|
||||||
'<li id="endconfig">' +
|
'<li id="endconfig">' +
|
||||||
(this.blinkingCursor ? '<img src="enabled.gif" />' : '') +
|
(this.blinkingCursor ? '<img src="enabled.gif" />' : '') +
|
||||||
'Blinking Cursor</li>'+
|
'Blinking Cursor</li>'+
|
||||||
|
@ -2038,6 +2451,7 @@ VT100.prototype.showContextMenu = function(x, y) {
|
||||||
// Actions for default items
|
// Actions for default items
|
||||||
var actions = [ this.copyLast, p, this.reset,
|
var actions = [ this.copyLast, p, this.reset,
|
||||||
this.toggleUTF, this.toggleBell,
|
this.toggleUTF, this.toggleBell,
|
||||||
|
this.toggleSoftKeyboard,
|
||||||
this.toggleCursorBlinking ];
|
this.toggleCursorBlinking ];
|
||||||
|
|
||||||
// Actions for user CSS styles (if any)
|
// Actions for user CSS styles (if any)
|
||||||
|
@ -2093,26 +2507,30 @@ VT100.prototype.showContextMenu = function(x, y) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Position menu next to the mouse pointer
|
// Position menu next to the mouse pointer
|
||||||
if (x + popup.clientWidth > this.container.offsetWidth) {
|
this.menu.style.left = '0px';
|
||||||
x = this.container.offsetWidth - popup.clientWidth;
|
this.menu.style.top = '0px';
|
||||||
|
this.menu.style.width = this.container.offsetWidth + 'px';
|
||||||
|
this.menu.style.height = this.container.offsetHeight + 'px';
|
||||||
|
popup.style.left = '0px';
|
||||||
|
popup.style.top = '0px';
|
||||||
|
|
||||||
|
var margin = 2;
|
||||||
|
if (x + popup.clientWidth >= this.container.offsetWidth - margin) {
|
||||||
|
x = this.container.offsetWidth-popup.clientWidth - margin - 1;
|
||||||
}
|
}
|
||||||
if (x < 0) {
|
if (x < margin) {
|
||||||
x = 0;
|
x = margin;
|
||||||
}
|
}
|
||||||
if (y + popup.clientHeight > this.container.offsetHeight) {
|
if (y + popup.clientHeight >= this.container.offsetHeight - margin) {
|
||||||
y = this.container.offsetHeight-popup.clientHeight;
|
y = this.container.offsetHeight-popup.clientHeight - margin - 1;
|
||||||
}
|
}
|
||||||
if (y < 0) {
|
if (y < margin) {
|
||||||
y = 0;
|
y = margin;
|
||||||
}
|
}
|
||||||
popup.style.left = x + 'px';
|
popup.style.left = x + 'px';
|
||||||
popup.style.top = y + 'px';
|
popup.style.top = y + 'px';
|
||||||
|
|
||||||
// Block all other interactions with the terminal emulator
|
// Block all other interactions with the terminal emulator
|
||||||
this.menu.style.left = '0px';
|
|
||||||
this.menu.style.top = '0px';
|
|
||||||
this.menu.style.width = this.container.offsetWidth + 'px';
|
|
||||||
this.menu.style.height = this.container.offsetHeight + 'px';
|
|
||||||
this.addListener(this.menu, 'click', function(vt100) {
|
this.addListener(this.menu, 'click', function(vt100) {
|
||||||
return function() {
|
return function() {
|
||||||
vt100.hideContextMenu();
|
vt100.hideContextMenu();
|
||||||
|
@ -2895,39 +3313,42 @@ VT100.prototype.restoreCursor = function() {
|
||||||
this.savedY[this.currentScreen]);
|
this.savedY[this.currentScreen]);
|
||||||
};
|
};
|
||||||
|
|
||||||
VT100.prototype.set80_132Mode = function(state) {
|
VT100.prototype.getTransformName = function() {
|
||||||
var transform = undefined;
|
var styles = [ 'transform', 'WebkitTransform', 'MozTransform', 'filter' ];
|
||||||
var styles = [ 'transform',
|
|
||||||
'WebkitTransform',
|
|
||||||
'MozTransform',
|
|
||||||
'filter'
|
|
||||||
];
|
|
||||||
for (var i = 0; i < styles.length; ++i) {
|
for (var i = 0; i < styles.length; ++i) {
|
||||||
if (typeof this.console[0].style[styles[i]] != 'undefined') {
|
if (typeof this.console[0].style[styles[i]] != 'undefined') {
|
||||||
transform = styles[i];
|
return styles[i];
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
VT100.prototype.getTransformStyle = function(transform, scale) {
|
||||||
|
return scale && scale != 1.0
|
||||||
|
? transform == 'filter'
|
||||||
|
? 'progid:DXImageTransform.Microsoft.Matrix(' +
|
||||||
|
'M11=' + (1.0/scale) + ',M12=0,M21=0,M22=1,' +
|
||||||
|
"sizingMethod='auto expand')"
|
||||||
|
: 'translateX(-50%) ' +
|
||||||
|
'scaleX(' + (1.0/scale) + ') ' +
|
||||||
|
'translateX(50%)'
|
||||||
|
: '';
|
||||||
|
};
|
||||||
|
|
||||||
|
VT100.prototype.set80_132Mode = function(state) {
|
||||||
|
var transform = this.getTransformName();
|
||||||
if (transform) {
|
if (transform) {
|
||||||
if ((this.console[this.currentScreen].style[transform] != '') == state) {
|
if ((this.console[this.currentScreen].style[transform] != '') == state) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var style =
|
var style = state ?
|
||||||
state ? transform == 'filter'
|
this.getTransformStyle(transform, 1.65):'';
|
||||||
? 'progid:DXImageTransform.Microsoft.Matrix(' +
|
|
||||||
'M11=0.606060606060606060606,M12=0,M21=0,M22=1,' +
|
|
||||||
"sizingMethod='auto expand')"
|
|
||||||
: 'translateX(-50%) ' +
|
|
||||||
'scaleX(0.606060606060606060606) ' +
|
|
||||||
'translateX(50%)'
|
|
||||||
: '';
|
|
||||||
this.console[this.currentScreen].style[transform] = style;
|
this.console[this.currentScreen].style[transform] = style;
|
||||||
this.cursor.style[transform] = style;
|
this.cursor.style[transform] = style;
|
||||||
this.space.style[transform] = style;
|
this.space.style[transform] = style;
|
||||||
this.scale = state ? 1.65 : 1.0;
|
this.scale = state ? 1.65 : 1.0;
|
||||||
if (transform == 'filter') {
|
if (transform == 'filter') {
|
||||||
this.console[this.currentScreen].style.width = state ? '165%' : '';
|
this.console[this.currentScreen].style.width = state ? '165%' : '';
|
||||||
}
|
}
|
||||||
this.resizer();
|
this.resizer();
|
||||||
}
|
}
|
||||||
|
|
|
@ -238,22 +238,16 @@ VT100.prototype.reset = function(clearHistory) {
|
||||||
this.enableAlternateScreen(false);
|
this.enableAlternateScreen(false);
|
||||||
|
|
||||||
var wasCompressed = false;
|
var wasCompressed = false;
|
||||||
var styles = [ 'transform',
|
var transform = this.getTransformName();
|
||||||
'WebkitTransform',
|
if (transform) {
|
||||||
'MozTransform',
|
for (var i = 0; i < 2; ++i) {
|
||||||
'filter' ];
|
wasCompressed |= this.console[i].style[transform] != '';
|
||||||
for (var i = 0; i < styles.length; ++i) {
|
this.console[i].style[transform] = '';
|
||||||
if (typeof this.console[0].style[styles[i]] != 'undefined') {
|
}
|
||||||
for (var j = 0; j < 1; ++j) {
|
this.cursor.style[transform] = '';
|
||||||
wasCompressed |= this.console[j].style[styles[i]] != '';
|
this.space.style[transform] = '';
|
||||||
this.console[j].style[styles[i]] = '';
|
if (transform == 'filter') {
|
||||||
}
|
this.console[this.currentScreen].style.width = '';
|
||||||
this.cursor.style[styles[i]] = '';
|
|
||||||
this.space.style[styles[i]] = '';
|
|
||||||
if (styles[i] == 'filter') {
|
|
||||||
this.console[this.currentScreen].style.width = '';
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.scale = 1.0;
|
this.scale = 1.0;
|
||||||
|
@ -270,10 +264,13 @@ VT100.prototype.reset = function(clearHistory) {
|
||||||
};
|
};
|
||||||
|
|
||||||
VT100.prototype.addListener = function(elem, event, listener) {
|
VT100.prototype.addListener = function(elem, event, listener) {
|
||||||
if (elem.addEventListener) {
|
try {
|
||||||
elem.addEventListener(event, listener, false);
|
if (elem.addEventListener) {
|
||||||
} else {
|
elem.addEventListener(event, listener, false);
|
||||||
elem.attachEvent('on' + event, listener);
|
} else {
|
||||||
|
elem.attachEvent('on' + event, listener);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -281,11 +278,12 @@ VT100.prototype.getUserSettings = function() {
|
||||||
// Compute hash signature to identify the entries in the userCSS menu.
|
// Compute hash signature to identify the entries in the userCSS menu.
|
||||||
// If the menu is unchanged from last time, default values can be
|
// If the menu is unchanged from last time, default values can be
|
||||||
// looked up in a cookie associated with this page.
|
// looked up in a cookie associated with this page.
|
||||||
this.signature = 2;
|
this.signature = 3;
|
||||||
this.utfPreferred = true;
|
this.utfPreferred = true;
|
||||||
this.visualBell = typeof suppressAllAudio != 'undefined' &&
|
this.visualBell = typeof suppressAllAudio != 'undefined' &&
|
||||||
suppressAllAudio;
|
suppressAllAudio;
|
||||||
this.autoprint = true;
|
this.autoprint = true;
|
||||||
|
this.softKeyboard = false;
|
||||||
this.blinkingCursor = true;
|
this.blinkingCursor = true;
|
||||||
if (this.visualBell) {
|
if (this.visualBell) {
|
||||||
this.signature = Math.floor(16807*this.signature + 1) %
|
this.signature = Math.floor(16807*this.signature + 1) %
|
||||||
|
@ -311,15 +309,16 @@ VT100.prototype.getUserSettings = function() {
|
||||||
if (settings >= 0) {
|
if (settings >= 0) {
|
||||||
settings = document.cookie.substr(settings + key.length).
|
settings = document.cookie.substr(settings + key.length).
|
||||||
replace(/([0-1]*).*/, "$1");
|
replace(/([0-1]*).*/, "$1");
|
||||||
if (settings.length == 3 + (typeof userCSSList == 'undefined' ?
|
if (settings.length == 5 + (typeof userCSSList == 'undefined' ?
|
||||||
0 : userCSSList.length)) {
|
0 : userCSSList.length)) {
|
||||||
this.utfPreferred = settings.charAt(0) != '0';
|
this.utfPreferred = settings.charAt(0) != '0';
|
||||||
this.visualBell = settings.charAt(1) != '0';
|
this.visualBell = settings.charAt(1) != '0';
|
||||||
this.autoprint = settings.charAt(2) != '0';
|
this.autoprint = settings.charAt(2) != '0';
|
||||||
this.blinkingCursor = settings.charAt(3) != '0';
|
this.softKeyboard = settings.charAt(3) != '0';
|
||||||
|
this.blinkingCursor = settings.charAt(4) != '0';
|
||||||
if (typeof userCSSList != 'undefined') {
|
if (typeof userCSSList != 'undefined') {
|
||||||
for (var i = 0; i < userCSSList.length; ++i) {
|
for (var i = 0; i < userCSSList.length; ++i) {
|
||||||
userCSSList[i][2] = settings.charAt(i + 3) != '0';
|
userCSSList[i][2] = settings.charAt(i + 5) != '0';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -332,6 +331,7 @@ VT100.prototype.storeUserSettings = function() {
|
||||||
(this.utfEnabled ? '1' : '0') +
|
(this.utfEnabled ? '1' : '0') +
|
||||||
(this.visualBell ? '1' : '0') +
|
(this.visualBell ? '1' : '0') +
|
||||||
(this.autoprint ? '1' : '0') +
|
(this.autoprint ? '1' : '0') +
|
||||||
|
(this.softKeyboard ? '1' : '0') +
|
||||||
(this.blinkingCursor ? '1' : '0');
|
(this.blinkingCursor ? '1' : '0');
|
||||||
if (typeof userCSSList != 'undefined') {
|
if (typeof userCSSList != 'undefined') {
|
||||||
for (var i = 0; i < userCSSList.length; ++i) {
|
for (var i = 0; i < userCSSList.length; ++i) {
|
||||||
|
@ -413,7 +413,7 @@ VT100.prototype.initializeUserCSSStyles = function() {
|
||||||
label.textContent= label.textContent;
|
label.textContent= label.textContent;
|
||||||
}
|
}
|
||||||
|
|
||||||
// User style sheets are number sequentially
|
// User style sheets are numbered sequentially
|
||||||
var sheet = document.getElementById(
|
var sheet = document.getElementById(
|
||||||
'usercss-' + i);
|
'usercss-' + i);
|
||||||
if (i == current) {
|
if (i == current) {
|
||||||
|
@ -470,6 +470,328 @@ VT100.prototype.initializeUserCSSStyles = function() {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
VT100.prototype.resetLastSelectedKey = function(e) {
|
||||||
|
var key = this.lastSelectedKey;
|
||||||
|
if (!key) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var position = this.mousePosition(e);
|
||||||
|
|
||||||
|
// We don't get all the necessary events to reliably reselect a key
|
||||||
|
// if we moved away from it and then back onto it. We approximate the
|
||||||
|
// behavior by remembering the key until either we release the mouse
|
||||||
|
// button (we might never get this event if the mouse has since left
|
||||||
|
// the window), or until we move away too far.
|
||||||
|
var box = this.keyboard.firstChild;
|
||||||
|
if (position[0] < box.offsetLeft + key.offsetWidth ||
|
||||||
|
position[1] < box.offsetTop + key.offsetHeight ||
|
||||||
|
position[0] >= box.offsetLeft + box.offsetWidth - key.offsetWidth ||
|
||||||
|
position[1] >= box.offsetTop + box.offsetHeight - key.offsetHeight ||
|
||||||
|
position[0] < box.offsetLeft + key.offsetLeft - key.offsetWidth ||
|
||||||
|
position[1] < box.offsetTop + key.offsetTop - key.offsetHeight ||
|
||||||
|
position[0] >= box.offsetLeft + key.offsetLeft + 2*key.offsetWidth ||
|
||||||
|
position[1] >= box.offsetTop + key.offsetTop + 2*key.offsetHeight) {
|
||||||
|
if (this.lastSelectedKey.className) log.console('reset: deselecting');
|
||||||
|
this.lastSelectedKey.className = '';
|
||||||
|
this.lastSelectedKey = undefined;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
VT100.prototype.showShiftState = function(state) {
|
||||||
|
var style = document.getElementById('shift_state');
|
||||||
|
if (state) {
|
||||||
|
this.setTextContentRaw(style,
|
||||||
|
'#vt100 #keyboard .shifted {' +
|
||||||
|
'display: inline }' +
|
||||||
|
'#vt100 #keyboard .unshifted {' +
|
||||||
|
'display: none }');
|
||||||
|
} else {
|
||||||
|
this.setTextContentRaw(style, '');
|
||||||
|
}
|
||||||
|
var elems = this.keyboard.getElementsByTagName('I');
|
||||||
|
for (var i = 0; i < elems.length; ++i) {
|
||||||
|
if (elems[i].id == '16') {
|
||||||
|
elems[i].className = state ? 'selected' : '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
VT100.prototype.showCtrlState = function(state) {
|
||||||
|
var ctrl = this.getChildById(this.keyboard, '17' /* Ctrl */);
|
||||||
|
if (ctrl) {
|
||||||
|
ctrl.className = state ? 'selected' : '';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
VT100.prototype.showAltState = function(state) {
|
||||||
|
var alt = this.getChildById(this.keyboard, '18' /* Alt */);
|
||||||
|
if (alt) {
|
||||||
|
alt.className = state ? 'selected' : '';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
VT100.prototype.clickedKeyboard = function(e, elem, ch, key, shift, ctrl, alt){
|
||||||
|
var fake = [ ];
|
||||||
|
fake.charCode = ch;
|
||||||
|
fake.keyCode = key;
|
||||||
|
fake.ctrlKey = ctrl;
|
||||||
|
fake.shiftKey = shift;
|
||||||
|
fake.altKey = alt;
|
||||||
|
fake.metaKey = alt;
|
||||||
|
return this.handleKey(fake);
|
||||||
|
};
|
||||||
|
|
||||||
|
VT100.prototype.addKeyBinding = function(elem, ch, key, CH, KEY) {
|
||||||
|
if (elem == undefined) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (ch == '\u00A0') {
|
||||||
|
// should be treated as a regular space character.
|
||||||
|
ch = ' ';
|
||||||
|
}
|
||||||
|
if (ch != undefined && CH == undefined) {
|
||||||
|
// For letter keys, we automatically compute the uppercase character code
|
||||||
|
// from the lowercase one.
|
||||||
|
CH = ch.toUpperCase();
|
||||||
|
}
|
||||||
|
if (KEY == undefined && key != undefined) {
|
||||||
|
// Most keys have identically key codes for both lowercase and uppercase
|
||||||
|
// keypresses. Normally, only function keys would have distinct key codes,
|
||||||
|
// whereas regular keys have character codes.
|
||||||
|
KEY = key;
|
||||||
|
} else if (KEY == undefined && CH != undefined) {
|
||||||
|
// For regular keys, copy the character code to the key code.
|
||||||
|
KEY = CH.charCodeAt(0);
|
||||||
|
}
|
||||||
|
if (key == undefined && ch != undefined) {
|
||||||
|
// For regular keys, copy the character code to the key code.
|
||||||
|
key = ch.charCodeAt(0);
|
||||||
|
}
|
||||||
|
// Convert characters to numeric character codes. If the character code
|
||||||
|
// is undefined (i.e. this is a function key), set it to zero.
|
||||||
|
ch = ch ? ch.charCodeAt(0) : 0;
|
||||||
|
CH = CH ? CH.charCodeAt(0) : 0;
|
||||||
|
|
||||||
|
// Mouse down events high light the key. We also set lastSelectedKey. This
|
||||||
|
// is needed to that mouseout/mouseover can keep track of the key that
|
||||||
|
// is currently being clicked.
|
||||||
|
this.addListener(elem, 'mousedown',
|
||||||
|
function(vt100, elem, key) { return function(e) {
|
||||||
|
if ((e.which || e.button) == 1) {
|
||||||
|
if (vt100.lastSelectedKey) {
|
||||||
|
vt100.lastSelectedKey.className= '';
|
||||||
|
}
|
||||||
|
// Highlight the key while the mouse button is held down.
|
||||||
|
if (key == 16 /* Shift */) {
|
||||||
|
if (!elem.className != vt100.isShift) {
|
||||||
|
vt100.showShiftState(!vt100.isShift);
|
||||||
|
}
|
||||||
|
} else if (key == 17 /* Ctrl */) {
|
||||||
|
if (!elem.className != vt100.isCtrl) {
|
||||||
|
vt100.showCtrlState(!vt100.isCtrl);
|
||||||
|
}
|
||||||
|
} else if (key == 18 /* Alt */) {
|
||||||
|
if (!elem.className != vt100.isAlt) {
|
||||||
|
vt100.showAltState(!vt100.isAlt);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
elem.className = 'selected';
|
||||||
|
}
|
||||||
|
vt100.lastSelectedKey = elem;
|
||||||
|
}
|
||||||
|
return false; }; }(this, elem, key));
|
||||||
|
var clicked =
|
||||||
|
// Modifier keys update the state of the keyboard, but do not generate
|
||||||
|
// any key clicks that get forwarded to the application.
|
||||||
|
key >= 16 /* Shift */ && key <= 18 /* Alt */ ?
|
||||||
|
function(vt100, elem) { return function(e) {
|
||||||
|
if (elem == vt100.lastSelectedKey) {
|
||||||
|
if (key == 16 /* Shift */) {
|
||||||
|
// The user clicked the Shift key
|
||||||
|
vt100.isShift = !vt100.isShift;
|
||||||
|
vt100.showShiftState(vt100.isShift);
|
||||||
|
} else if (key == 17 /* Ctrl */) {
|
||||||
|
vt100.isCtrl = !vt100.isCtrl;
|
||||||
|
vt100.showCtrlState(vt100.isCtrl);
|
||||||
|
} else if (key == 18 /* Alt */) {
|
||||||
|
vt100.isAlt = !vt100.isAlt;
|
||||||
|
vt100.showAltState(vt100.isAlt);
|
||||||
|
}
|
||||||
|
vt100.lastSelectedKey = undefined;
|
||||||
|
}
|
||||||
|
if (vt100.lastSelectedKey) {
|
||||||
|
vt100.lastSelectedKey.className = '';
|
||||||
|
vt100.lastSelectedKey = undefined;
|
||||||
|
}
|
||||||
|
return false; }; }(this, elem) :
|
||||||
|
// Regular keys generate key clicks, when the mouse button is released or
|
||||||
|
// when a mouse click event is received.
|
||||||
|
function(vt100, elem, ch, key, CH, KEY) { return function(e) {
|
||||||
|
if (vt100.lastSelectedKey) {
|
||||||
|
if (elem == vt100.lastSelectedKey) {
|
||||||
|
// The user clicked a key.
|
||||||
|
if (vt100.isShift) {
|
||||||
|
vt100.clickedKeyboard(e, elem, CH, KEY,
|
||||||
|
true, vt100.isCtrl, vt100.isAlt);
|
||||||
|
} else {
|
||||||
|
vt100.clickedKeyboard(e, elem, ch, key,
|
||||||
|
false, vt100.isCtrl, vt100.isAlt);
|
||||||
|
}
|
||||||
|
vt100.isShift = false;
|
||||||
|
vt100.showShiftState(false);
|
||||||
|
vt100.isCtrl = false;
|
||||||
|
vt100.showCtrlState(false);
|
||||||
|
vt100.isAlt = false;
|
||||||
|
vt100.showAltState(false);
|
||||||
|
}
|
||||||
|
vt100.lastSelectedKey.className = '';
|
||||||
|
vt100.lastSelectedKey = undefined;
|
||||||
|
}
|
||||||
|
elem.className = '';
|
||||||
|
return false; }; }(this, elem, ch, key, CH, KEY);
|
||||||
|
this.addListener(elem, 'mouseup', clicked);
|
||||||
|
this.addListener(elem, 'click', clicked);
|
||||||
|
|
||||||
|
// When moving the mouse away from a key, check if any keys need to be
|
||||||
|
// deselected.
|
||||||
|
this.addListener(elem, 'mouseout',
|
||||||
|
function(vt100, elem, key) { return function(e) {
|
||||||
|
if (key == 16 /* Shift */) {
|
||||||
|
if (!elem.className == vt100.isShift) {
|
||||||
|
vt100.showShiftState(vt100.isShift);
|
||||||
|
}
|
||||||
|
} else if (key == 17 /* Ctrl */) {
|
||||||
|
if (!elem.className == vt100.isCtrl) {
|
||||||
|
vt100.showCtrlState(vt100.isCtrl);
|
||||||
|
}
|
||||||
|
} else if (key == 18 /* Alt */) {
|
||||||
|
if (!elem.className == vt100.isAlt) {
|
||||||
|
vt100.showAltState(vt100.isAlt);
|
||||||
|
}
|
||||||
|
} else if (elem.className) {
|
||||||
|
elem.className = '';
|
||||||
|
vt100.lastSelectedKey = elem;
|
||||||
|
} else if (vt100.lastSelectedKey) {
|
||||||
|
vt100.resetLastSelectedKey(e);
|
||||||
|
}
|
||||||
|
return false; }; }(this, elem, key));
|
||||||
|
|
||||||
|
// When moving the mouse over a key, select it if the user is still holding
|
||||||
|
// the mouse button down (i.e. elem == lastSelectedKey)
|
||||||
|
this.addListener(elem, 'mouseover',
|
||||||
|
function(vt100, elem, key) { return function(e) {
|
||||||
|
if (elem == vt100.lastSelectedKey) {
|
||||||
|
if (key == 16 /* Shift */) {
|
||||||
|
if (!elem.className != vt100.isShift) {
|
||||||
|
vt100.showShiftState(!vt100.isShift);
|
||||||
|
}
|
||||||
|
} else if (key == 17 /* Ctrl */) {
|
||||||
|
if (!elem.className != vt100.isCtrl) {
|
||||||
|
vt100.showCtrlState(!vt100.isCtrl);
|
||||||
|
}
|
||||||
|
} else if (key == 18 /* Alt */) {
|
||||||
|
if (!elem.className != vt100.isAlt) {
|
||||||
|
vt100.showAltState(!vt100.isAlt);
|
||||||
|
}
|
||||||
|
} else if (!elem.className) {
|
||||||
|
elem.className = 'selected';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
vt100.resetLastSelectedKey(e);
|
||||||
|
}
|
||||||
|
return false; }; }(this, elem, key));
|
||||||
|
};
|
||||||
|
|
||||||
|
VT100.prototype.initializeKeyBindings = function(elem) {
|
||||||
|
if (elem) {
|
||||||
|
if (elem.nodeName == "I" || elem.nodeName == "B") {
|
||||||
|
if (elem.id) {
|
||||||
|
// Function keys. The Javascript keycode is part of the "id"
|
||||||
|
var i = parseInt(elem.id);
|
||||||
|
if (i) {
|
||||||
|
// If the id does not parse as a number, it is not a keycode.
|
||||||
|
this.addKeyBinding(elem, undefined, i);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
var child = elem.firstChild;
|
||||||
|
if (child.nodeName == "#text") {
|
||||||
|
// If the key only has a text node as a child, then it is a letter.
|
||||||
|
// Automatically compute the lower and upper case version of the key.
|
||||||
|
this.addKeyBinding(elem, this.getTextContent(child).toLowerCase());
|
||||||
|
} else {
|
||||||
|
// If the key has two children, they are the lower and upper case
|
||||||
|
// character code, respectively.
|
||||||
|
this.addKeyBinding(elem, this.getTextContent(child), undefined,
|
||||||
|
this.getTextContent(child.nextSibling));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Recursively parse all other child nodes.
|
||||||
|
for (elem = elem.firstChild; elem; elem = elem.nextSibling) {
|
||||||
|
this.initializeKeyBindings(elem);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
VT100.prototype.initializeKeyboard = function() {
|
||||||
|
// Configure mouse event handlers for button that displays/hides keyboard
|
||||||
|
var box = this.keyboard.firstChild;
|
||||||
|
this.hideSoftKeyboard();
|
||||||
|
this.addListener(this.keyboardImage, 'click',
|
||||||
|
function(vt100) { return function(e) {
|
||||||
|
if (vt100.keyboard.style.display != '') {
|
||||||
|
if (vt100.reconnectBtn.style.visibility != '') {
|
||||||
|
vt100.showSoftKeyboard();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
vt100.hideSoftKeyboard();
|
||||||
|
vt100.input.focus();
|
||||||
|
}
|
||||||
|
return false; }; }(this));
|
||||||
|
|
||||||
|
// Enable button that displays keyboard
|
||||||
|
if (this.softKeyboard) {
|
||||||
|
this.keyboardImage.style.visibility = 'visible';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Configure mouse event handlers for on-screen keyboard
|
||||||
|
this.addListener(this.keyboard, 'click',
|
||||||
|
function(vt100) { return function(e) {
|
||||||
|
vt100.hideSoftKeyboard();
|
||||||
|
vt100.input.focus();
|
||||||
|
return false; }; }(this));
|
||||||
|
this.addListener(this.keyboard, 'selectstart', this.cancelEvent);
|
||||||
|
this.addListener(box, 'click', this.cancelEvent);
|
||||||
|
this.addListener(box, 'mouseup',
|
||||||
|
function(vt100) { return function(e) {
|
||||||
|
if (vt100.lastSelectedKey) {
|
||||||
|
vt100.lastSelectedKey.className = '';
|
||||||
|
vt100.lastSelectedKey = undefined;
|
||||||
|
}
|
||||||
|
return false; }; }(this));
|
||||||
|
this.addListener(box, 'mouseout',
|
||||||
|
function(vt100) { return function(e) {
|
||||||
|
return vt100.resetLastSelectedKey(e); }; }(this));
|
||||||
|
this.addListener(box, 'mouseover',
|
||||||
|
function(vt100) { return function(e) {
|
||||||
|
return vt100.resetLastSelectedKey(e); }; }(this));
|
||||||
|
|
||||||
|
// Configure SHIFT key behavior
|
||||||
|
var style = document.createElement('style');
|
||||||
|
var id = document.createAttribute('id');
|
||||||
|
id.nodeValue = 'shift_state';
|
||||||
|
style.setAttributeNode(id);
|
||||||
|
var type = document.createAttribute('type');
|
||||||
|
type.nodeValue = 'text/css';
|
||||||
|
style.setAttributeNode(type);
|
||||||
|
document.getElementsByTagName('head')[0].appendChild(style);
|
||||||
|
|
||||||
|
// Set up key bindings
|
||||||
|
this.initializeKeyBindings(box);
|
||||||
|
};
|
||||||
|
|
||||||
VT100.prototype.initializeElements = function(container) {
|
VT100.prototype.initializeElements = function(container) {
|
||||||
// If the necessary objects have not already been defined in the HTML
|
// If the necessary objects have not already been defined in the HTML
|
||||||
// page, create them now.
|
// page, create them now.
|
||||||
|
@ -483,6 +805,9 @@ VT100.prototype.initializeElements = function(container) {
|
||||||
|
|
||||||
if (!this.getChildById(this.container, 'reconnect') ||
|
if (!this.getChildById(this.container, 'reconnect') ||
|
||||||
!this.getChildById(this.container, 'menu') ||
|
!this.getChildById(this.container, 'menu') ||
|
||||||
|
!this.getChildById(this.container, 'keyboard') ||
|
||||||
|
!this.getChildById(this.container, 'kbd_button') ||
|
||||||
|
!this.getChildById(this.container, 'kbd_img') ||
|
||||||
!this.getChildById(this.container, 'scrollable') ||
|
!this.getChildById(this.container, 'scrollable') ||
|
||||||
!this.getChildById(this.container, 'console') ||
|
!this.getChildById(this.container, 'console') ||
|
||||||
!this.getChildById(this.container, 'alt_console') ||
|
!this.getChildById(this.container, 'alt_console') ||
|
||||||
|
@ -525,7 +850,15 @@ VT100.prototype.initializeElements = function(container) {
|
||||||
'<div id="cursize" style="visibility: hidden">' +
|
'<div id="cursize" style="visibility: hidden">' +
|
||||||
'</div>' +
|
'</div>' +
|
||||||
'<div id="menu"></div>' +
|
'<div id="menu"></div>' +
|
||||||
|
'<div id="keyboard" unselectable="on">' +
|
||||||
|
KEYBOARD +
|
||||||
|
'</div>' +
|
||||||
'<div id="scrollable">' +
|
'<div id="scrollable">' +
|
||||||
|
'<table id="kbd_button">' +
|
||||||
|
'<tr><td width="100%"> </td>' +
|
||||||
|
'<td><img id="kbd_img" src="keyboard.png" /></td>' +
|
||||||
|
'<td> </td></tr>' +
|
||||||
|
'</table>' +
|
||||||
'<pre id="lineheight"> </pre>' +
|
'<pre id="lineheight"> </pre>' +
|
||||||
'<pre id="console">' +
|
'<pre id="console">' +
|
||||||
'<pre></pre>' +
|
'<pre></pre>' +
|
||||||
|
@ -566,6 +899,8 @@ VT100.prototype.initializeElements = function(container) {
|
||||||
this.reconnectBtn = this.getChildById(this.container,'reconnect');
|
this.reconnectBtn = this.getChildById(this.container,'reconnect');
|
||||||
this.curSizeBox = this.getChildById(this.container, 'cursize');
|
this.curSizeBox = this.getChildById(this.container, 'cursize');
|
||||||
this.menu = this.getChildById(this.container, 'menu');
|
this.menu = this.getChildById(this.container, 'menu');
|
||||||
|
this.keyboard = this.getChildById(this.container, 'keyboard');
|
||||||
|
this.keyboardImage = this.getChildById(this.container, 'kbd_img');
|
||||||
this.scrollable = this.getChildById(this.container,
|
this.scrollable = this.getChildById(this.container,
|
||||||
'scrollable');
|
'scrollable');
|
||||||
this.lineheight = this.getChildById(this.container,
|
this.lineheight = this.getChildById(this.container,
|
||||||
|
@ -646,6 +981,9 @@ VT100.prototype.initializeElements = function(container) {
|
||||||
// Hide context menu
|
// Hide context menu
|
||||||
this.hideContextMenu();
|
this.hideContextMenu();
|
||||||
|
|
||||||
|
// Set up onscreen soft keyboard
|
||||||
|
this.initializeKeyboard();
|
||||||
|
|
||||||
// Add listener to reconnect button
|
// Add listener to reconnect button
|
||||||
this.addListener(this.reconnectBtn.firstChild, 'click',
|
this.addListener(this.reconnectBtn.firstChild, 'click',
|
||||||
function(vt100) {
|
function(vt100) {
|
||||||
|
@ -733,6 +1071,7 @@ VT100.prototype.reconnect = function() {
|
||||||
|
|
||||||
VT100.prototype.showReconnect = function(state) {
|
VT100.prototype.showReconnect = function(state) {
|
||||||
if (state) {
|
if (state) {
|
||||||
|
this.hideSoftKeyboard();
|
||||||
this.reconnectBtn.style.visibility = '';
|
this.reconnectBtn.style.visibility = '';
|
||||||
} else {
|
} else {
|
||||||
this.reconnectBtn.style.visibility = 'hidden';
|
this.reconnectBtn.style.visibility = 'hidden';
|
||||||
|
@ -766,6 +1105,9 @@ VT100.prototype.resized = function(w, h) {
|
||||||
};
|
};
|
||||||
|
|
||||||
VT100.prototype.resizer = function() {
|
VT100.prototype.resizer = function() {
|
||||||
|
// Hide onscreen soft keyboard
|
||||||
|
this.hideSoftKeyboard();
|
||||||
|
|
||||||
// The cursor can get corrupted if the print-preview is displayed in Firefox.
|
// The cursor can get corrupted if the print-preview is displayed in Firefox.
|
||||||
// Recreating it, will repair it.
|
// Recreating it, will repair it.
|
||||||
var newCursor = document.createElement('pre');
|
var newCursor = document.createElement('pre');
|
||||||
|
@ -945,6 +1287,17 @@ VT100.prototype.cancelEvent = function(event) {
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
VT100.prototype.mousePosition = function(event) {
|
||||||
|
var offsetX = this.container.offsetLeft;
|
||||||
|
var offsetY = this.container.offsetTop;
|
||||||
|
for (var e = this.container; e = e.offsetParent; ) {
|
||||||
|
offsetX += e.offsetLeft;
|
||||||
|
offsetY += e.offsetTop;
|
||||||
|
}
|
||||||
|
return [ event.clientX - offsetX,
|
||||||
|
event.clientY - offsetY ];
|
||||||
|
};
|
||||||
|
|
||||||
VT100.prototype.mouseEvent = function(event, type) {
|
VT100.prototype.mouseEvent = function(event, type) {
|
||||||
// If any text is currently selected, do not move the focus as that would
|
// If any text is currently selected, do not move the focus as that would
|
||||||
// invalidate the selection.
|
// invalidate the selection.
|
||||||
|
@ -954,15 +1307,10 @@ VT100.prototype.mouseEvent = function(event, type) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compute mouse position in characters.
|
// Compute mouse position in characters.
|
||||||
var offsetX = this.container.offsetLeft;
|
var position = this.mousePosition(event);
|
||||||
var offsetY = this.container.offsetTop;
|
var x = Math.floor(position[0] / this.cursorWidth);
|
||||||
for (var e = this.container; e = e.offsetParent; ) {
|
var y = Math.floor((position[1] + this.scrollable.scrollTop) /
|
||||||
offsetX += e.offsetLeft;
|
this.cursorHeight) - this.numScrollbackLines;
|
||||||
offsetY += e.offsetTop;
|
|
||||||
}
|
|
||||||
var x = (event.clientX - offsetX) / this.cursorWidth;
|
|
||||||
var y = ((event.clientY - offsetY) + this.scrollable.offsetTop) /
|
|
||||||
this.cursorHeight - this.numScrollbackLines;
|
|
||||||
var inside = true;
|
var inside = true;
|
||||||
if (x >= this.terminalWidth) {
|
if (x >= this.terminalWidth) {
|
||||||
x = this.terminalWidth - 1;
|
x = this.terminalWidth - 1;
|
||||||
|
@ -1022,7 +1370,7 @@ VT100.prototype.mouseEvent = function(event, type) {
|
||||||
// Bring up context menu.
|
// Bring up context menu.
|
||||||
if (button == 2 && !event.shiftKey) {
|
if (button == 2 && !event.shiftKey) {
|
||||||
if (type == MOUSE_DOWN) {
|
if (type == MOUSE_DOWN) {
|
||||||
this.showContextMenu(event.clientX - offsetX, event.clientY - offsetY);
|
this.showContextMenu(position[0], position[1]);
|
||||||
}
|
}
|
||||||
return this.cancelEvent(event);
|
return this.cancelEvent(event);
|
||||||
}
|
}
|
||||||
|
@ -1058,6 +1406,29 @@ VT100.prototype.getTextContent = function(elem) {
|
||||||
(typeof elem.textContent == 'undefined' ? elem.innerText : '');
|
(typeof elem.textContent == 'undefined' ? elem.innerText : '');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
VT100.prototype.setTextContentRaw = function(elem, s) {
|
||||||
|
// Updating the content of an element is an expensive operation. It actually
|
||||||
|
// pays off to first check whether the element is still unchanged.
|
||||||
|
if (typeof elem.textContent == 'undefined') {
|
||||||
|
if (elem.innerText != s) {
|
||||||
|
try {
|
||||||
|
elem.innerText = s;
|
||||||
|
} catch (e) {
|
||||||
|
// Very old versions of IE do not allow setting innerText. Instead,
|
||||||
|
// remove all children, by setting innerHTML and then set the text
|
||||||
|
// using DOM methods.
|
||||||
|
elem.innerHTML = '';
|
||||||
|
elem.appendChild(document.createTextNode(
|
||||||
|
this.replaceChar(s, ' ', '\u00A0')));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (elem.textContent != s) {
|
||||||
|
elem.textContent = s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
VT100.prototype.setTextContent = function(elem, s) {
|
VT100.prototype.setTextContent = function(elem, s) {
|
||||||
// Check if we find any URLs in the text. If so, automatically convert them
|
// Check if we find any URLs in the text. If so, automatically convert them
|
||||||
// to links.
|
// to links.
|
||||||
|
@ -1103,26 +1474,7 @@ VT100.prototype.setTextContent = function(elem, s) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Updating the content of an element is an expensive operation. It actually
|
this.setTextContentRaw(elem, s);
|
||||||
// pays off to first check whether the element is still unchanged.
|
|
||||||
if (typeof elem.textContent == 'undefined') {
|
|
||||||
if (elem.innerText != s) {
|
|
||||||
try {
|
|
||||||
elem.innerText = s;
|
|
||||||
} catch (e) {
|
|
||||||
// Very old versions of IE do not allow setting innerText. Instead,
|
|
||||||
// remove all children, by setting innerHTML and then set the text
|
|
||||||
// using DOM methods.
|
|
||||||
elem.innerHTML = '';
|
|
||||||
elem.appendChild(document.createTextNode(
|
|
||||||
this.replaceChar(s, ' ', '\u00A0')));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (elem.textContent != s) {
|
|
||||||
elem.textContent = s;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
VT100.prototype.insertBlankLine = function(y, color, style) {
|
VT100.prototype.insertBlankLine = function(y, color, style) {
|
||||||
|
@ -1578,27 +1930,21 @@ VT100.prototype.enableAlternateScreen = function(state) {
|
||||||
this.console[this.currentScreen].style.display = '';
|
this.console[this.currentScreen].style.display = '';
|
||||||
|
|
||||||
// Select appropriate character pitch.
|
// Select appropriate character pitch.
|
||||||
var styles = [ 'transform',
|
var transform = this.getTransformName();
|
||||||
'WebkitTransform',
|
if (transform) {
|
||||||
'MozTransform',
|
if (state) {
|
||||||
'filter' ];
|
// Upon enabling the alternate screen, we switch to 80 column mode. But
|
||||||
for (var i = 0; i < styles.length; ++i) {
|
// upon returning to the regular screen, we restore the mode that was
|
||||||
if (typeof this.console[0].style[styles[i]] != 'undefined') {
|
// in effect previously.
|
||||||
if (state) {
|
this.console[1].style[transform] = '';
|
||||||
// Upon enabling the alternate screen, we switch to 80 column mode. But
|
}
|
||||||
// upon returning to the regular screen, we restore the mode that was
|
var style =
|
||||||
// in effect previously.
|
this.console[this.currentScreen].style[transform];
|
||||||
this.console[1].style[styles[i]] = '';
|
this.cursor.style[transform] = style;
|
||||||
}
|
this.space.style[transform] = style;
|
||||||
var style =
|
this.scale = style == '' ? 1.0:1.65;
|
||||||
this.console[this.currentScreen].style[styles[i]];
|
if (transform == 'filter') {
|
||||||
this.cursor.style[styles[i]] = style;
|
this.console[this.currentScreen].style.width = style == '' ? '165%':'';
|
||||||
this.space.style[styles[i]] = style;
|
|
||||||
this.scale = style == '' ? 1.0:1.65;
|
|
||||||
if (styles[i] == 'filter') {
|
|
||||||
this.console[this.currentScreen].style.width = style == '' ? '165%':'';
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.resizer();
|
this.resizer();
|
||||||
|
@ -1969,6 +2315,70 @@ VT100.prototype.toggleBell = function() {
|
||||||
this.visualBell = !this.visualBell;
|
this.visualBell = !this.visualBell;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
VT100.prototype.toggleSoftKeyboard = function() {
|
||||||
|
this.softKeyboard = !this.softKeyboard;
|
||||||
|
this.keyboardImage.style.visibility = this.softKeyboard ? 'visible' : '';
|
||||||
|
};
|
||||||
|
|
||||||
|
VT100.prototype.deselectKeys = function(elem) {
|
||||||
|
if (elem && elem.className == 'selected') {
|
||||||
|
elem.className = '';
|
||||||
|
}
|
||||||
|
for (elem = elem.firstChild; elem; elem = elem.nextSibling) {
|
||||||
|
this.deselectKeys(elem);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
VT100.prototype.showSoftKeyboard = function() {
|
||||||
|
// Make sure no key is currently selected
|
||||||
|
this.lastSelectedKey = undefined;
|
||||||
|
this.deselectKeys(this.keyboard);
|
||||||
|
this.isShift = false;
|
||||||
|
this.showShiftState(false);
|
||||||
|
this.isCtrl = false;
|
||||||
|
this.showCtrlState(false);
|
||||||
|
this.isAlt = false;
|
||||||
|
this.showAltState(false);
|
||||||
|
|
||||||
|
this.keyboard.style.left = '0px';
|
||||||
|
this.keyboard.style.top = '0px';
|
||||||
|
this.keyboard.style.width = this.container.offsetWidth + 'px';
|
||||||
|
this.keyboard.style.height = this.container.offsetHeight + 'px';
|
||||||
|
this.keyboard.style.visibility = 'hidden';
|
||||||
|
this.keyboard.style.display = '';
|
||||||
|
|
||||||
|
var kbd = this.keyboard.firstChild;
|
||||||
|
var scale = 1.0;
|
||||||
|
var transform = this.getTransformName();
|
||||||
|
if (transform) {
|
||||||
|
kbd.style[transform] = '';
|
||||||
|
if (kbd.offsetWidth > 0.9 * this.container.offsetWidth) {
|
||||||
|
scale = (kbd.offsetWidth/
|
||||||
|
this.container.offsetWidth)/0.9;
|
||||||
|
}
|
||||||
|
if (kbd.offsetHeight > 0.9 * this.container.offsetHeight) {
|
||||||
|
scale = Math.max((kbd.offsetHeight/
|
||||||
|
this.container.offsetHeight)/0.9);
|
||||||
|
}
|
||||||
|
var style = this.getTransformStyle(transform,
|
||||||
|
scale > 1.0 ? scale : undefined);
|
||||||
|
kbd.style[transform] = style;
|
||||||
|
}
|
||||||
|
if (transform == 'filter') {
|
||||||
|
scale = 1.0;
|
||||||
|
}
|
||||||
|
kbd.style.left = ((this.container.offsetWidth -
|
||||||
|
kbd.offsetWidth/scale)/2) + 'px';
|
||||||
|
kbd.style.top = ((this.container.offsetHeight -
|
||||||
|
kbd.offsetHeight/scale)/2) + 'px';
|
||||||
|
|
||||||
|
this.keyboard.style.visibility = 'visible';
|
||||||
|
};
|
||||||
|
|
||||||
|
VT100.prototype.hideSoftKeyboard = function() {
|
||||||
|
this.keyboard.style.display = 'none';
|
||||||
|
};
|
||||||
|
|
||||||
VT100.prototype.toggleCursorBlinking = function() {
|
VT100.prototype.toggleCursorBlinking = function() {
|
||||||
this.blinkingCursor = !this.blinkingCursor;
|
this.blinkingCursor = !this.blinkingCursor;
|
||||||
};
|
};
|
||||||
|
@ -2007,6 +2417,9 @@ VT100.prototype.showContextMenu = function(x, y) {
|
||||||
'<li>' +
|
'<li>' +
|
||||||
(this.visualBell ? '<img src="enabled.gif" />' : '') +
|
(this.visualBell ? '<img src="enabled.gif" />' : '') +
|
||||||
'Visual Bell</li>'+
|
'Visual Bell</li>'+
|
||||||
|
'<li>' +
|
||||||
|
(this.softKeyboard ? '<img src="enabled.gif" />' : '') +
|
||||||
|
'Onscreen Keyboard</li>' +
|
||||||
'<li id="endconfig">' +
|
'<li id="endconfig">' +
|
||||||
(this.blinkingCursor ? '<img src="enabled.gif" />' : '') +
|
(this.blinkingCursor ? '<img src="enabled.gif" />' : '') +
|
||||||
'Blinking Cursor</li>'+
|
'Blinking Cursor</li>'+
|
||||||
|
@ -2038,6 +2451,7 @@ VT100.prototype.showContextMenu = function(x, y) {
|
||||||
// Actions for default items
|
// Actions for default items
|
||||||
var actions = [ this.copyLast, p, this.reset,
|
var actions = [ this.copyLast, p, this.reset,
|
||||||
this.toggleUTF, this.toggleBell,
|
this.toggleUTF, this.toggleBell,
|
||||||
|
this.toggleSoftKeyboard,
|
||||||
this.toggleCursorBlinking ];
|
this.toggleCursorBlinking ];
|
||||||
|
|
||||||
// Actions for user CSS styles (if any)
|
// Actions for user CSS styles (if any)
|
||||||
|
@ -2093,26 +2507,30 @@ VT100.prototype.showContextMenu = function(x, y) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Position menu next to the mouse pointer
|
// Position menu next to the mouse pointer
|
||||||
if (x + popup.clientWidth > this.container.offsetWidth) {
|
this.menu.style.left = '0px';
|
||||||
x = this.container.offsetWidth - popup.clientWidth;
|
this.menu.style.top = '0px';
|
||||||
|
this.menu.style.width = this.container.offsetWidth + 'px';
|
||||||
|
this.menu.style.height = this.container.offsetHeight + 'px';
|
||||||
|
popup.style.left = '0px';
|
||||||
|
popup.style.top = '0px';
|
||||||
|
|
||||||
|
var margin = 2;
|
||||||
|
if (x + popup.clientWidth >= this.container.offsetWidth - margin) {
|
||||||
|
x = this.container.offsetWidth-popup.clientWidth - margin - 1;
|
||||||
}
|
}
|
||||||
if (x < 0) {
|
if (x < margin) {
|
||||||
x = 0;
|
x = margin;
|
||||||
}
|
}
|
||||||
if (y + popup.clientHeight > this.container.offsetHeight) {
|
if (y + popup.clientHeight >= this.container.offsetHeight - margin) {
|
||||||
y = this.container.offsetHeight-popup.clientHeight;
|
y = this.container.offsetHeight-popup.clientHeight - margin - 1;
|
||||||
}
|
}
|
||||||
if (y < 0) {
|
if (y < margin) {
|
||||||
y = 0;
|
y = margin;
|
||||||
}
|
}
|
||||||
popup.style.left = x + 'px';
|
popup.style.left = x + 'px';
|
||||||
popup.style.top = y + 'px';
|
popup.style.top = y + 'px';
|
||||||
|
|
||||||
// Block all other interactions with the terminal emulator
|
// Block all other interactions with the terminal emulator
|
||||||
this.menu.style.left = '0px';
|
|
||||||
this.menu.style.top = '0px';
|
|
||||||
this.menu.style.width = this.container.offsetWidth + 'px';
|
|
||||||
this.menu.style.height = this.container.offsetHeight + 'px';
|
|
||||||
this.addListener(this.menu, 'click', function(vt100) {
|
this.addListener(this.menu, 'click', function(vt100) {
|
||||||
return function() {
|
return function() {
|
||||||
vt100.hideContextMenu();
|
vt100.hideContextMenu();
|
||||||
|
@ -2895,39 +3313,42 @@ VT100.prototype.restoreCursor = function() {
|
||||||
this.savedY[this.currentScreen]);
|
this.savedY[this.currentScreen]);
|
||||||
};
|
};
|
||||||
|
|
||||||
VT100.prototype.set80_132Mode = function(state) {
|
VT100.prototype.getTransformName = function() {
|
||||||
var transform = undefined;
|
var styles = [ 'transform', 'WebkitTransform', 'MozTransform', 'filter' ];
|
||||||
var styles = [ 'transform',
|
|
||||||
'WebkitTransform',
|
|
||||||
'MozTransform',
|
|
||||||
'filter'
|
|
||||||
];
|
|
||||||
for (var i = 0; i < styles.length; ++i) {
|
for (var i = 0; i < styles.length; ++i) {
|
||||||
if (typeof this.console[0].style[styles[i]] != 'undefined') {
|
if (typeof this.console[0].style[styles[i]] != 'undefined') {
|
||||||
transform = styles[i];
|
return styles[i];
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
VT100.prototype.getTransformStyle = function(transform, scale) {
|
||||||
|
return scale && scale != 1.0
|
||||||
|
? transform == 'filter'
|
||||||
|
? 'progid:DXImageTransform.Microsoft.Matrix(' +
|
||||||
|
'M11=' + (1.0/scale) + ',M12=0,M21=0,M22=1,' +
|
||||||
|
"sizingMethod='auto expand')"
|
||||||
|
: 'translateX(-50%) ' +
|
||||||
|
'scaleX(' + (1.0/scale) + ') ' +
|
||||||
|
'translateX(50%)'
|
||||||
|
: '';
|
||||||
|
};
|
||||||
|
|
||||||
|
VT100.prototype.set80_132Mode = function(state) {
|
||||||
|
var transform = this.getTransformName();
|
||||||
if (transform) {
|
if (transform) {
|
||||||
if ((this.console[this.currentScreen].style[transform] != '') == state) {
|
if ((this.console[this.currentScreen].style[transform] != '') == state) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var style =
|
var style = state ?
|
||||||
state ? transform == 'filter'
|
this.getTransformStyle(transform, 1.65):'';
|
||||||
? 'progid:DXImageTransform.Microsoft.Matrix(' +
|
|
||||||
'M11=0.606060606060606060606,M12=0,M21=0,M22=1,' +
|
|
||||||
"sizingMethod='auto expand')"
|
|
||||||
: 'translateX(-50%) ' +
|
|
||||||
'scaleX(0.606060606060606060606) ' +
|
|
||||||
'translateX(50%)'
|
|
||||||
: '';
|
|
||||||
this.console[this.currentScreen].style[transform] = style;
|
this.console[this.currentScreen].style[transform] = style;
|
||||||
this.cursor.style[transform] = style;
|
this.cursor.style[transform] = style;
|
||||||
this.space.style[transform] = style;
|
this.space.style[transform] = style;
|
||||||
this.scale = state ? 1.65 : 1.0;
|
this.scale = state ? 1.65 : 1.0;
|
||||||
if (transform == 'filter') {
|
if (transform == 'filter') {
|
||||||
this.console[this.currentScreen].style.width = state ? '165%' : '';
|
this.console[this.currentScreen].style.width = state ? '165%' : '';
|
||||||
}
|
}
|
||||||
this.resizer();
|
this.resizer();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue