Merge branch 'master' of ssh://git.indexdata.com:222/home/git/pub/mkws
authorWolfram Schneider <wosch@indexdata.dk>
Mon, 20 Oct 2014 11:43:24 +0000 (11:43 +0000)
committerWolfram Schneider <wosch@indexdata.dk>
Mon, 20 Oct 2014 11:43:24 +0000 (11:43 +0000)
26 files changed:
doc/Makefile
doc/index.markdown
doc/mkws-manual.markdown
examples/htdocs/mike.html
examples/htdocs/mike2.html
src/mkws-core.js
src/mkws-popup.js
src/mkws-team.js
src/mkws-widget-authname.js
src/mkws-widget-builder.js
src/mkws-widget-categories.js
src/mkws-widget-log.js
src/mkws-widget-main.js
src/mkws-widget-record.js
src/mkws-widget-reference.js
src/mkws-widget-termlists.js
src/mkws.templates/Facet.handlebars
src/mkws.templates/Image.handlebars
src/mkws.templates/Progress.handlebars
src/mkws.templates/Ranking.handlebars
src/mkws.templates/Record.handlebars
src/mkws.templates/Records.handlebars
src/mkws.templates/Search.handlebars
src/mkws.templates/Targets.handlebars
test/README.txt
tools/htdocs/mkws.css

index 7e59c93..7d2cbbd 100644 (file)
@@ -31,9 +31,6 @@ all: $(INSTALLED)
        pandoc --standalone --toc -c mkws-doc.css $< | ./tweak-html > $@
        chmod ugo-w $@
 
-# ### In order to compile the manual, which has tables, to PDF,
-# you will need to install the Debian package
-#      texlive-latex-recommended
 ../tools/htdocs/%.pdf: %.markdown
        rm -f $@
        $(MARKDOWN2PDF) $< -o $@
