You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jspwiki.apache.org by br...@apache.org on 2018/07/01 14:20:34 UTC

[jspwiki] branch master updated: 2.10.5-git-05 : haddock update on INFO nav menu and localstorage cache

This is an automated email from the ASF dual-hosted git repository.

brushed pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/jspwiki.git


The following commit(s) were added to refs/heads/master by this push:
     new aacdfe2  2.10.5-git-05 : haddock update on INFO nav menu and localstorage cache
aacdfe2 is described below

commit aacdfe284c75649dd870ea82ce279971c6549842
Author: brushed <di...@gmail.com>
AuthorDate: Sun Jul 1 16:20:22 2018 +0200

    2.10.5-git-05 : haddock update on INFO nav menu and localstorage cache
---
 ChangeLog                                          | 19 ++++++
 .../src/main/java/org/apache/wiki/Release.java     |  2 +-
 .../main/java/org/apache/wiki/tags/LinkTag.java    |  7 +++
 .../java/org/apache/wiki/tags/RSSImageLinkTag.java | 20 +++----
 .../src/main/resources/META-INF/jspwiki.tld        |  4 ++
 .../main/resources/templates/default.properties    |  5 ++
 .../main/resources/templates/default_fr.properties |  5 ++
 .../main/resources/templates/default_nl.properties |  4 ++
 jspwiki-war/src/main/scripts/behaviors/Magnify.js  |  4 ++
 .../src/main/scripts/moo-extend/Array.Extend.js    |  6 +-
 .../src/main/scripts/moo-extend/Element.Extend.js  | 54 ++++++++++-------
 jspwiki-war/src/main/scripts/moo-extend/Tips.js    |  5 +-
 .../src/main/scripts/wiki-edit/Wiki.Edit.js        | 44 ++++++++++----
 jspwiki-war/src/main/scripts/wiki/Wiki.js          |  1 -
 .../src/main/styles/haddock/default/Columns.less   |  3 +
 .../src/main/styles/haddock/default/Magnify.less   |  2 +-
 .../main/styles/haddock/default/Template.Edit.less | 21 +++++++
 .../main/styles/haddock/default/Template.Nav.less  |  1 +
 .../src/main/styles/haddock/default/Tips.less      |  6 ++
 .../src/main/styles/haddock/default/modals.less    | 39 ++++++------
 .../haddock/default/responsive-viewport.less       | 66 +++++++++++++++++++-
 .../src/main/styles/haddock/default/type.less      |  4 +-
 .../src/main/styles/haddock/default/variables.less |  5 +-
 .../src/main/webapp/templates/haddock/Footer.jsp   |  2 +-
 .../src/main/webapp/templates/haddock/Nav.jsp      | 70 +++++++++++++++-------
 .../main/webapp/templates/haddock/SearchBox.jsp    | 27 +++++----
 .../src/main/webapp/templates/haddock/UserBox.jsp  |  9 +--
 .../main/webapp/templates/haddock/ViewTemplate.jsp |  2 +-
 28 files changed, 319 insertions(+), 118 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 159b520..def591a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,22 @@
+2018-07-01  Dirk Frederickx (brushed AT apache DOT org)
+
+       * 2.10.5-git-05 : few more haddock template updates
+
+       * The haddock editor has now a page restore functionality to recover unsaved page
+         edits.  When your session or login timer expires, or your accidentally close a
+         browser tab without saving, etc...  your last changes are now preserved in the
+         localstorage area of your browser.
+         At the start of a new edit sessions,  you will be presented with a modal dialog
+         to restore the cached page.
+
+       * The "attach" and the "info" menu are now combined into a single navigation menu.
+         The INFO or ATTACHMENT UPLOAD page can be accessed with an additional
+         click of a button. This also improves usability on touch devices.
+
+       * Small refinements of the Search and User buttons (top-right corner)
+         to improve support for touch devices. (issue reported by Juan Pablo)
+
+
 2018-06-17  Dirk Frederickx (brushed AT apache DOT org)
 
        * 2.10.5-git-04  Fine-tuning Haddock for mobile devices.
