From 7ab3b32465a3b4ec4a2d551fde5c3adc14f83ae9 Mon Sep 17 00:00:00 2001 From: zodiac Date: Tue, 11 Aug 2009 07:21:51 +0000 Subject: [PATCH] Initial version of code that allows users to interactively select from different style sheet options. This code is still incomplete and subject to change (e.g. the command line syntax might still change). But it is good enough to demonstrate the concept on simple style sheets (such as selecting between normal and reverse video). git-svn-id: https://shellinabox.googlecode.com/svn/trunk@165 0da03de8-d603-11dd-86c2-0f8696b7b6f9 --- Makefile.am | 2 + Makefile.in | 19 ++- config.h | 2 +- configure | 2 +- configure.ac | 2 +- demo/vt100.js | 127 +++++++++++++++++++- shellinabox/root_page.html | 31 ++--- shellinabox/service.c | 4 +- shellinabox/shell_in_a_box.js | 2 +- shellinabox/shellinaboxd.c | 78 +++++++++---- shellinabox/usercss.c | 210 ++++++++++++++++++++++++++++++++++ shellinabox/usercss.h | 65 +++++++++++ shellinabox/vt100.js | 127 +++++++++++++++++++- shellinabox/vt100.jspp | 125 +++++++++++++++++++- 14 files changed, 742 insertions(+), 54 deletions(-) create mode 100644 shellinabox/usercss.c create mode 100644 shellinabox/usercss.h diff --git a/Makefile.am b/Makefile.am index 10182e7..1c78369 100644 --- a/Makefile.am +++ b/Makefile.am @@ -76,6 +76,8 @@ shellinaboxd_SOURCES = shellinabox/shellinaboxd.c \ shellinabox/service.h \ shellinabox/session.c \ shellinabox/session.h \ + shellinabox/usercss.c \ + shellinabox/usercss.h \ shellinabox/cgi_root.html \ shellinabox/root_page.html \ shellinabox/vt100.jspp \ diff --git a/Makefile.in b/Makefile.in index 856ae63..e61f461 100644 --- a/Makefile.in +++ b/Makefile.in @@ -73,7 +73,7 @@ PROGRAMS = $(bin_PROGRAMS) am__dirstamp = $(am__leading_dot)dirstamp am_shellinaboxd_OBJECTS = shellinaboxd.$(OBJEXT) \ externalfile.$(OBJEXT) launcher.$(OBJEXT) privileges.$(OBJEXT) \ - service.$(OBJEXT) session.$(OBJEXT) \ + service.$(OBJEXT) session.$(OBJEXT) usercss.$(OBJEXT) \ shellinabox/cgi_root.$(OBJEXT) shellinabox/root_page.$(OBJEXT) \ shellinabox/vt100.$(OBJEXT) \ shellinabox/shell_in_a_box.$(OBJEXT) \ @@ -320,6 +320,8 @@ shellinaboxd_SOURCES = shellinabox/shellinaboxd.c \ shellinabox/service.h \ shellinabox/session.c \ shellinabox/session.h \ + shellinabox/usercss.c \ + shellinabox/usercss.h \ shellinabox/cgi_root.html \ shellinabox/root_page.html \ shellinabox/vt100.jspp \ @@ -503,6 +505,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssl.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/trie.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/url.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/usercss.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @@ -658,6 +661,20 @@ session.obj: shellinabox/session.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o session.obj `if test -f 'shellinabox/session.c'; then $(CYGPATH_W) 'shellinabox/session.c'; else $(CYGPATH_W) '$(srcdir)/shellinabox/session.c'; fi` +usercss.o: shellinabox/usercss.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT usercss.o -MD -MP -MF $(DEPDIR)/usercss.Tpo -c -o usercss.o `test -f 'shellinabox/usercss.c' || echo '$(srcdir)/'`shellinabox/usercss.c +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/usercss.Tpo $(DEPDIR)/usercss.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='shellinabox/usercss.c' object='usercss.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o usercss.o `test -f 'shellinabox/usercss.c' || echo '$(srcdir)/'`shellinabox/usercss.c + +usercss.obj: shellinabox/usercss.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT usercss.obj -MD -MP -MF $(DEPDIR)/usercss.Tpo -c -o usercss.obj `if test -f 'shellinabox/usercss.c'; then $(CYGPATH_W) 'shellinabox/usercss.c'; else $(CYGPATH_W) '$(srcdir)/shellinabox/usercss.c'; fi` +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/usercss.Tpo $(DEPDIR)/usercss.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='shellinabox/usercss.c' object='usercss.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o usercss.obj `if test -f 'shellinabox/usercss.c'; then $(CYGPATH_W) 'shellinabox/usercss.c'; else $(CYGPATH_W) '$(srcdir)/shellinabox/usercss.c'; fi` + mostlyclean-libtool: -rm -f *.lo diff --git a/config.h b/config.h index 8f5d734..d2118c9 100644 --- a/config.h +++ b/config.h @@ -138,7 +138,7 @@ #define STDC_HEADERS 1 /* Most recent revision number in the version control system */ -#define VCS_REVISION "164" +#define VCS_REVISION "165" /* Version number of package */ #define VERSION "2.9" diff --git a/configure b/configure index 399f436..37e5ae4 100755 --- a/configure +++ b/configure @@ -2317,7 +2317,7 @@ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $ ac_compiler_gnu=$ac_cv_c_compiler_gnu -VCS_REVISION=164 +VCS_REVISION=165 cat >>confdefs.h <<_ACEOF diff --git a/configure.ac b/configure.ac index 3cdd440..b214501 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ AC_PREREQ(2.57) dnl This is the one location where the authoritative version number is stored AC_INIT(shellinabox, 2.9, markus@shellinabox.com) -VCS_REVISION=164 +VCS_REVISION=165 AC_SUBST(VCS_REVISION) AC_DEFINE_UNQUOTED(VCS_REVISION, "${VCS_REVISION}", [Most recent revision number in the version control system]) diff --git a/demo/vt100.js b/demo/vt100.js index 23dd26f..e66f163 100644 --- a/demo/vt100.js +++ b/demo/vt100.js @@ -259,6 +259,108 @@ VT100.prototype.addListener = function(elem, event, listener) { } }; +VT100.prototype.initializeUserCSSStyles = function() { + this.usercssActions = []; + if (typeof userCSSList != 'undefined') { + var menu = ''; + var group = ''; + var wasSingleSel = 1; + var beginOfGroup = 0; + for (var i = 0; i <= userCSSList.length; ++i) { + if (i < userCSSList.length) { + var label = userCSSList[i][0]; + var newGroup = userCSSList[i][1]; + var enabled = userCSSList[i][2]; + + // Add user style sheet to document + var style = document.createElement('link'); + var id = document.createAttribute('id'); + id.nodeValue = 'usercss-' + i; + style.setAttributeNode(id); + var rel = document.createAttribute('rel'); + rel.nodeValue = 'stylesheet'; + style.setAttributeNode(rel); + var href = document.createAttribute('href'); + href.nodeValue = 'usercss-' + i + '.css'; + style.setAttributeNode(href); + var type = document.createAttribute('type'); + type.nodeValue = 'text/css'; + style.setAttributeNode(type); + document.getElementsByTagName('head')[0].appendChild(style); + style.disabled = !enabled; + } + + // Add entry to menu + if (newGroup || i == userCSSList.length) { + if (beginOfGroup != 0 && (i - beginOfGroup > 1 || !wasSingleSel)) { + // The last group had multiple entries that are mutually exclusive; + // or the previous to last group did. In either case, we need to + // append a "
" before we can add the last group to the menu. + menu += '
'; + } + wasSingleSel = i - beginOfGroup < 1; + menu += group; + group = ''; + + for (var j = beginOfGroup; j < i; ++j) { + this.usercssActions[this.usercssActions.length] = + function(vt100, current, begin, count) { + + // Deselect all other entries in the group, then either select + // (for multiple entries in group) or toggle (for on/off entry) + // the current entry. + return function() { + var entry = vt100.getChildById(vt100.menu, + 'beginusercss'); + var i = -1; + var j = -1; + for (var c = count; c > 0; ++j) { + if (entry.tagName == 'LI') { + if (++i >= begin) { + --c; + var label = vt100.usercss.childNodes[j]; + label.innerHTML = + label.innerHTML.replace(/^\u2714 /, ''); + var sheet = document.getElementById( + 'usercss-' + i); + if (i == current) { + if (count == 1) { + sheet.disabled = !sheet.disabled; + } else { + sheet.disabled = false; + } + if (!sheet.disabled) { + label.innerHTML= '✔ ' + label.innerHTML; + } + } else { + sheet.disabled = true; + } + } + } + entry = entry.nextSibling; + } + }; + }(this, j, beginOfGroup, i - beginOfGroup); + } + + if (i == userCSSList.length) { + break; + } + + beginOfGroup = i; + } + // Collect all entries in a group, before attaching them to the menu. + // This is necessary as we don't know whether this is a group of + // mutually exclusive options (which should be separated by "
" on + // both ends), or whether this is a on/off toggle, which can be grouped + // together with other on/off options. + group += + '
  • ' + (enabled ? '✔ ' : '') + label + '
  • '; + } + this.usercss.innerHTML = menu; + } +}; + VT100.prototype.initializeElements = function(container) { // If the necessary objects have not already been defined in the HTML // page, create them now. @@ -279,6 +381,7 @@ VT100.prototype.initializeElements = function(container) { !this.getChildById(this.container, 'padding') || !this.getChildById(this.container, 'cursor') || !this.getChildById(this.container, 'lineheight') || + !this.getChildById(this.container, 'usercss') || !this.getChildById(this.container, 'space') || !this.getChildById(this.container, 'input') || !this.getChildById(this.container, 'cliphelper') || @@ -325,6 +428,7 @@ VT100.prototype.initializeElements = function(container) { '
     
    ' + '' + '' + '' + '