index ae3382d..e830e89 100644 (file)
@@ -175,7 +175,7 @@ are and how various things are done.
   [uses a local authentication regime](//example.indexdata.com/localauth.html)
   and the corresponding
   [Apache2 configuration stanza](//example.indexdata.com/apache-config.txt).
-* [A version that uses a jQuery popup](//example.indexdata.com/popup.html).
+* [A version that uses a jQuery popup](//example.indexdata.com/popup.html?q=sushi).
 
 ### Non-standard interfaces
 
index 1e767d0..8f3cf42 100644 (file)
@@ -252,8 +252,7 @@ Inspecting metadata for templating
 MKWS makes requests to Service Proxy or Pazpar2 that perform the actual
 searching. Depending on how these are configured and what is available from the
 targets you are searching there may be more data available than what is
-presented by the default templates. In this case, you can redefine the
-`Record` template to include more fields in the full-record popup.
+presented by the default templates.
 
 Handlebars offers a convenient log helper that will output the contents of a
 variable for you to inspect. This lets you look at exactly what is being
@@ -316,33 +315,6 @@ day, a welcome message or a help page. This can be done by placing an
 search is made.
 
 
-Responsive design
------------------
-
-Metasearching applications may need to appear differently on
-small-screened mobile devices, or change their appearance when
-screen-width changes (as when a small device is rotated). To achieve
-this, MKWS supports responsive design which will move the termlists to
-the bottom on narrow screens and to the sidebar on wide screens.
-
-To turn on this behaviour, set the `responsive_design_width` to the desired
-threshhold width in pixels. For example:
-
-        <script type="text/javascript">
-            var mkws_config = {
-                responsive_design_width: 990
-            };
-        </script>
-
-If individual result-related widgets are in use in place of the
-all-in-one mkwsResults, then the redesigned application needs to
-specify the locations where the termlists should appear in both
-cases. In this case, wrap the wide-screen `mkwsTermlists` element in a
-`mkwsTermlists-Container-wide` element; and provide an
-`mkwsTermlists-Container-narrow` element in the place where the narrow-screen
-termlists should appear.
-
-
 Popup results with jQuery UI
 ----------------------------
 
index 69a070a..d6f52d6 100644 (file)
@@ -7,7 +7,7 @@
         sp_auth_credentials: "mkwstest/mkwstest"
       }
     </script>
-    <link rel="stylesheet" type="text/css" href="//mkws.indexdata.com/mkws.css" />
+    <link rel="stylesheet" type="text/css" href="tools/htdocs/mkws.css" />
     <script type="text/javascript" src="tools/htdocs/jquery-1.10.0.min.js"></script>
     <script type="text/javascript" src="tools/htdocs/jquery.json-2.4.js"></script>
     <script type="text/javascript" src="tools/htdocs/handlebars-v2.0.0.js"></script>
index 92bd0db..99aa581 100644 (file)
@@ -4,8 +4,8 @@
     <title>MKWS demo</title>
     <script type="text/javascript">
       var mkws_config = {
-//        pp2_hostname: "x.sp-mkws.indexdata.com",
-      };
+        sp_auth_credentials: "mkwstest/mkwstest"
+      }
     </script>
     <link rel="stylesheet" type="text/css" href="tools/htdocs/mkws.css" />
     <script type="text/javascript" src="tools/htdocs/jquery-1.10.0.min.js"></script>
     <script type="text/javascript" src="src/mkws-widget-record.js"></script>
     <script type="text/javascript" src="src/mkws-widget-reference.js"></script>
     <script type="text/javascript" src="src/mkws-widget-builder.js"></script>
-    <script type="text/javascript" src="mkws-widget-sru.js"></script>
+    <script type="text/javascript" src="src/mkws-templates.js"></script>
   </head>
   <body>
-    <h1>SRU example: dinosaurs at LoC</h1>
-    <div class="mkwsSRU" autosearch="dinosaur" maximumRecords="3" recordSchema="dc">Stand by ...</div>
-    <!- Use:
-http://z3950.loc.gov:7090/voyager?version=1.1&operation=searchRetrieve&query=dinosaur&maximumRecords=3&recordSchema=dc
-     -->
+    <div class="mkws-auth-name"></div>
+    <div class="mkws-switch"></div>
+    <div class="mkws-lang"></div>
+    <div class="mkws-progress"></div>
+    <div class="mkws-search"></div>
+    <div class="mkws-results"></div>
+    <div class="mkws-targets"></div>
+    <div class="mkws-stat"></div>
+    <div class="mkws-builder"></div>
   </body>
 </html>
index 3a4fa5b..56e7f28 100644 (file)
@@ -286,6 +286,23 @@ mkws.log("Using window.name '" + window.name + "'");
 // wrapper to provide local copy of the jQuery object.
 (function($) {
   var log = mkws.log;
+  var _old2new = { // Maps old-style widget names to new-style
+    'Authname': 'auth-name',
+    'ConsoleBuilder': 'console-builder',
+    'Coverart': 'cover-art',
+    'GoogleImage': 'google-image',
+    'MOTD': 'motd',
+    'MOTDContainer': 'motd-container',
+    'Perpage': 'per-page',
+    'SearchForm': 'search-form',
+  };
+  // Annoyingly, there is no built-in way to invert a hash
+  var _new2old = {};
+  for (var key in _old2new) {
+    if(_old2new.hasOwnProperty(key)) {
+      _new2old[_old2new[key]] = key;
+    }
+  }
 
   function handleNodeWithTeam(node, callback) {
     // First branch for DOM objects; second branch for jQuery objects
@@ -303,10 +320,19 @@ mkws.log("Using window.name '" + window.name + "'");
 
     for (var i = 0; i < list.length; i++) {
       var cname = list[i];
-      if (cname.match(/^mkwsTeam_/)) {
+      if (cname.match(/^mkws-team-/)) {
+        // New-style teamnames of the form mkws-team-xyz
+        teamName = cname.replace(/^mkws-team-/, '');
+      } else if (cname.match(/^mkwsTeam_/)) {
+        // Old-style teamnames of the form mkwsTeam_xyz
         teamName = cname.replace(/^mkwsTeam_/, '');
+      } else if (cname.match(/^mkws-/)) {
+        // New-style names of the from mkws-foo-bar
+        type = cname.replace(/^mkws-/, '');
       } else if (cname.match(/^mkws/)) {
-        type = cname.replace(/^mkws/, '');
+        // Old-style names of the form mkwsFooBar
+        var tmp = cname.replace(/^mkws/, '');
+        type = _old2new[tmp] || tmp.toLowerCase();
       }
     }
 
@@ -353,8 +379,8 @@ mkws.log("Using window.name '" + window.name + "'");
       for (var tname in mkws.teams) {
         var team = mkws.teams[tname];
         team.visitWidgets(function(t, w) {
-          var w1 = team.widget(t + "-Container-" + from);
-          var w2 = team.widget(t + "-Container-" + to);
+          var w1 = team.widget(t + "-container-" + from);
+          var w2 = team.widget(t + "-container-" + to);
           if (w1) {
             w1.node.hide();
           }
@@ -443,9 +469,14 @@ mkws.log("Using window.name '" + window.name + "'");
       var s = "";
       for (var type in mkws.widgetType2function) {
        if (s) s += ',';
-       s += '.mkws' + type;
-       s += ',.mkws' + type + "-Container-wide";
-       s += ',.mkws' + type + "-Container-narrow";
+       s += '.mkws-' + type;
+       s += ',.mkws-' + type + "-container-wide";
+       s += ',.mkws-' + type + "-container-narrow";
+        // Annoyingly, we also need to recognise old-style names
+        var oldtype = _new2old[type] || type.charAt(0).toUpperCase() + type.slice(1);
+       s += ',.mkws' + oldtype;
+       s += ',.mkws' + oldtype + "-Container-wide";
+       s += ',.mkws' + oldtype + "-Container-narrow";
       }
       return s;
     }
index bc54f3c..97156c0 100644 (file)
@@ -4,12 +4,12 @@
 
 //"use strict";
 // $(document).ready(function () {
-mkws.registerWidgetType('Popup', function() {
+mkws.registerWidgetType('popup', function() {
     var $ = mkws.$;
     var debug = mkws.log;
     debug("init popup window");
 
-    var popup_window = $(this.node); // mkws.registerWidgetType('Popup',....)
+    var popup_window = $(this.node);
     // var popup_window = $(".mkwsPopup"); // $(document).ready()
     if (!popup_window) {
         debug("no popup found, skip...");
index 0879add..2cc27c0 100644 (file)
@@ -340,10 +340,10 @@ mkws.makeTeam = function($, teamName) {
 
   // switching view between targets and records
   function switchView(view) {
-    var targets = widgetNode('Targets');
-    var results = widgetNode('Results') || widgetNode('Records');
-    var blanket = widgetNode('Blanket');
-    var motd    = widgetNode('MOTD');
+    var targets = widgetNode('targets');
+    var results = widgetNode('results') || widgetNode('records');
+    var blanket = widgetNode('blanket');
+    var motd    = widgetNode('motd');
 
     switch(view) {
     case 'targets':
index b1e0b1f..b96dad2 100644 (file)
@@ -1,4 +1,4 @@
-mkws.registerWidgetType('Authname', function() {
+mkws.registerWidgetType('auth-name', function() {
   var that = this;
 
   this.team.queue("authenticated").subscribe(function(authName) {
index 6468e86..aae9a81 100644 (file)
@@ -1,4 +1,4 @@
-mkws.registerWidgetType('Builder', function() {
+mkws.registerWidgetType('builder', function() {
   var that = this;
   var team = this.team;
 
@@ -8,9 +8,9 @@ mkws.registerWidgetType('Builder', function() {
   });
   this.node.append(button);
   button.click(function() {
-    var   query = team.widget('Query').value();
-    var    sort = team.widget('Sort').value();
-    var perpage = team.widget('Perpage').value();
+    var   query = team.widget('query').value();
+    var    sort = team.widget('sort').value();
+    var perpage = team.widget('per-page').value();
 
     var html = ('<div class="mkwsRecords" ' +
                 'autosearch="' + query + '" ' +
@@ -21,8 +21,8 @@ mkws.registerWidgetType('Builder', function() {
   });
 });
 
-mkws.registerWidgetType('ConsoleBuilder', function() {
-  mkws.promotionFunction('Builder').call(this);
+mkws.registerWidgetType('console-builder', function() {
+  mkws.promotionFunction('builder').call(this);
   this.callback = function(s) {
     console.log("generated widget: " + s);
   }
index 6982db8..90df81e 100644 (file)
@@ -1,4 +1,4 @@
-mkws.registerWidgetType('Categories', function() {
+mkws.registerWidgetType('categories', function() {
   var that = this;
 
   if (!mkws.authenticated) {
index 4ea6cd8..b520e35 100644 (file)
@@ -1,4 +1,4 @@
-mkws.registerWidgetType('Log', function() {
+mkws.registerWidgetType('log', function() {
   var that = this;
 
   this.team.queue("log").subscribe(function(teamName, timestamp, message) {
index e01675f..ef4b3c7 100644 (file)
@@ -5,7 +5,7 @@
 // source files.
 
 
-mkws.registerWidgetType('Targets', function() {
+mkws.registerWidgetType('targets', function() {
   if (!this.config.show_switch) return;
   var that = this;
 
@@ -33,7 +33,7 @@ mkws.registerWidgetType('Targets', function() {
 });
 
 
-mkws.registerWidgetType('Stat', function() {
+mkws.registerWidgetType('stat', function() {
   var that = this;
   this.team.queue("stat").subscribe(function(data) {
     var template = that.team.loadTemplate(that.config.template || "Stat");
@@ -42,7 +42,7 @@ mkws.registerWidgetType('Stat', function() {
 });
 
 
-mkws.registerWidgetType('Pager', function() {
+mkws.registerWidgetType('pager', function() {
   var that = this;
   var M = mkws.M;
 
@@ -88,7 +88,7 @@ mkws.registerWidgetType('Pager', function() {
   });
 });
 
-mkws.registerWidgetType('Details', function() {
+mkws.registerWidgetType('details', function() {
   var that = this;
   var recid = that.node.attr("data-mkws-recid");
   if (this.team.gotRecords()) { 
@@ -108,7 +108,7 @@ mkws.registerWidgetType('Details', function() {
   that.autosearch();
 });
 
-mkws.registerWidgetType('Records', function() {
+mkws.registerWidgetType('records', function() {
   var that = this;
   var team = this.team;
 
@@ -138,7 +138,7 @@ mkws.registerWidgetType('Records', function() {
 });
 
 
-mkws.registerWidgetType('Navi', function() {
+mkws.registerWidgetType('navi', function() {
   var that = this;
   var teamName = this.team.name();
 
@@ -171,7 +171,7 @@ mkws.registerWidgetType('Navi', function() {
 // It seems this and the Perpage widget doen't need to subscribe to
 // anything, since they produce events rather than consuming them.
 //
-mkws.registerWidgetType('Sort', function() {
+mkws.registerWidgetType('sort', function() {
   var that = this;
 
   this.node.change(function() {
@@ -184,7 +184,7 @@ mkws.registerWidgetType('Sort', function() {
 });
 
 
-mkws.registerWidgetType('Perpage', function() {
+mkws.registerWidgetType('per-page', function() {
   var that = this;
 
   this.node.change(function() {
@@ -197,7 +197,7 @@ mkws.registerWidgetType('Perpage', function() {
 });
 
 
-mkws.registerWidgetType('Done', function() {
+mkws.registerWidgetType('done', function() {
   var that = this;
   this.team.queue("complete").subscribe(function(n) {
     var template = that.team.loadTemplate(that.config.template || "Done");
@@ -206,7 +206,7 @@ mkws.registerWidgetType('Done', function() {
 });
 
 
-mkws.registerWidgetType('Switch', function() {
+mkws.registerWidgetType('switch', function() {
   if (!this.config.show_switch) return;
   var tname = this.team.name();
   var output = {};
@@ -218,7 +218,7 @@ mkws.registerWidgetType('Switch', function() {
 });
 
 
-mkws.registerWidgetType('Search', function() {
+mkws.registerWidgetType('search', function() {
   var output = {};
   output.team = this.team.name();
   output.queryWidth = this.config.query_width;
@@ -227,24 +227,24 @@ mkws.registerWidgetType('Search', function() {
 });
 
 
-mkws.registerWidgetType('SearchForm', function() {
+mkws.registerWidgetType('search-form', function() {
   var team = this.team;
   this.node.submit(function() {
-    var val = team.widget('Query').value();
+    var val = team.widget('query').value();
     team.newSearch(val);
     return false;
   });
 });
 
 
-mkws.registerWidgetType('Results', function() {
+mkws.registerWidgetType('results', function() {
   var template = this.team.loadTemplate(this.config.template || "Results");
   this.node.html(template({team: this.team.name()}));
   this.autosearch();
 });
 
 
-mkws.registerWidgetType('Ranking', function() {
+mkws.registerWidgetType('ranking', function() {
   var output = {};
   output.perPage = [];
   output.sort = [];
@@ -277,7 +277,7 @@ mkws.registerWidgetType('Ranking', function() {
 });
 
 
-mkws.registerWidgetType('Lang', function() {
+mkws.registerWidgetType('lang', function() {
   // dynamic URL or static page? /path/foo?query=test
   /* create locale language menu */
   if (!this.config.show_lang) return;
@@ -339,8 +339,8 @@ mkws.registerWidgetType('Lang', function() {
 });
 
 
-mkws.registerWidgetType('MOTD', function() {
-  var container = this.team.widget('MOTDContainer');
+mkws.registerWidgetType('motd', function() {
+  var container = this.team.widget('motd-container');
   if (container) {
     // Move the MOTD from the provided element down into the container
     this.node.appendTo(container.node);
@@ -352,7 +352,7 @@ mkws.registerWidgetType('MOTD', function() {
 // is copied up into its team, allowing it to affect other widgets in
 // the team.
 //
-mkws.registerWidgetType('Config', function() {
+mkws.registerWidgetType('config', function() {
   var c = this.config;
   for (var name in c) {
     if (c.hasOwnProperty(name)) {
@@ -363,7 +363,7 @@ mkws.registerWidgetType('Config', function() {
 });
 
 
-mkws.registerWidgetType('Progress', function() {
+mkws.registerWidgetType('progress', function() {
   var that = this;
   this.node.hide();
   this.team.queue("stat").subscribe(function(data) {
@@ -382,9 +382,9 @@ mkws.registerWidgetType('Progress', function() {
 // no actual functionality. We register these to prevent ignorable
 // warnings when they occur.
 
-mkws.registerWidgetType('Query', function() {});
-mkws.registerWidgetType('MOTDContainer', function() {});
-mkws.registerWidgetType('Button', function() {});
+mkws.registerWidgetType('query', function() {});
+mkws.registerWidgetType('motd-container', function() {});
+mkws.registerWidgetType('button', function() {});
 
 
 })(mkws.$); // jQuery wrapper
index 6623842..1d77e40 100644 (file)
@@ -1,5 +1,5 @@
 // A widget for one record
-mkws.registerWidgetType('Record', function() {
+mkws.registerWidgetType('record', function() {
   if (!this.config.maxrecs) this.config.maxrecs = 1;
   var that = this;
   var team = this.team;
@@ -11,22 +11,22 @@ mkws.registerWidgetType('Record', function() {
   that.autosearch();
 });
 
-mkws.registerWidgetType('Image', function() {
-  mkws.promotionFunction('Records').call(this);
+mkws.registerWidgetType('image', function() {
+  mkws.promotionFunction('records').call(this);
   if (!this.config.template) this.config.template = 'Image';
 });
 
-mkws.registerWidgetType('GoogleImage', function() {
-  mkws.promotionFunction('Image').call(this);
+mkws.registerWidgetType('google-image', function() {
+  mkws.promotionFunction('image').call(this);
   if (!this.config.target) this.config.target = 'Google_Images';
 });
 
-mkws.registerWidgetType('Lolcat', function() {
-  mkws.promotionFunction('GoogleImage').call(this);
+mkws.registerWidgetType('lolcat', function() {
+  mkws.promotionFunction('google-image').call(this);
   if (!this.config.autosearch) this.config.autosearch = 'kitteh';
 });
 
-mkws.registerWidgetType('Coverart', function() {
-  mkws.promotionFunction('Image').call(this);
+mkws.registerWidgetType('cover-art', function() {
+  mkws.promotionFunction('image').call(this);
   if (!this.config.target) this.config.target = 'AmazonBooks';
 });
index c8d41be..2993a60 100644 (file)
@@ -1,5 +1,5 @@
-mkws.registerWidgetType('Reference', function() {
-  mkws.promotionFunction('Record').call(this);
+mkws.registerWidgetType('reference', function() {
+  mkws.promotionFunction('record').call(this);
   if (!this.config.target) this.config.target = 'wikimedia_wikipedia_single_result';
   if (!this.config.template) this.config.template = 'Reference';
   this.config.template_vars.paragraphs = this.config.paragraphs || 0;
index 4052251..2e684f6 100644 (file)
@@ -1,4 +1,4 @@
-mkws.registerWidgetType('Termlists', function() {
+mkws.registerWidgetType('termlists', function() {
   // Initially hide the termlists; display when we get results
   var that = this;
   var team = this.team;
@@ -15,7 +15,7 @@ mkws.registerWidgetType('Termlists', function() {
 });
 
 
-mkws.registerWidgetType('Facet', function() {
+mkws.registerWidgetType('facet', function() {
   var facetConfig = {
     xtargets: [ "Sources",  16, false ],
     subject:  [ "Subjects", 10, true ],
index 621c9c1..cf697ed 100644 (file)
@@ -7,6 +7,7 @@ terms:
   term - term name
   count - count of items matching in the current search for this team
   linkdata - attributes to add to the term element including an onclick handler
+  field - for the xtargets facet ONLY, the opaque identifier of the target
 }}
 
 <div class="mkwsFacetTitle">{{caption}}</div>
index abee587..f74f174 100644 (file)
@@ -1,8 +1,11 @@
 {{!
 Records presented as images.
 
+The non-metadata keys enable an optional link to display an AJAX popup that
+fetches additional record detail.
+
 hits:
-  containerClass - class  attribute for same
+  containerClass - partial class attribute for element containing a record
   detailLinkId - id for the element triggering detail display
   detailClick - a click event handler for details
   renderedDetails - active record details rendered from the Record template
index 1b08a2c..cb78cae 100644 (file)
@@ -4,8 +4,8 @@ Progress
 done - number of targets complete
 waiting - number of targets waiting
 }}
-<span class="mkwsDone">{{#mkws-repeat done}}&#x2588;{{/mkws-repeat}}</span>
+<span class="mkws-done mkwsDone">{{#mkws-repeat done}}&#x2588;{{/mkws-repeat}}</span>
 {{~#if waiting~}}
-<span class="mkwsWaiting">{{#mkws-repeat waiting}}&#x2588;{{/mkws-repeat}}</span>
+<span class="mkws-waiting mkwsWaiting">{{#mkws-repeat waiting}}&#x2588;{{/mkws-repeat}}</span>
 {{~/if~}}
 
index 1c823bb..c016dc5 100644 (file)
@@ -2,8 +2,8 @@
 Ranking -- widget to select sort ordering and number of records to display
 
 team - team for this widget
-showSort
-showPerPage
+showSort - set if sort control is to be displayed
+showPerPage - set if per-page control is to be displayed
 sort
   key - machine readable value for this sort option
   label - text to display for this sort option
index f8bf951..9e8184e 100644 (file)
@@ -1,5 +1,7 @@
 {{!
 Full record display.
+
+Top level object is metadata from Service Proxy / Pazpar2
 }}
 <table>
   <tr>
index 03ba9a2..3e1b3a7 100644 (file)
@@ -1,8 +1,11 @@
 {{!
 Records from a search.
 
+The non-metadata keys enable an optional link to display an AJAX popup that
+fetches additional record detail.
+
 hits:
-  containerClass - class  attribute for same
+  containerClass - partial class attribute for element containing a record
   detailLinkId - id for the element triggering detail display
   detailClick - a click event handler for details
   renderedDetails - active record details rendered from the Record template
index 5530013..182b852 100644 (file)
@@ -4,8 +4,8 @@ Search form
 team - MKWS team
 queryWidth - configured width for search box
 }}
-<form name="mkwsSearchForm" class="mkwsSearchForm mkwsTeam_{{team}}" action="">
-  <input class="mkwsQuery mkwsTeam_{{team}}" type="text" size="{{queryWidth}}">
-  <input class="mkwsButton mkwsTeam_{{team}}" type="submit" value="{{{mkws-translate "Search"}}}">
+<form name="mkws-search-form" class="mkws-search-form mkws-team-{{team}}" action="">
+  <input class="mkws-query mkwsQuery mkws-team-{{team}}" type="text" size="{{queryWidth}}">
+  <input class="mkws-button mkwsButton mkws-team-{{team}}" type="submit" value="{{{mkws-translate "Search"}}}">
 </form>
 
index 99ed801..132f87f 100644 (file)
@@ -2,11 +2,11 @@
 Target detail
 
 data:
-  id - target id
-  hits - number of hits for this target
-  diagnostic - 
-  records - 
-  state - target state
+  id - target id, an opaque identifier
+  hits - number of hits for this target, or "Error" if an error has occurred
+  diagnostic - diagnostic code returned by target, if any. May be numeric or human-readable
+  records - number of record retrieved from target
+  state - target state (Client_Idle, Client_Working, Client_Disconnected or Client_Error)
 }}
 <table>
   <thead>
@@ -26,7 +26,7 @@ data:
       <td>{{hits}}</td>
       <td>{{diagnostic}}</td>
       <td>{{records}}</td>
-      <td>{{hits}}</td>
+      <td>{{state}}</td>
     </tr>
   {{/each}}
   </tbody>
index 221a4a4..227a35a 100644 (file)
@@ -7,12 +7,15 @@ This directory contains the MasterKey Widget Set (MKWS) Test framework.
 Installation
 -------------------------------------
 1. install node.js, see http://nodejs.org/
+(and apache2 if you have not already)
 
 # debian7
 $ sudo apt-get install npm
+$ sudo apt-get install apache2
 
 # centos6
 $ sudo yum install npm
+$ sudo yum install httpd
 
 
 The nodejs modules are configured in ./package.json
index cb5f2e7..db7bffa 100644 (file)
@@ -1,87 +1,87 @@
-.mkwsLang,
-.mkwsSwitch,
-.mkwsSearch,
-.mkwsTermlists,
-.mkwsFacet,
-.mkwsRanking,
-.mkwsPager,
-.mkwsNavi,
-.mkwsRecords,
-.mkwsRecord,
-.mkwsTargets,
-.mkwsStat,
-.mkwsMOTD {
+.mkwsLang, .mkws-lang,
+.mkwsSwitch, .mkws-switch,
+.mkwsSearch, .mkws-search,
+.mkwsTermlists, .mkws-termlists,
+.mkwsFacet, .mkws-facet,
+.mkwsRanking, .mkws-ranking,
+.mkwsPager, .mkws-pager,
+.mkwsNavi, .mkws-navi,
+.mkwsRecords, .mkws-records,
+.mkwsRecord, .mkws-record,
+.mkwsTargets, .mkws-targets,
+.mkwsStat, .mkws-stat,
+.mkwsMOTD, .mkws-motd {
     font-family: Gill Sans, "Gillius ADF", Gillius, GilliusADF, Verdana, Sans-Serif;
 }
 
-.mkwsLang {
+.mkwsLang, .mkws-lang {
     float: left;
     padding-left: 1em;
     padding-top: 0.4em;
 }
 
-.mkwsLang a {
+.mkwsLang a, .mkws-lang a {
     background: #d0e0ff;
     padding: 1px 4px;
 }
 
-.mkwsLang span {
+.mkwsLang span, .mkws-lang span {
     border: solid 1px #d0e0ff;
     padding: 0px 3px;
 }
 
-.mkwsSearch {
+.mkwsSearch, .mkws-search {
     float: right;
 }
 
-.mkwsSwitch {
+.mkwsSwitch, .mkws-switch {
     float: right;
     padding-left: 1em;
     padding-top: 0.4em;
 }
 
-.mkwsTargets {
+.mkwsTargets, .mkws-targets {
     background-color: #fafafa;
 }
 
-.mkwsStat {
+.mkwsStat, .mkws-stat {
     margin-top: 10px;
     border-top: 1px solid  #156a16;
     padding-top: 5px;
     font-size: small;
 }
 
-.mkwsStat:before {
+.mkwsStat:before, .mkws-stat:before {
     content: "Status info";
     font-weight: bold;
 }
 
-.mkwsSwitch a,
-.mkwsLang a,
-.mkwsFacet a,
-.mkwsRanking a,
-.mkwsPager a,
-.mkwsNavi a,
-.mkwsRecords a,
-.mkwsRecord a {
+.mkwsSwitch a, .mkws-switch a,
+.mkwsLang a, .mkws-lang a,
+.mkwsFacet a, .mkws-facet a,
+.mkwsRanking a, .mkws-ranking a,
+.mkwsPager a, .mkws-pager a,
+.mkwsNavi a, .mkws-navi a,
+.mkwsRecords a, .mkws-records a,
+.mkwsRecord a, .mkws-record a {
     color: #005701;
     text-decoration: none;
 }
 
-.mkwsSwitch a:hover,
-.mkwsLang a:hover,
-.mkwsFacet a:hover,
-.mkwsPager a:hover,
-.mkwsRecords a:hover,
-.mkwsRecord a:hover {
+.mkwsSwitch a:hover, .mkws-switch a:hover,
+.mkwsLang a:hover, .mkws-lang a:hover,
+.mkwsFacet a:hover, .mkws-facet a:hover,
+.mkwsPager a:hover, .mkws-pager a:hover,
+.mkwsRecords a:hover, .mkws-records a:hover,
+.mkwsRecord a:hover, .mkws-record a:hover {
     text-decoration: underline;
 }
 
-.mkwsNavi a.mkwsRemovable:hover {
+.mkwsNavi a.mkwsRemovable:hover, .mkws-navi a.mkws-removable:hover {
     text-decoration: line-through;
 }
 
-.mkwsSearch input.mkwsButton {
+.mkwsSearch input.mkwsButton, .mkws-search input.mkws-button {
     border: 3px outset #132194;
     background-color: #132194;
     padding: 2px;
     cursor: pointer;
 }
 
-.mkwsSearch input.mkwsQuery {
+.mkwsSearch input.mkwsQuery, .mkws-search input.mkws-query {
     border: 2px inset #e0f0ff;
     padding: 3px;
     font-size: 12px;
     background: #f0f8ff;
 }
 
-.mkwsTermlistsTitle {
+.mkwsTermlistsTitle, .mkws-termlists-title {
     font-size: large;
     font-weight: bold;
     text-transform: uppercase;
 }
 
-.mkwsTermlists {
+.mkwsTermlists, .mkws-termlists {
     background: #d0e0ff;
     padding: 0.7em;
     font-size: small;
     -webkit-border-top-right-radius: 10px;
 }
 
-.mkwsTermlists.active {
+.mkwsTermlists.active, .mkws-termlists.active {
     display: block;
 }
 
-.mkwsFacet {
+.mkwsFacet, .mkws-facet {
     background: #e0f0ff;
     padding: 0.7em;
     margin-top: 0.7em;
     -webkit-border-top-right-radius: 10px;
 }
 
-.mkwsTerm {
+.mkwsTerm, .mkws-term {
     clear: both;
 }
 
-.mkwsTerm span {
+.mkwsTerm span, .mkws-term span {
     float: right;
 }
 
-.mkwsFacetTitle {
+.mkwsFacetTitle, .mkws-facet-title {
     font-weight: bold;
 }
 
-.mkwsSummary {
+.mkwsSummary, .mkws-summary {
     padding: 5px;
 }
 
-.mkwsDetails {
+.mkwsDetails, .mkws-details {
     border: 1px solid #404040;
     background: #e8e8e8;
     color: black;
     -webkit-border-top-right-radius: 10px;
 }
 
-.mkwsDetails th {
+.mkwsDetails th, .mkws-details th {
     text-align: right;
     vertical-align: top;
     padding-right: 0.6em;
 }
 
-.mkwsDetails th:after {
+.mkwsDetails th:after, .mkws-details th:after {
     content: ":";
 }
 
-.mkwsPager {
+.mkwsPager, .mkws-pager {
     background: #e0e0e0;
     padding: 0.3em;
 }
 
-.mkwsTargets table thead tr td {
+.mkwsTargets table thead tr td, .mkws-targets table thead tr td {
     background-color: #132194;
     color: white;
     font-weight: bold;
     padding: 0.2em 0.5em;
 }
 
-.mkwsTargets table tbody tr:nth-child(odd) {
+.mkwsTargets table tbody tr:nth-child(odd), .mkws-targets table tbody tr:nth-child(odd) {
     background-color: #e0f0ff;
 }
 
-.mkwsTargets table tbody tr:nth-child(even) {
+.mkwsTargets table tbody tr:nth-child(even), .mkws-targets table tbody tr:nth-child(even) {
     background-color: #d0e0ff;
 }
 
-.mkwsTargets table tbody tr td {
+.mkwsTargets table tbody tr td, .mkws-targets table tbody tr td {
     padding: 0.2em 0.5em;
 }
 
-.mkwsCurrentPage {
+.mkwsCurrentPage, .mkws-current-page {
     padding: 0.1em 0.5em;
     background: #508751;
     color: white;
 }
 
-.mkwsProgress {
+.mkwsProgress, .mkws-progress {
     border: 1px solid #c0c0c0;
     float: left;
     margin-left: 2em;
     padding: 0 0.3em;
 }
 
-.mkwsProgress .mkwsDone { color: #005701 }
-.mkwsProgress .mkwsWaiting { color: #c0c0c0 }
+.mkwsProgress .mkwsDone, .mkws-progress .mkws-done { color: #005701 }
+.mkwsProgress .mkwsWaiting, .mkws-progress .mkws-waiting { color: #c0c0c0 }
 
-.mkwsResults table {
+.mkwsResults table, .mkws-results table {
   display: inline-table /* only for Firefox! */
 }