diff --git a/jspwiki-war/src/main/java/org/apache/wiki/Release.java b/jspwiki-war/src/main/java/org/apache/wiki/Release.java
index c250857..f5a1189 100644
--- a/jspwiki-war/src/main/java/org/apache/wiki/Release.java
+++ b/jspwiki-war/src/main/java/org/apache/wiki/Release.java
@@ -72,7 +72,7 @@ public final class Release {
      *  <p>
      *  If the build identifier is empty, it is not added.
      */
-    public static final String     BUILD         = "4";
+    public static final String     BUILD         = "5";
 
     /**
      *  This is the generic version string you should use when printing out the version.  It is of
diff --git a/jspwiki-war/src/main/java/org/apache/wiki/tags/LinkTag.java b/jspwiki-war/src/main/java/org/apache/wiki/tags/LinkTag.java
index a05cec2..be33434 100644
--- a/jspwiki-war/src/main/java/org/apache/wiki/tags/LinkTag.java
+++ b/jspwiki-war/src/main/java/org/apache/wiki/tags/LinkTag.java
@@ -65,6 +65,7 @@ public class LinkTag extends WikiLinkTag implements ParamHandler, BodyTag {
     private String m_ref     = null;
     private String m_context = WikiContext.VIEW;
     private String m_accesskey = null;
+    private String m_tabindex = null;
     private String m_templatefile = null;
 
     private boolean m_absolute = false;
@@ -129,6 +130,11 @@ public class LinkTag extends WikiLinkTag implements ParamHandler, BodyTag {
         m_target = target;
     }
 
+    public void setTabindex( String tabindex )
+    {
+        m_tabindex = tabindex;
+    }
+
     public void setCompareToVersion( String ver )
     {
         m_compareToVersion = ver;
@@ -431,6 +437,7 @@ public class LinkTag extends WikiLinkTag implements ParamHandler, BodyTag {
             sb.append( (m_title != null )  ? "title=\""+m_title+"\" " : "" );
             sb.append( (m_rel != null )    ? "rel=\""+m_rel+"\" " : "" );
             sb.append( (m_accesskey != null) ? "accesskey=\""+m_accesskey+"\" " : "" );
+            sb.append( (m_tabindex != null) ? "tabindex=\""+m_tabindex+"\" " : "" );
 
             switch( m_format )
             {
diff --git a/jspwiki-war/src/main/java/org/apache/wiki/tags/RSSImageLinkTag.java b/jspwiki-war/src/main/java/org/apache/wiki/tags/RSSImageLinkTag.java
index 3f17f51..06de420 100644
--- a/jspwiki-war/src/main/java/org/apache/wiki/tags/RSSImageLinkTag.java
+++ b/jspwiki-war/src/main/java/org/apache/wiki/tags/RSSImageLinkTag.java
@@ -1,4 +1,4 @@
-/* 
+/*
     Licensed to the Apache Software Foundation (ASF) under one
     or more contributor license agreements.  See the NOTICE file
     distributed with this work for additional information
@@ -14,7 +14,7 @@
     "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
     KIND, either express or implied.  See the License for the
     specific language governing permissions and limitations
-    under the License.  
+    under the License.
  */
 package org.apache.wiki.tags;
 
@@ -40,11 +40,11 @@ public class RSSImageLinkTag
     extends WikiTagBase
 {
     private static final long serialVersionUID = 0L;
-    
+
     protected String m_title;
     private   String m_mode;
     private   String m_pageName;
-    
+
     /**
      *  {@inheritDoc}
      */
@@ -59,7 +59,7 @@ public class RSSImageLinkTag
 
     /**
      *  Sets the title for the link.  If not defined, no title is shown.
-     *  
+     *
      *  @param title A string for the title.
      */
     public void setTitle( String title )
@@ -71,11 +71,11 @@ public class RSSImageLinkTag
     {
         m_mode = mode;
     }
-  
-    
+
+
     /**
      *  Returns the title.
-     *  
+     *
      *  @return The title.
      */
     public String getTitle()
@@ -108,7 +108,7 @@ public class RSSImageLinkTag
             else
             {
                 String page = m_pageName != null ? m_pageName : m_wikiContext.getPage().getName();
-            
+
                 String params = "page="+page+"&mode="+m_mode;
                 out.print( "<a href='"+m_wikiContext.getURL( WikiContext.NONE, "rss.jsp", params ));
                 out.print( "' class='feed'" );
@@ -116,7 +116,7 @@ public class RSSImageLinkTag
                 out.print( "&nbsp;</a> ");
             }
         }
-        
+
         return SKIP_BODY;
     }
 }
diff --git a/jspwiki-war/src/main/resources/META-INF/jspwiki.tld b/jspwiki-war/src/main/resources/META-INF/jspwiki.tld
index 7dec5d1..ab8378b 100644
--- a/jspwiki-war/src/main/resources/META-INF/jspwiki.tld
+++ b/jspwiki-war/src/main/resources/META-INF/jspwiki.tld
@@ -358,6 +358,10 @@
        <rtexprvalue>true</rtexprvalue>
     </attribute>
     <attribute>
+       <name>tabindex</name>
+       <rtexprvalue>true</rtexprvalue>
+    </attribute>
+    <attribute>
        <name>compareToVersion</name>
        <rtexprvalue>true</rtexprvalue>
     </attribute>
diff --git a/jspwiki-war/src/main/resources/templates/default.properties b/jspwiki-war/src/main/resources/templates/default.properties
index eb1cf88..3ee37ae 100644
--- a/jspwiki-war/src/main/resources/templates/default.properties
+++ b/jspwiki-war/src/main/resources/templates/default.properties
@@ -310,6 +310,8 @@ actions.index.title=Alphabetically sorted list of all pages
 actions.recentchanges=Recent Changes
 actions.recentchanges.title=Pages sorted by modification date
 
+actions.trail=Trail
+
 actions.more=More...
 actions.separator= - - - - - -
 actions.comment=Add Comment
@@ -530,6 +532,9 @@ editor.plain.preview.title=Preview [ v ]
 editor.plain.cancel.submit=Cancel
 editor.plain.cancel.title=Cancel editing. Your changes will be lost. [ q ]
 
+editor.plain.localstorage.restore=Restore this unsaved version!
+editor.plain.localstorage.delete=Delete
+
 editor.plain.changenote=Change Note
 editor.commentsignature=Comment signature
 editor.plain.toolbar=Toolbar
diff --git a/jspwiki-war/src/main/resources/templates/default_fr.properties b/jspwiki-war/src/main/resources/templates/default_fr.properties
index 8b360a2..f4203b2 100644
--- a/jspwiki-war/src/main/resources/templates/default_fr.properties
+++ b/jspwiki-war/src/main/resources/templates/default_fr.properties
@@ -342,6 +342,8 @@ actions.index.title=Liste de toutes les pages, tri\u00E9e par ordre alphab\u00E9
 actions.recentchanges=Modifications r\u00E9centes
 actions.recentchanges.title=Pages tri\u00E9es par date de modification
 
+actions.trail=Trace
+
 actions.more=Plus...
 actions.separator= - - - - - -
 actions.comment=Ajouter un commentaire
@@ -583,6 +585,9 @@ editor.plain.preview.title=Aper\u00E7u [ p ]
 editor.plain.cancel.submit=Abandonner
 editor.plain.cancel.title=Abandonner l\u0027\u00E9dition. Vos modifications seront perdues. [ q ]
 
+editor.plain.localstorage.restore=Restaurer cette version qui n'est pas encore enregistr\u00E9e!
+editor.plain.localstorage.delete=Supprimer
+
 editor.plain.changenote=Note de changement
 editor.commentsignature=Commenter la signature
 editor.plain.toolbar=Barre d\u0027outils
diff --git a/jspwiki-war/src/main/resources/templates/default_nl.properties b/jspwiki-war/src/main/resources/templates/default_nl.properties
index 7306de0..f14bbee 100644
--- a/jspwiki-war/src/main/resources/templates/default_nl.properties
+++ b/jspwiki-war/src/main/resources/templates/default_nl.properties
@@ -341,6 +341,7 @@ actions.confirmlogout = Bevestig dat u wilt uitloggen!
 actions.groups = Groepen
 actions.registernow = Registreer een nieuwe gebruiker!
 
+actions.trail=Broodkruimels
 
 actions.more=Meer...
 actions.separator= - - - - - -
@@ -575,6 +576,9 @@ editor.plain.preview.title=Preview [ v ]
 editor.plain.cancel.submit=Annuleer
 editor.plain.cancel.title=Annuleer. Uw wijzigingen worden niet bewaard. [ q ]
 
+editor.plain.localstorage.restore=Herstel deze vorige niet bewaarde versie!
+editor.plain.localstorage.delete=Verwijder
+
 editor.plain.changenote=Opmerking
 editor.commentsignature=Commentaar signatuur
 editor.plain.toolbar=Toolbar
diff --git a/jspwiki-war/src/main/scripts/behaviors/Magnify.js b/jspwiki-war/src/main/scripts/behaviors/Magnify.js
index a28984a..a4cc780 100644
--- a/jspwiki-war/src/main/scripts/behaviors/Magnify.js
+++ b/jspwiki-war/src/main/scripts/behaviors/Magnify.js
@@ -55,6 +55,9 @@ function Magnify( images ){
                 backgroundPosition: bgX + "px " + bgY + "px"
             });
 
+            /*avoid that the whole screen starts to scroll around when touch-down*/
+            if( /touch/.test(event.type) ){ event.preventDefault(); }
+
         }
 
         maggy.ifClass( isVisible , "show" );
@@ -62,6 +65,7 @@ function Magnify( images ){
     }
 
     $$( images ).addEvents({
+        mousedown: function(event){ event.stop(); },  //avoid dragging/selecting the img
         mousemove: move_maggy,
         touchmove: move_maggy,
         mouseleave: move_maggy,
diff --git a/jspwiki-war/src/main/scripts/moo-extend/Array.Extend.js b/jspwiki-war/src/main/scripts/moo-extend/Array.Extend.js
index 5c49818..c4cb8fc 100644
--- a/jspwiki-war/src/main/scripts/moo-extend/Array.Extend.js
+++ b/jspwiki-war/src/main/scripts/moo-extend/Array.Extend.js
@@ -44,7 +44,7 @@ Example
 >   new Element("div",{ attach:[this] });    //this.element now refers to div
 >   new Element("div",{ attach:[this,"myproperty"] }); //this.myproperty now refers to div
 
-Example rendAr()
+Example [...].slick()
 >   ["div",{attach:[this,"myproperty"] }].slick();
 >   ["ul", ["li[text=One]","li[text=Two]","li[text=Three]"]].slick();
 
@@ -68,8 +68,8 @@ Array.implement({
             if(item != null){
                 type = typeOf(item);
                 if ( type == "elements" ){ elements.append(item); }
-                else if ( item.grab /*isElement*/ ){ elements.push(item); }
-                else if ( item.big  /*isString*/ ){ elements.push(item.slick()); }
+                else if ( item instanceof Element ){ elements.push(item); }
+                else if ( ""+item === item /*isString*/ ){ elements.push(item.slick()); }
                 else if ( type == "object" ){ elements.getLast().set(item); }
                 else if ( item.pop /*isArray*/ ){ elements.getLast().adopt(item.slick()); }
             }
diff --git a/jspwiki-war/src/main/scripts/moo-extend/Element.Extend.js b/jspwiki-war/src/main/scripts/moo-extend/Element.Extend.js
index 0fb1d68..2d5595c 100644
--- a/jspwiki-war/src/main/scripts/moo-extend/Element.Extend.js
+++ b/jspwiki-war/src/main/scripts/moo-extend/Element.Extend.js
@@ -152,9 +152,9 @@ Element.implement({
                 document.removeEvent("touchend", toggleMenu);
 
             }
-
             event.preventDefault;
 
+
         };
 
         toggle = this.getParent( toggle );
@@ -256,6 +256,12 @@ Element.implement({
         behavior.add("[data-modal]", function(element){
             element.onModal( element.get("data-modal") );
         });
+
+
+       //immediate invocation
+        modal.openModal( function(){
+                //onSuccess
+        });
     (end)
 
     */
@@ -264,40 +270,47 @@ Element.implement({
         var self = this,
             modal = self.getElement(selector);
 
-        function doSelfEvent(event){
-
-            modal.addClass( "active" );
-            document.body.addClass( "show-modal" );
-            event.preventDefault(); //postpone the click event
+        function onClick(event){
+            event.preventDefault();
+            modal.openModal( function(){
+                //console.log(self);
+                self.removeEvent("click",onClick).click();
+            });
         }
 
-        function doModalEvent(){
+        if( modal ){ self.addEvent( "click" , onClick); }
 
-            modal.removeClass( "active" );
-            document.body.removeClass( "show-modal" );
+    },
+    openModal: function( callback ){
+
+        var modal = this,
+            init = "modal-initialized";
+
+        function clickModal(event){
+
+            modal.ifClass(!event, "active");
+            document.body.ifClass(!event, "show-modal");
+            if( event && this.match(".btn-success") ){ callback(); }
 
-            if( this.match(".btn-success") ){
-                self.removeEvent( "click" , doSelfEvent ).click();
-            }
         }
 
-        if( modal ){
+        if( !modal.hasClass(init) ){
 
-            //build a pretty modal dialog
-            if( !modal.getElement("> modal-footer") ){
+            if( !modal.getElement("> .modal-footer") ){
                 modal.grab([
                     "div.modal-footer", [
                         "button.btn.btn-success", { text: "Confirm" },  //FIXME: i18n
                         "button.btn.btn-danger", { text: "Cancel" }
-                    ]
-                ].slick());
+                        ]
+                    ].slick());
             }
             //move it just before the backdrop element for easy css styling
             modal.inject( document.getBackdrop(), "before" )
-                 .addEvent( "click:relay(.btn)",  doModalEvent );
-
-            self.addEvent( "click" , doSelfEvent );
+                 .addClass( init )
+                 .addEvent("click:relay(.btn)",  clickModal);
         }
+
+        clickModal(false); //and now show the modal
     },
 
     /*
@@ -335,7 +348,6 @@ Element.implement({
 
         "div.sticky-spacer".slick({styles: {height: element.offsetHeight} }).inject(element, "after");
 
-        //FFS: consider adding throttle to limit event invocation rate eg "scroll:throttle"
         document.addEvent("scroll", function(){
 
             on = ( window.scrollY >= origOffset );
diff --git a/jspwiki-war/src/main/scripts/moo-extend/Tips.js b/jspwiki-war/src/main/scripts/moo-extend/Tips.js
index a2bf598..8c9bc94 100644
--- a/jspwiki-war/src/main/scripts/moo-extend/Tips.js
+++ b/jspwiki-war/src/main/scripts/moo-extend/Tips.js
@@ -39,8 +39,9 @@ Bootstrap
 var Tips = function Tips(elements){
 
         var tt = 'div.tooltip',
-            TheTip = [tt,[tt+'-inner'/*,tt+'-arrow'*/]].slick().inject(document.body),
-            inner = TheTip.getFirst();
+            zTip = [tt,[tt+'-inner'/*,tt+'-arrow'*/]].slick().inject(document.body),
+            inner = zTip.firstChild,
+            isVisible;
 
         function tipEvent( e ){
 
diff --git a/jspwiki-war/src/main/scripts/wiki-edit/Wiki.Edit.js b/jspwiki-war/src/main/scripts/wiki-edit/Wiki.Edit.js
index f4ba211..40dacb7 100644
--- a/jspwiki-war/src/main/scripts/wiki-edit/Wiki.Edit.js
+++ b/jspwiki-war/src/main/scripts/wiki-edit/Wiki.Edit.js
@@ -31,7 +31,8 @@ Class: Wiki.Edit
 
 !(function( wiki ){
 
-var PreviewSemaphore;  //global semaphore to avoid double running the XHR preview
+var PreviewSemaphore,  //global semaphore to avoid double running the XHR preview
+    LocalCache; //name of the localstorage key
 
 wiki.add("textarea#editorarea", function( main ){
 
@@ -41,7 +42,6 @@ wiki.add("textarea#editorarea", function( main ){
 
     onbeforeunload( window, main );
 
-
     if( snipe = getFormElem("textarea.snipeable") ){
 
         snipe = new Snipe( snipe, {
@@ -66,8 +66,12 @@ wiki.add("textarea#editorarea", function( main ){
 
                 if( snipeHasChanged && !PreviewSemaphore ){
 
+                    var content = snipe.get('value').trim();
+
+                    localStorage.setItem(LocalCache, content);
+
                     snipeHasChanged = false;
-                    livepreview( snipe, preview, getFormElem("[data-cmd=livepreview]") );
+                    livepreview( content, preview, getFormElem("[data-cmd=livepreview]") );
 
                 }
 
@@ -83,6 +87,20 @@ wiki.add("textarea#editorarea", function( main ){
             parser: jspwikiSectionParser
         });
 
+
+        LocalCache = "wiki" + wiki.PageName;
+
+        if(LocalCache in localStorage){
+
+            var cache = localStorage.getItem(LocalCache),
+                modal = getFormElem(".localstorage");
+
+            modal.grab("pre".slick({text:cache}) )
+                .openModal( function(){
+                    snipe.set("value", cache);
+                });
+        }
+
     }
 
 });
@@ -109,6 +127,7 @@ function onbeforeunload( window, main ){
 
     main.form.addEvent("submit", function(){
 
+        localStorage.removeItem( LocalCache );
         window.onbeforeunload = null;
 
     });
@@ -122,26 +141,25 @@ Function: livepreview
     (wiki markup) to HTML.
 */
 
-function livepreview(snipe, preview, previewToggle){
+function livepreview(content, preview, previewToggle){
 
-    var content = snipe.get("value").trim(),
-        isEmpty = content == "",
+    var isEmpty = content == "",
+        loading = "loading",
         name, link;
 
 
-    function previewDone(){  PreviewSemaphore = false;  } //semaphore OFF!
+    function previewDone(){  PreviewSemaphore = false;  }
 
-    function renderPreview( completed ){
+    function renderPreview(done){
 
-        preview.ifClass(!completed, "loading");
-
-        if( completed ){
+        preview.ifClass(done,loading);
+        if(done){
             wiki.update();  //render the preview area
             previewDone();
         }
-
     }
 
+
     if( !previewToggle.checked ){
 
         //reset the preview area
@@ -187,7 +205,7 @@ function livepreview(snipe, preview, previewToggle){
             },
             update: preview,
             onRequest: renderPreview,
-            onComplete: renderPreview.pass(true),
+            onSuccess: renderPreview.pass(true),
             onError: previewDone
 
         }).send();
diff --git a/jspwiki-war/src/main/scripts/wiki/Wiki.js b/jspwiki-war/src/main/scripts/wiki/Wiki.js
index 291d068..f832b61 100644
--- a/jspwiki-war/src/main/scripts/wiki/Wiki.js
+++ b/jspwiki-war/src/main/scripts/wiki/Wiki.js
@@ -91,7 +91,6 @@ var Wiki = {
 
             //generate modal confirmation boxes, eg prompting to execute
             //an unrecoverable action such as deleting a page or attachment
-            //.add("[data-modal]", "onModal", {attr:"data-modal"})
             .add( "[data-modal]", function(element){
                 element.onModal( element.get("data-modal") );
             })
diff --git a/jspwiki-war/src/main/styles/haddock/default/Columns.less b/jspwiki-war/src/main/styles/haddock/default/Columns.less
index d4f5a92..a2179ba 100644
--- a/jspwiki-war/src/main/styles/haddock/default/Columns.less
+++ b/jspwiki-war/src/main/styles/haddock/default/Columns.less
@@ -61,6 +61,9 @@ DOM structure:
         margin:  -@padding-base-vertical  -@padding-base-horizontal ;
         min-height: 100%;
     }
+    .col > pre:only-child {
+    	margin:-@padding-base-vertical 0;
+    }
 
     &.border > .col:not(:last-child){ border-right:1px solid @btn-default-border; }
     &.border + &.border { border-top:none; }
diff --git a/jspwiki-war/src/main/styles/haddock/default/Magnify.less b/jspwiki-war/src/main/styles/haddock/default/Magnify.less
index d117a69..acc82d5 100644
--- a/jspwiki-war/src/main/styles/haddock/default/Magnify.less
+++ b/jspwiki-war/src/main/styles/haddock/default/Magnify.less
@@ -41,6 +41,6 @@ DOM Structure:
 
 }
 
-.magnify img { cursor:move;}
+.magnify img { cursor:move; -webkit-user-select: none; user-select: none; }
 
 //.magnifier.show { display:block; }  covered by bootstrap's generic .show
diff --git a/jspwiki-war/src/main/styles/haddock/default/Template.Edit.less b/jspwiki-war/src/main/styles/haddock/default/Template.Edit.less
index dff931c..282bfe0 100644
--- a/jspwiki-war/src/main/styles/haddock/default/Template.Edit.less
+++ b/jspwiki-war/src/main/styles/haddock/default/Template.Edit.less
@@ -238,3 +238,24 @@ General styles to support wysiwyg editors
     }
 
 }
+
+/*
+modal dialog
+*/
+.localstorage {
+
+	display:flex;
+	flex-direction:column;
+
+	.modal-footer {
+    	margin:0 0 @modal-inner-padding 0;
+    }
+	pre {
+		display:flex;
+		flex:1;
+		margin:0;
+		font-size:90%;
+		overflow:scroll;
+		white-space: pre-wrap;
+	}
+}
\ No newline at end of file
diff --git a/jspwiki-war/src/main/styles/haddock/default/Template.Nav.less b/jspwiki-war/src/main/styles/haddock/default/Template.Nav.less
index bc793ed..ab6fe41 100644
--- a/jspwiki-war/src/main/styles/haddock/default/Template.Nav.less
+++ b/jspwiki-war/src/main/styles/haddock/default/Template.Nav.less
@@ -84,6 +84,7 @@ div.row
 		background:rgba(255,255,255,.5);
 		color:@gray;
     }
+    .nav .btn-xs .badge { background-color: @badge-bg; }  /*reset to bootstrap default for small btns also */
 
     .nav > li > a.slimbox-link:after { color:white; font-size:70%; top:-.7em; }
 
diff --git a/jspwiki-war/src/main/styles/haddock/default/Tips.less b/jspwiki-war/src/main/styles/haddock/default/Tips.less
index e67a048..35884d2 100644
--- a/jspwiki-war/src/main/styles/haddock/default/Tips.less
+++ b/jspwiki-war/src/main/styles/haddock/default/Tips.less
@@ -45,6 +45,12 @@ Bootstrap
 (end)
 */
 
+
+.dropdown-menu[data-hover-parent] {
+	.transition(all .5s ease);
+}
+
+
 .tip-link {
     border-bottom: .1em dotted;
     > [class^=tip] { .hidden; }
diff --git a/jspwiki-war/src/main/styles/haddock/default/modals.less b/jspwiki-war/src/main/styles/haddock/default/modals.less
index 11ca62f..8bde01b 100755
--- a/jspwiki-war/src/main/styles/haddock/default/modals.less
+++ b/jspwiki-war/src/main/styles/haddock/default/modals.less
@@ -36,44 +36,44 @@ body[.show-modal]
 */
 
 .modal {
-  position: fixed;
-  top: 50%; left: 50%;
-  width: 20em; margin: -5em -10em;
+  //position: fixed;
+  position: absolute;
+  max-width: unit(@wiki-modal-max-width, vw);
+  max-height: unit(@wiki-modal-max-height,vh);
+  top: unit( (100 - @wiki-modal-max-height)/2,vh);
+  left: 50%; margin-right:-50%;
+  transform: translate(-50%);
 
   padding: @modal-inner-padding;
-  .lead; //get some bigger font
 
   background-color: @modal-content-bg;
   border: 1px solid @modal-content-border-color;
   border-radius: @border-radius-large;
-  .box-shadow(0 5px 15px rgba(0,0,0,.5));
-  // Remove focus outline from opened modal
-  outline: none;
-
-  .transition(all .6s);
-  .opacity(0);
-  z-index: -1;
-  pointer-events:0;
+  .box-shadow(0 0 20vh rgba(0,0,0,.5));
+  outline: none; // Remove focus outline from opened modal
 }
 
 
-// Modal background DOM element, inserted as last element of the DOM
+// Modal background DOM element, inserted as last element of the body
 .backdrop {
-    position: fixed;top: 0;left: 0;right: 0;bottom: 0;
+    position: fixed;
+    top: 0;left: 0;right: 0;bottom: 0;
     background-color: @modal-backdrop-bg;
+    pointer-events:none;
+}
 
-    .transition(all .6s);
+.modal, .backdrop {
+    z-index: -1; //hidden by default
     .opacity(0);
-    z-index: -1;
+    .transition(all .6s);
 }
 
 .show-modal {
 
     .backdrop {
         .opacity(0.3);
-        z-index: (@zindex-modal-background - 10); //bring above main content, but below the dialog
+        z-index: (@zindex-modal-background - 1); //bring above main content, but below the modal dialog
     }
-
     .modal.active {
         .opacity(1);
         z-index: @zindex-modal-background;
@@ -83,7 +83,7 @@ body[.show-modal]
 
 // Footer (for actions)
 .modal-footer {
-    margin-top: 15px;
+    margin-top: @modal-inner-padding;
     text-align: center; // right align buttons
 
     // Properly space out buttons
@@ -93,7 +93,6 @@ body[.show-modal]
     }
 }
 
-
 // Scale up the modal
 @media screen and (min-width: @screen-sm-min) {
 
diff --git a/jspwiki-war/src/main/styles/haddock/default/responsive-viewport.less b/jspwiki-war/src/main/styles/haddock/default/responsive-viewport.less
index c3ff99b..9e5ff32 100644
--- a/jspwiki-war/src/main/styles/haddock/default/responsive-viewport.less
+++ b/jspwiki-war/src/main/styles/haddock/default/responsive-viewport.less
@@ -83,6 +83,71 @@ Medium size screens,  tablets,  phones in landscape mode
 	// type.less
 	// grid.less
 	// tables.less
+	//	Use .table-responsive as wrapper around large wide tables
+	//  Modified from bootstrap/tables.less
+	.table-responsive {
+		overflow-x: auto;
+		min-height: 0.01%; // Workaround for IE9 bug (see https://github.com/twbs/bootstrap/issues/14837)
+
+	    width: 100%;
+	    margin-bottom: (@line-height-computed * 0.75);
+    	overflow-y: hidden;
+    	-ms-overflow-style: -ms-autohiding-scrollbar;
+    	border: 0; //overrule default bootstrap :  1px solid @table-border-color;
+
+	    // Tighten up spacing
+	    table, .wikitable {
+    		margin-bottom: 0;
+
+    		// Ensure the content doesn't wrap
+		    > thead,
+    		> tbody,
+    		> tfoot {
+        		> tr {
+        			> th,
+        			> td {
+            			white-space: nowrap;
+        			}
+        		}
+    		}
+    	}
+
+    	// Special overrides for the bordered tables
+    	.table-bordered {
+    		border: 0;
+
+    		// Nuke the appropriate borders so that the parent can handle them
+    		> thead,
+    		> tbody,
+    		> tfoot {
+        		> tr {
+        			> th:first-child,
+        			> td:first-child {
+            			border-left: 0;
+        			}
+	        		> th:last-child,
+    	    		> td:last-child {
+            			border-right: 0;
+        			}
+        		}
+    		}
+
+    		// Only nuke the last row's bottom-border in `tbody` and `tfoot` since
+    		// chances are there will be only one `tr` in a `thead` and that would
+    		// remove the border altogether.
+    		> tbody,
+    		> tfoot {
+        		> tr:last-child {
+        			> th,
+        			> td {
+            			border-bottom: 0;
+        			}
+        		}
+    		}
+    	}
+	}
+
+
 	// TableX.Sort.less
 	// TableX.Filter.less
 	// forms.less
@@ -256,7 +321,6 @@ Medium size screens,  tablets,  phones in landscape mode
 	input#changenote { max-width: @wiki-small-viewport-dialog-width; }
 
 
-	.modal,
 	.slmbx,
 	.dialog.find {
 		max-width:@wiki-small-viewport-dialog-width;
diff --git a/jspwiki-war/src/main/styles/haddock/default/type.less b/jspwiki-war/src/main/styles/haddock/default/type.less
index f644935..7995dfd 100644
--- a/jspwiki-war/src/main/styles/haddock/default/type.less
+++ b/jspwiki-war/src/main/styles/haddock/default/type.less
@@ -512,13 +512,11 @@ a.interwiki[href^="rss.jsp"],
 .feed {
 	&:after {
        .icon--all;
-        margin-left:.15em;
-        .sup;
         content:@icon-rss;
 	}
     &:hover { text-decoration:none; }
-
 }
+.dropdown-menu > li > a.feed { padding-left:0; }
 
 /*
 Footnotes
diff --git a/jspwiki-war/src/main/styles/haddock/default/variables.less b/jspwiki-war/src/main/styles/haddock/default/variables.less
index 14f4783..19e6b61 100644
--- a/jspwiki-war/src/main/styles/haddock/default/variables.less
+++ b/jspwiki-war/src/main/styles/haddock/default/variables.less
@@ -97,12 +97,15 @@ images/feather-small.png   wxh  162x286
 
 //blurb layout :        1 | (1*phi*phi)
 //three section layout: 1 | (1*phi*phi) | 1
-@wiki-sidebar-width: percentage( 1 / (1 + @golden-square + 1) );  //21.6447%
+@sidebar-ratio: 1 / (1 + @golden-square + 1); //21.6447
+@wiki-sidebar-width: percentage( @sidebar-ratio );  //21.6447%
 
 //wider layout :  1 | (1*phi)   => commentbox
 @wiki-commentbox-ratio: percentage( 1 / (1 + @golden-square) ); //27.6373%
 @wiki-commentbox-width: @wiki-commentbox-ratio * 100% / (100% - @wiki-sidebar-width);
 @wiki-commentbox-width-inverse: (100% - @wiki-commentbox-width);
+@wiki-modal-max-width: 100 * (1-@sidebar-ratio);
+@wiki-modal-max-height: 90;
 
 //Nav bar
 @wiki-logo-font-family: 'HelveticaNeue-UltraLight', 'Helvetica Neue UltraLight', 'Helvetica Neue', Arial, Helvetica, sans-serif;
diff --git a/jspwiki-war/src/main/webapp/templates/haddock/Footer.jsp b/jspwiki-war/src/main/webapp/templates/haddock/Footer.jsp
index 2179fca..7c05154 100644
--- a/jspwiki-war/src/main/webapp/templates/haddock/Footer.jsp
+++ b/jspwiki-war/src/main/webapp/templates/haddock/Footer.jsp
@@ -28,7 +28,7 @@
   <wiki:InsertPage page="CopyrightNotice"/>
 
   <div class="wiki-version"><%=Release.APPNAME%> v<%=Release.getVersionString()%>
-    <wiki:RSSImageLink title="Aggregate the RSS feed" />
+    <wiki:RSSImageLink />
   </div>
 
 </div>
\ No newline at end of file
diff --git a/jspwiki-war/src/main/webapp/templates/haddock/Nav.jsp b/jspwiki-war/src/main/webapp/templates/haddock/Nav.jsp
index 2d44757..917e640 100644
--- a/jspwiki-war/src/main/webapp/templates/haddock/Nav.jsp
+++ b/jspwiki-war/src/main/webapp/templates/haddock/Nav.jsp
@@ -32,33 +32,36 @@
 <c:set var="attachments" value="<%= c.getEngine().getAttachmentManager().listAttachments( c.getPage() ).size() %>" />
 
 <%-- navigation bar --%>
-<div class="navigation">
+<div class="navigation" role="navigation">
 
 <ul class="nav nav-pills pull-left">
   <%-- toggle sidebar --%>
   <li id="menu"><a href="#"><!--&#x2261;-->&#9776;</a></li>
 
+  <c:set var="refresh_breadCrumbTrail_attr"><wiki:Breadcrumbs /></c:set>
+  <%-- don't show the breadcrumbs if it has none or only one item --%>
+  <c:if test="${fn:length(breadCrumbTrail) gt 2}">
   <li id="trail" tabindex="0">
     <a href="#">
         <span>&hellip;</span>
-        <span>&hellip;</span>
+        <span><fmt:message key="actions.trail"/></span>
         <span class="caret"></span>
     </a>
     <ul class="dropdown-menu" data-hover-parent="li">
       <li class="dropdown-header"><fmt:message key="header.yourtrail"/></li>
       <li class="divider"></li>
 
-      <%--  FIXME: breadcrumbs tag returns items in wrong order: 1st item is at back of the list !!
+      <%--  FIXME: breadcrumbs tag returns items in wrong order: most recent item is at back of the list !!
       <li><wiki:Breadcrumbs separator="</li><li>" /></li>
       --%>
-      <c:set var="refresh_breadCrumbTrail_attr"><wiki:Breadcrumbs /></c:set>
       <c:forEach items="${breadCrumbTrail}" varStatus="status" begin="2">
           <c:set var="crumb" value="${breadCrumbTrail[fn:length(breadCrumbTrail) - status.index]}" />
-          <li><wiki:Link page="${crumb}" >${crumb}</wiki:Link></li>
+          <li><wiki:Link page="${crumb}">${crumb}</wiki:Link></li>
       </c:forEach>
 
     </ul>
   </li>
+  </c:if>
 
 </ul>
 
@@ -91,10 +94,10 @@
   </li>
   </wiki:CheckRequestContext>
 
-  <%-- attachment --%>
+  <%-- attachment   : included in the info menu
   <wiki:CheckRequestContext context='view|info|rename|diff|rename|edit|comment|conflict'>
   <wiki:PageExists>
-  <c:if test="${param.tab ne 'attach'}"><%-- context upload -> context view&tab=attach ... --%>
+  <c:if test="${param.tab ne 'attach'}"><!-- context upload -> context view&tab=attach ... -- >
   <li id="attach"
    class="<wiki:Permission permission='!upload'>disabled</wiki:Permission>">
     <wiki:Link page="${page}" context="upload" accessKey="a" >
@@ -106,36 +109,59 @@
   </c:if>
   </wiki:PageExists>
   </wiki:CheckRequestContext>
+  --%>
 
   <%-- info --%>
   <wiki:CheckRequestContext context='view|info|upload|rename|edit|comment|conflict'>
   <wiki:PageExists>
   <li id="info" tabindex="0">
-    <wiki:Link context="info" accessKey="i">
-      <span class="icon-info-menu"></span>
-      <span><fmt:message key='info.tab'/></span>
-      <wiki:PageExists><span class="caret"></span></wiki:PageExists>
-    </wiki:Link>
+      <a href="#" accessKey="i">
+        <span class="icon-info-menu"></span>
+        <span><fmt:message key='info.tab'/></span>
+        <c:if test="${attachments > 0}"><span class="badge">${attachments}</span></c:if>
+        <wiki:PageExists><span class="caret"></span></wiki:PageExists>
+      </a>
     <ul class="dropdown-menu pull-right" data-hover-parent="li">
       <li class="dropdown-header"><fmt:message key="info.version"/> : <span class="badge"><wiki:PageVersion /></span></li>
-      <li class="dropdown-header"><fmt:message key="info.date"/> : </li>
-      <wiki:CheckVersion mode="latest">
-        <li><wiki:DiffLink version="latest" newVersion="previous"><wiki:PageDate format='${prefs["DateFormat"]}'/></wiki:DiffLink></li>
-      </wiki:CheckVersion>
-      <wiki:CheckVersion mode="notlatest">
-        <li><wiki:DiffLink version="current" newVersion="latest"><wiki:PageDate format='${prefs["DateFormat"]}'/></wiki:DiffLink></li>
-      </wiki:CheckVersion>
-      <li class="dropdown-header"><fmt:message key="info.author"/> : </li>
-      <li>
+      <li class="dropdown-header"><fmt:message key="info.date"/> :
+        <span>
+        <wiki:CheckVersion mode="latest">
+          <wiki:DiffLink version="latest" newVersion="previous"><wiki:PageDate format='${prefs["DateFormat"]}'/></wiki:DiffLink>
+        </wiki:CheckVersion>
+        <wiki:CheckVersion mode="notlatest">
+          <wiki:DiffLink version="current" newVersion="latest"><wiki:PageDate format='${prefs["DateFormat"]}'/></wiki:DiffLink>
+        </wiki:CheckVersion>
+        </span>
+      </li>
+      <li class="dropdown-header"><fmt:message key="info.author"/> :
+        <span>
         <%-- wiki:Author sometimes returns a link(ok) or a plain text, we always need a link! --%>
         <c:set var="author"><wiki:Author/></c:set>
         <c:choose>
           <c:when test="${ fn:contains(author,'href=')}">${author}</c:when>
           <c:otherwise><a href="#">${author}</a></c:otherwise>
         </c:choose>
+        </span>
+      </li>
+      <li class="dropdown-header">
+        <wiki:RSSImageLink mode="wiki" title="<fmt:message key='info.feed'/>"/>
       </li>
       <li class="divider"></li>
-      <li><wiki:RSSImageLink mode="wiki" /></li>
+      <li class="dropdown-header">
+        <c:set var="disabledBtn" value=""/>
+        <wiki:CheckRequestContext context='info'><c:set var="disabledBtn" value="disabled" /></wiki:CheckRequestContext>
+          <wiki:Link cssClass="btn btn-xs btn-default ${disabledBtn}" context="info" tabindex="0"><fmt:message key='info.moreinfo'/></wiki:Link>
+      </li>
+      <li class="dropdown-header">
+        <c:set var="disabledBtn" value=""/>
+        <wiki:CheckRequestContext context='upload'><c:set var="disabledBtn" value="disabled" /></wiki:CheckRequestContext>
+        <wiki:Permission permission='!upload'><c:set var="disabledBtn" value="disabled" /></wiki:Permission>
+        <wiki:Link cssClass="btn btn-xs btn-default ${disabledBtn}" page="${page}" context="upload" tabindex="0">
+          <span class="icon-paper-clip"></span>
+          <fmt:message key='edit.tab.attachments'/>
+          <c:if test="${attachments > 0}"><span class="badge">${attachments}</span></c:if>
+        </wiki:Link>
+      </li>
     </ul>
   </li>
   </wiki:PageExists>
diff --git a/jspwiki-war/src/main/webapp/templates/haddock/SearchBox.jsp b/jspwiki-war/src/main/webapp/templates/haddock/SearchBox.jsp
index bc032af..647fdb6 100644
--- a/jspwiki-war/src/main/webapp/templates/haddock/SearchBox.jsp
+++ b/jspwiki-war/src/main/webapp/templates/haddock/SearchBox.jsp
@@ -25,30 +25,31 @@
 <%-- Powered by wiki/Findpages.js and wiki/Recents.js  --%>
 <form action="<wiki:Link jsp='Search.jsp' format='url'/>"
   class="form-inline searchbox pull-right"
-  id="searchForm" tabindex="0"
+  id="searchForm" tabindex="0" role="search"
   accept-charset="<wiki:ContentEncoding />">
 
-  <%-- the onclick="" is needed for hover effect on ipad https://www.codehaven.co.uk/fix-css-hover-on-iphone-ipad/ --%>
-  <div onclick="" class="btn"><span class="icon-search"></span><span class="caret"></span></div>
-
+  <%-- FFS <div onclick="" class="btn">
+    the onclick="" is needed for hover effect on ipad https://www.codehaven.co.uk/fix-css-hover-on-iphone-ipad/ --%>
+  <a href="#" class="btn">
+    <span class="icon-search"></span><span class="caret"></span>
+  </a>
   <ul class="dropdown-menu" data-hover-parent=".searchbox">
     <li class="dropdown-header">
-  <input type="text" size="20"
-        class="form-control" name="query" id="query"
-    placeholder="<fmt:message key='sbox.search.submit'/>" />
+      <input type="text" size="20" class="form-control" name="query" id="query"
+             placeholder="<fmt:message key='sbox.search.submit'/>" />
     </li>
     <li class="dropdown-header">
-    <button type="submit"
-           class="btn btn-primary btn-block" name="searchSubmit" id="searchSubmit"
-  	       value="<fmt:message key='find.submit.go'/>"> <fmt:message key='sbox.search.fullsearch'/>
-    </button>
+      <button type="submit"
+              class="btn btn-primary btn-block" name="searchSubmit" id="searchSubmit"
+  	          value="<fmt:message key='find.submit.go'/>"> <fmt:message key='sbox.search.fullsearch'/>
+      </button>
     </li>
-    <%-- see wiki/Findpages.js
+    <%-- generated by wiki/Findpages.js
         <li class="findpages"> ... </li>
     --%>
     <li class="divider"></li>
     <li class="dropdown-header"><fmt:message key="sbox.recentsearches"/></li>
-    <%-- see wiki/Recents.js
+    <%-- generated by wiki/Recents.js
         <li class="recents"><a>Recent-1</a></li>
         <li class="recents"><a>Recent-2</a></li>
         <li class="recents clear"><a>[Clear recent searches]</a></li>
diff --git a/jspwiki-war/src/main/webapp/templates/haddock/UserBox.jsp b/jspwiki-war/src/main/webapp/templates/haddock/UserBox.jsp
index 62c253d..4780078 100644
--- a/jspwiki-war/src/main/webapp/templates/haddock/UserBox.jsp
+++ b/jspwiki-war/src/main/webapp/templates/haddock/UserBox.jsp
@@ -33,11 +33,12 @@
 
 <div class="cage pull-right userbox user-${loginstatus}" tabindex="0">
 
-  <%-- the onclick="" is needed for hover effect on ipad https://www.codehaven.co.uk/fix-css-hover-on-iphone-ipad/ --%>
-  <div onclick="" class="btn"><span class="icon-user"></span><span class="caret"></span></div>
-
+  <%-- <div onclick="" class="btn">
+      FFS the onclick="" is needed for hover effect on ipad https://www.codehaven.co.uk/fix-css-hover-on-iphone-ipad/ --%>
+  <a href="#" class="btn">
+    <span class="icon-user"></span><span class="caret"></span>
+  </a>
   <ul class="dropdown-menu pull-right" data-hover-parent=".userbox">
-
     <li>
       <wiki:UserCheck status="anonymous">
         <wiki:LinkTo page="UserPreferences">
diff --git a/jspwiki-war/src/main/webapp/templates/haddock/ViewTemplate.jsp b/jspwiki-war/src/main/webapp/templates/haddock/ViewTemplate.jsp
index 1a1864e..c926146 100644
--- a/jspwiki-war/src/main/webapp/templates/haddock/ViewTemplate.jsp
+++ b/jspwiki-war/src/main/webapp/templates/haddock/ViewTemplate.jsp
@@ -59,7 +59,7 @@
 
   <div class="content ${sidebarState}" data-toggle="li#menu,.sidebar>.close"
                                        data-toggle-pref="${sidebarCookie}" >
-    <div class="page">
+    <div class="page" role="content">
       <wiki:Content/>
       <wiki:Include page="PageInfo.jsp"/>
     </div>