jspwiki-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From brus...@apache.org
Subject svn commit: r1732806 [2/3] - in /jspwiki/trunk: ./ jspwiki-war/src/main/config/wro/ jspwiki-war/src/main/java/org/apache/wiki/ jspwiki-war/src/main/scripts/behaviors/ jspwiki-war/src/main/scripts/dialog/ jspwiki-war/src/main/scripts/lib/ jspwiki-war/sr...
Date Sun, 28 Feb 2016 21:53:38 GMT
Modified: jspwiki/trunk/jspwiki-war/src/main/scripts/wiki-edit/Snipe.Snips.js
URL: http://svn.apache.org/viewvc/jspwiki/trunk/jspwiki-war/src/main/scripts/wiki-edit/Snipe.Snips.js?rev=1732806&r1=1732805&r2=1732806&view=diff
==============================================================================
--- jspwiki/trunk/jspwiki-war/src/main/scripts/wiki-edit/Snipe.Snips.js (original)
+++ jspwiki/trunk/jspwiki-war/src/main/scripts/wiki-edit/Snipe.Snips.js Sun Feb 28 21:53:37 2016
@@ -15,6 +15,8 @@
     specific language governing permissions and limitations
     under the License.
 */
+/*eslint-env browser*/
+/*global typeOf, Class, Events, Snipe  */
 /*
 Snippet:
     init - initialize snippets; detect shortcut-keys, and suggestion dialogs
@@ -44,17 +46,12 @@ Snipe.Snips = new Class({
 
         var self = this,
             cmd, snip, key, suggest,
-            //shortcut = ((navigator.userAgent.indexOf("Mac OS X")!=-1) ? "meta+" : "control+");
-            //control = (Browser.platform == "mac" ? "meta+" : "control+");
             control = ( navigator.platform.match( /mac/i ) ? "meta+" : "control+");
 
-
-
         self.workarea = workarea;  //Textarea class
-        self.snips = snips;
-
         self.keys = {};
         self.dialogs = {};
+        self.snips = snips; //{};
         self.suggestions = {};
 
         for( cmd in snips ){
@@ -62,22 +59,21 @@ Snipe.Snips = new Class({
             snip = Function.from( snips[cmd] )( workarea, cmd );
 
             // short format of snip
-            if( typeOf(snip)=="string" ){ snip = { snippet:snip }; }
+            if( typeOf(snip) == "string" ){ snip = { snippet:snip }; }
 
-            //Not needed sofar: Function.from( snip.initialize )(cmd, snip);
+            //shortcut keys
+            if( (key = snip.key) ){
 
-            if( key = snip.key ){
-
-                // key:"f" => key:"control+f" ;  key:"shift+enter" (no change)
-                if( !key.contains("+") ){ key = control + key; }
+                // key: "f" => "control+f" ;  key: "shift+enter" (no change)
+                if( !key.contains( "+" ) ){ key = control + key; }
                 self.keys[ key.toLowerCase() ] = cmd;
-                snip.key = key;
 
             }
 
-            if( suggest = snip.suggest ){
+            if( (suggest = snip.suggest) ){
 
-                if( typeOf(suggest)== "string" ){
+                //this is a suggest snippets
+                if( typeOf(suggest) == "string" ){
 
                     snip.suggest = {
                         pfx: RegExp( suggest + "$" ),
@@ -85,18 +81,22 @@ Snipe.Snips = new Class({
                     }
                     //console.log( snip.suggest );
                 }
+
                 self.suggestions[cmd] = snip;
 
+            } else {
+
+                //otherwise regular snippet
+
             }
 
             //check for snip dialogs -- they have the same name as the command
-            //EG:  find: { find:<this is a snip dialog> }
             if( snip[cmd] ){ self.dialogs[cmd] = snip[cmd]; }
 
             snips[cmd] = snip;
 
         }
-        //console.log(this.keys);
+        //console.log(this.keys, this.suggest, this.snip);
 
     },
 
@@ -109,10 +109,13 @@ Snipe.Snips = new Class({
         var cmd, fromStart = this.workarea.getFromStart();
 
         for( cmd in this.snips ){
-            if( fromStart.test( cmd + "$" ) ) return cmd;
+
+            if( fromStart.test( cmd + "$" ) ){ return cmd; }
+
         }
 
         return false;
+
     },
 
     /*
@@ -120,31 +123,32 @@ Snipe.Snips = new Class({
         Lookup a cmd enter just in front of the caret/cursor of the workarea..
 
         snip.suggest => {
-            start: <pos>,
-            match: <match-string-before-caret>,
-            tail:  <length-match-after-caret>
+            start: (number) start position,
+            match: (string) matched string (selected?)
+            cmd:  (string) command
         }
     */
     matchSuggest: function(){
 
-        var cmd, snip, pfx, result, suggest,
-            snips = this.suggestions,
+        var cmd, snip, pfx, match, result, suggest,
+            suggestions = this.suggestions,
             workarea = this.workarea,
             caret = workarea.getSelectionRange(),
             fromStart = workarea.getFromStart();
 
         //"selectInline", "selectBlock", "selectStartOfLine";
 
-        var SOL = workarea.isCaretAtStartOfLine();
-        var EOL = workarea.isCaretAtEndOfLine();
+        //var SOL = workarea.isCaretAtStartOfLine();
+        //var EOL = workarea.isCaretAtEndOfLine();
 
-        for( cmd in snips ){
+        for( cmd in suggestions ){
 
-            snip = snips[cmd];
-            suggest = snip.suggest;
+            snip = suggestions[cmd];
 
             if( this.inScope(snip, fromStart) ){
 
+                suggest = snip.suggest;
+
                 if( suggest.pfx ){
 
                     pfx = fromStart.match( suggest.pfx );
@@ -153,13 +157,16 @@ Snipe.Snips = new Class({
 
                         console.log("SUGGEST Prefix ", cmd, suggest.pfx, pfx.getLast() );
                         pfx = pfx.getLast(); //match last (x)
-                        result = workarea.slice( caret.start - pfx.length )
+
+                        match = workarea.slice( caret.start - pfx.length )
                                          .match( suggest.match );
 
-                        console.log("SUGGEST Match ", suggest.match, result );
+                        console.log("SUGGEST Match ", suggest.match, match );
+
+                        if( match ){
+
+                            result = { pfx: pfx, match: match.getLast() } ;
 
-                        if( result ){
-                            result = { pfx:pfx, match:result.getLast() } ;
                         }
 
                     }
@@ -188,77 +195,17 @@ Snipe.Snips = new Class({
         Returns false when the snippet is not found or not in scope.
 
     Arguments:
-        snips - snippet collection object for lookup of the cmd
-        cmd - snippet key. If not present, retrieve the cmd from
-            the textarea just to the left of the caret. (i.e. tab-completion)
-
-    Example:
-        (start code)
-        sn.get( "bold" );
-
-        returned_object = false || {
-                key: "snippet-key",
-                snippet: " snippet-string ",
-                text: " converted snippet-string, no-parameter braces, auto-indented ",
-                parms: [parm1, parm2, "last-snippet-string" ]
-            }
-        (end)
+        cmd - snippet key
     */
     get: function( cmd ){
 
         var self = this,
-            txta = self.workarea,
-            fromStart = txta.getFromStart(),
-            snip = self.snips[cmd],
-            parms = [],
-            s,last;
-
-        if( snip && snip.synonym ){ snip = self.snips[snip.synonym]; }
-
-        if( !snip || !self.inScope(snip, fromStart) ){ return false; }
-
-        s = snip.snippet || "";
-
-        //parse snippet {parameters}
-        s = s.replace( /\\?\{([^{}]+)\}/g, function(match, name){
+            snip = self.snips[cmd];
 
-            if( match.charAt(0) == "{" ){
-                parms.push(name);
-                return name;
-            } else {
-                return match.slice(1)
-            }
-
-        }).replace( /\\\{/g, "{" );
-        //and end by replacing all escaped "\{" by real "{" chars
-
-        //also push the last piece of the snippet onto the parms[] array
-        last = parms.getLast();
-        if( last ){ parms.push( s.slice(s.lastIndexOf(last) + last.length) ); }
-
-        //collapse \n of previous line if the snippet starts with \n
-        if( s.test(/^\n/) && ( fromStart.test( /(^|[\n\r]\s*)$/ ) ) ) {
-            s = s.slice(1);
-            //console.log("remove leading \\n");
-        }
-
-        //collapse \n of subsequent line when the snippet ends with a \n
-        if( s.test(/\n$/) && ( txta.getTillEnd().test( /^\s*[\n\r]/ ) ) ) {
-            s = s.slice(0,-1);
-            //console.log("remove trailing \\n");
-        }
+        if( snip && snip.alias ){ snip = self.snips[snip.alias]; }
 
-        //finally auto-indent the snippet"s internal newlines \n
-        var prevline = fromStart.split(/\r?\n/).pop(),
-            indent = prevline.match(/^\s+/);
-        if( indent ){ s = s.replace( /\n/g, "\n" + indent[0] ); }
-
-        //complete the snip object
-        snip.text = s;
-        snip.parms = parms;
+        return ( snip && self.inScope( snip, self.workarea.getFromStart() ) ) ? snip : false;
 
-        //console.log("Snipe.Snips:get() ",snip.text, JSON.encode(snip),"***" );
-        return snip;
     },
 
     /*
@@ -295,101 +242,37 @@ Snipe.Snips = new Class({
     */
     inScope: function(snip, text){
 
-        var pattern, pos, scope=snip.scope, nscope=snip.nscope;
-
-        if( scope ){
-
-            if( typeOf(scope)=="function" ){
-
-                return scope( this.textarea );
-
-            } else {
+        var pattern, pos,
+            scope = snip.scope,
+            nscope = snip.nscope;
 
-                for( pattern in scope ){
+        function parse(patterns, inscope){
 
-                    pos = text.lastIndexOf(pattern);
-                    if( (pos > -1) && (text.indexOf( scope[pattern], pos ) == -1) ){
+            for( pattern in patterns ){
 
-                        return true;
-
-                    }
+                pos = text.lastIndexOf( pattern );
+                if( (pos > -1) && (text.indexOf( patterns[pattern], pos ) == -1) ){
+                        return inscope;
 
                 }
-                return false;
             }
+            return !inscope;
         }
 
-        if( nscope ){
-
-            for( pattern in nscope ){
 
-                pos = text.lastIndexOf(pattern);
-                if( (pos > -1) && (text.indexOf( nscope[pattern], pos ) == -1) ){
-
-                    return false;
-
-                }
+        if( scope ){
 
-            }
+            return typeOf(scope)=="function" ? scope( this.textarea ) : parse(scope, true);
 
         }
-        return 1 /*true*/;
-    },
 
+        if( nscope ){
 
-    /*
-    Function: toggle
-        Toggle the prefix and suffix of a snippet.
-        Eg. toggle between {{__text__}} and {{text}}.
-        The selection will be matched against the snippet.
-
-    Precondition:
-        - the selection is not empty (caret.thin = false)
-        - the snippet has exatly one {parameter}
-
-    Arguments:
-        txta - Textarea object
-        snip - Snippet object
-        caret - Caret object {start, end, thin}
-
-    Returns:
-        - (string) replacement string for the selection.
-            By default, returns snip.text
-        - the snip.parms will be set to [] is toggle was executed successfully
-        Eventually the selection will be extended if the
-        prefix and suffix were just outside the selection.
-    */
-    toggle: function(txta, snip, caret){
-
-        var s = snip.text,
-            //get the first and last textual parts of the snippet
-            arr = s.trim().split( snip.parms[0] ),
-            fst = arr[0],
-            lst = arr[1],
-            re = new RegExp( "^\\s*" + fst.trim().escapeRegExp() + "\\s*(.*)\\s*" + lst.trim().escapeRegExp() + "\\s*$" );
-
-        if( (fst + lst)!="" ){
-
-            s = txta.getSelection();
-            snip.parms = [];
-
-            // if pfx & sfx (with optional whitespace) are matched: remove them
-            if( s.test(re) ){
-
-                s = s.replace( re, "$1" );
-
-            // if pfx/sfx are matched just outside the selection: extend selection
-            } else if( txta.getFromStart().test(fst.escapeRegExp()+"$") && txta.getTillEnd().test("^"+lst.escapeRegExp()) ){
-
-                txta.setSelectionRange(caret.start-fst.length, caret.end+lst.length);
-
-            // otherwise, insert snippet and set caret between pfx and sfx
-            } else {
+            return parse(nscope /*,false*/);
 
-                txta.setSelection( fst+lst ).setSelectionRange( caret.start + fst.length );
-            }
         }
 
-        return s;
+        return true;
     }
+
 });
\ No newline at end of file

Modified: jspwiki/trunk/jspwiki-war/src/main/scripts/wiki-edit/Snipe.js
URL: http://svn.apache.org/viewvc/jspwiki/trunk/jspwiki-war/src/main/scripts/wiki-edit/Snipe.js?rev=1732806&r1=1732805&r2=1732806&view=diff
==============================================================================
--- jspwiki/trunk/jspwiki-war/src/main/scripts/wiki-edit/Snipe.js (original)
+++ jspwiki/trunk/jspwiki-war/src/main/scripts/wiki-edit/Snipe.js Sun Feb 28 21:53:37 2016
@@ -18,6 +18,10 @@
     specific language governing permissions and limitations
     under the License.
 */
+/*eslint-env browser*/
+/*global $, Class, Options, Events, Undoable, Textarea, Dialog  */
+/*eslint-disable no-console */
+
 /*
 Class: Snipe
     The Snipe class decorates a TEXTAREA object with extra capabilities such as
@@ -58,9 +62,6 @@ Options:
         dialogs suchs as Font, Color and Special.
         See property [initializeDialogs] and [openDialog]
     findForm - (object) list of form-controls. See [onFindAndReplace] handler.
-    next - (Element), when pressing Shift-Enter, the textarea will ""blur"" and
-        this ""next"" element will ge the focus.
-        This compensates the overwritting default TAB handling of the browser.
     onresize - (function, optional), when present, a textarea resize bar
         with css class {{resize-bar}} is added after the textarea,
         allowing to resize the heigth of the textarea.
@@ -69,17 +70,16 @@ Options:
 
 Dependencies:
     [Textarea]
-    [UndoRedo]
+    [Undoable]
+    [Snipe.Snips]
     [Snipe.Commands]
 
 Example:
 (start code)
     new Snipe( "mainTextarea", {
-        snippets: { bold:"**{bold text}**", italic:"""{italic text}""" },
-        tabcompletion:true,
-        directsnips: { "(":")", "[" : "]" },
-        buttons: $$("a.tool"),
-        next:"nextInputField"
+        tabcompletion: true,
+        snippets: { bold:"**{bold text}**", italic:"\"\"{italic text}\"\"" },
+        directsnips: { "(":")", "[" : "]" }
     });
 (end)
 
@@ -112,9 +112,9 @@ var Snipe = new Class({
 
             /*
             The textarea is cloned into a main and work textarea.
-            The work texarea is visible and used for the actual editing.
+            The work texarea remains visible and is used for the actual editing.
             It contains either the full document or a particular section.
-            The main textarea is hidden and is kept always up to date.
+            The main textarea is hidden and contains always the complete document.
             On submit, the mainarea is send back to the server.
             */
             main = self.mainarea = $(el),
@@ -125,8 +125,6 @@ var Snipe = new Class({
             // Make sure the content of the mainarea is always in sync with the workarea
             textarea = self.textarea = new Textarea( work );
 
-        //console.log("**** JUST CREATED THE SNIPE WORK EDITAEREA!  Huray!! ****");
-
         self.directsnips = new Snipe.Snips( textarea, options.directsnips );
         self.snippets    = new Snipe.Snips( textarea, options.snippets );
 
@@ -136,18 +134,18 @@ var Snipe = new Class({
                 get: function(){
                     var selection = textarea.getSelection();
                     return (selection=="") ? work.value : selection;
+                    //return (selection=="") ? textarea.getValue() : selection;
                 },
                 set: function(v){
                     var s = textarea.getSelectionRange();
-                    self.fireEvent("beforeChange");
+                    //self.fireEvent("beforeChange");
+                    //textarea[ s.thin ? "setValue" : "setSelection" ](v);
                     s.thin ? work.value = v : textarea.setSelection(v);
-                    //self.fireEvent("change");
+                    self.fireEvent("change");
                 }
             }
         }];
 
-        //console.log("snip dialogs",JSON.encode(Object.keys(self.snippets.dialogs)));
-
         //Snipe.Commands takes care of capturing commands.
         //Commands are entered via tab-completion, button clicks, or a dialog.
         //Snipe.Commands ensures that at most one dialog is open at the same time.
@@ -155,7 +153,6 @@ var Snipe = new Class({
             //onOpen: function( /*command*/ ){ work.focus(); },
             onClose: function( /*command*/ ){ work.focus(); },
             onAction: self.action,
-
             dialogs: self.snippets.dialogs,
             relativeTo: textarea
         });
@@ -163,20 +160,20 @@ var Snipe = new Class({
 
         self.reset();
 
-        //Activate snipe trigger events on the work textarea
         work.addEvents({
 
             keydown: self.keystroke,
             keypress: self.keystroke,
 
             //fixme: any click outside the suggestion block should clear the context -- blur ?
-            //blur: self.reset.bind(self), //(and hide any open dialogs; and update the preview area...)
+            //blur: self.reset.bind(self),
             keyup: self.suggest.debounce(), //(250, true)
             click: self.suggest.debounce(),
-            change: function( parm ){
-                //console.log("change :", parm);
-                self.fireEvent("change",parm);
-            }
+
+            input: (function( ){
+                console.log("***Snipe: dom textarea input :");
+                self.fireEvent("change");
+            }).debounce()
 
         });
 
@@ -260,7 +257,7 @@ var Snipe = new Class({
 
             if ( keycmd ){
 
-                console.log("Snipe shortcut",key,keycmd,e.code);
+                //console.log("Snipe shortcut",key,keycmd,e.code);
                 e.stop();
                 this.commands.action( keycmd );
 
@@ -290,14 +287,14 @@ var Snipe = new Class({
     */
     keystroke: function(e){
 
-        //console.log(e.key, e.code + " keystroke "+e.shift+" "+e.type+"+meta="+e.meta+" +ctrl="+e.control );
+        //console.log(e.type, e.key, e.code, "shift:"+e.shift,"meta:"+e.meta,"ctrl:"+e.control );
 
-        if( e.type=="keydown" ){
+        if( e.type == "keydown" ){
 
             //Exit if this is a normal key; process special chars with the keydown event
-            if( e.key.length==1 ) return;
+            if( e.key.length == 1 ){ return; }
 
-        } else { // e.type=="keypress"
+        } else { // e.type == "keypress"
 
             //CHECKME
             //Only process regular character keys via keypress event
@@ -313,11 +310,11 @@ var Snipe = new Class({
 
         var self = this,
             txta = self.textarea,
-            el = txta.toElement(),
+            //el = txta.toElement(),
             key = e.key,
             caret = txta.getSelectionRange();
 
-        el.focus();
+        txta.toElement().focus();
 
         if( /up|down|esc/.test(key) ){
 
@@ -346,7 +343,7 @@ var Snipe = new Class({
         txta - Textarea object
         caret - caret object, indicating the start/end of the textarea selection
     */
-    enter: function(e, txta, caret) {
+    enter: function(e, txta /*, caret*/ ) {
 
         this.reset();
 
@@ -354,7 +351,7 @@ var Snipe = new Class({
         //prevline[1]=sequence of spaces (indentation string)
         //prevline[2]=non-blank tail of the prevline
 
-        if( !e.shift && prevline && (prevline[2]!="") ){
+        if( !e.shift && prevline && ( prevline[2] != "" ) ){
 
             e.stop();
             //console.log("enter key - autoindent", prevline);
@@ -379,7 +376,6 @@ var Snipe = new Class({
 
             var key = txta.getValue().charAt(caret.start-1),
                 snip = this.directsnips.get( key );
-                //snip = this.getSnippet( this.options.directsnips, key );
 
             if( snip && (snip.snippet == txta.getValue().charAt(caret.start)) ){
 
@@ -440,7 +436,7 @@ var Snipe = new Class({
 
                 //remove the command
                 txta.setSelectionRange(caret.start - cmd.length, caret.start)
-                    .setSelection("");
+                    .setSelection( "" );
 
                 return self.commands.action( cmd );
             }
@@ -467,7 +463,7 @@ var Snipe = new Class({
 
         var tab = this.options.tab,
             selection = txta.getSelection(),
-            fromStart = txta.getFromStart();
+            fromStart = txta.getFromStart(),
             isCaretAtStart = txta.isCaretAtStartOfLine();
 
         //handle multi-line selection
@@ -542,10 +538,10 @@ var Snipe = new Class({
     */
     reset: function(){
 
-        //console.log("Snipe:reset");
+        //console.log("Snipe:reset", this.context);
         this.context = {};
-        this.commands.close();
         this.toElement().removeClass("activeSnip").focus();
+        this.commands.close();
 
     },
 
@@ -597,8 +593,8 @@ var Snipe = new Class({
 
             //insert the keystroke, retain the selection and insert the snippet outcome
             //and keep the original selection (caret)
-            workarea.setSelection( key, workarea.getSelection(), snip.text )
-                    .setSelectionRange( caret.start+1, caret.end+1 );
+            workarea.setSelection( key, workarea.getSelection(), snip.snippet )
+                    .setSelectionRange( caret.start + 1, caret.end + 1 );
 
         }
 
@@ -611,48 +607,30 @@ var Snipe = new Class({
         When clicking items in the suggest dialogs, content is inserted
         in the textarea.
 
-        snip.suggest => {
-            cmd:  <cmd>,
-            start: <pos>,
-            value: <match-string-before-caret>,
-            xxxtail:  <length-match-after-caret>
-        }
-
     */
-    suggest: function(e){
+    suggest: function( /*event*/ ){
 
-        var self = this, suggest;
+        var suggest;
 
         if( this.options.autosuggest ){
 
-            if ( suggest = this.snippets.matchSuggest() ){
+            if ( (suggest = this.snippets.matchSuggest()) ){
 
-                //console.log( "Snipe.suggest ",suggest );
+                console.log( "Snipe.suggest ",suggest );
                 this.setContext( null/*snip*/, suggest );
                 return this.commands.action( suggest.cmd , suggest.pfx );
 
             }
-            //close suggest dialog if one is still open
-            //CHECKME: this.commands.close();
-            this.reset();
-        }
-
-        self.fireEvent("change");
-        //CHECKME: Potential change of the textarea, to be debounced by receiver -- CHECKME
-        //FIXME: FIRE-EVENT to be done when a snippet is inserted
 
+            this.commands.close();
+        }
     },
 
 
     /*
     Function: action
         This function executes the command action.
-        The trigger of a command can be
-        - "keydown/keypress" TAB key , via snipe.commands to close any dialogs...
-        - "keydown" with CTRL/META key, via snipe.command to close any dialogs...
-        - "click" event on a button , captured by snipe.commands
-        - "keyup"/"click" on the workarea -- suggestion snip
-
+        It will insert the snippet and update the selection and caret.
 
         It looks up and processes the snippet.
         - insert the snippet text at the caret in the textarea.
@@ -669,218 +647,147 @@ var Snipe = new Class({
     action: function( cmd ){
 
         var self = this,
-            args = Array.slice(arguments,1),
-            snip, // = self.context.snip || self.getSnippet(self.options.snippets, cmd),
+            args = Array.slice(arguments, 1),
+            snip = self.snippets.get( cmd ),
+            //snippet = snip.snippet,
+            s = snip.snippet,
+            suggest = snip.suggest && self.context.suggest,
+
             txta = self.textarea,
             caret = txta.getSelectionRange(),
-            s, p;
+            hasCaret = !caret.thin,
+            caretStart = caret.start,
 
-        //console.log("Snipe:action() "+cmd+" ["+args+"]");
+            pfx, sel, sfx, snipArr, selectionLength,
+            /* match "pfx{selection}sfx" into ["pfx","selection","sfx"] */
+            /* do not match "pfx~{do-not-match}sfx"  */
+            snipSelection = /(^|[\S\s]*[^~])\{([^\{\}]+)\}([\S\s]*)/,
+            snipEscapeChar = /~\{/g;
 
-        if( snip = self.snippets.get(cmd) ){
+        function setCaret(start,end){ txta.setSelectionRange(start, end); }
+        function removeEscapeChar(s){ return s.replace(snipEscapeChar, "{"); }
 
-            if( snip.event ){
-                //console.log("Snipe:action() fire-event: ",snip.event);
-                return self.fireEvent(snip.event, arguments);
-            }
+        console.log("Snipe:action ", snip, s, cmd, args,suggest );
 
-            this.fireEvent("beforeChange");
+        if( snip ){
 
-            if( snip.suggest ){
+            if( snip.event ){
 
-                return self.suggestAction( cmd, args );
-                //todo -- bring that here inline ...
-                //snip.text = ...
+                //console.log("Snipe:action() fire-event: ",snip.event);
+                return self.fireEvent(snip.event, arguments);
 
             }
 
-            s = snip.text;
-
-            if( !caret.thin && (snip.parms.length==2) ){
+            this.fireEvent("beforeChange"); //CHECKME
 
-                s = self.toggleSnip(txta, snip, caret);
-                //console.log("toggle snippet: "+s+" parms:"+snip.parms);
+            //adjust caret based on suggestion context
+            if( suggest ){
 
-            }
+                s = args.join();  //result of the suggest dialog
+                selectionLength = suggest.match.length;
 
-            //inject args into the snippet parms
-            while( args && args[0] ){
+                if( s.startsWith(suggest.pfx) ){
 
-                if( snip.parms[0] ){
-                    s = s.replace( snip.parms.shift(), args.shift() );
-                }
+                    s = s.slice(suggest.pfx.length);
+                    selectionLength -= suggest.pfx.length;
 
-            }
+                } else {
 
-            //replace the first parm by the selected text
-            if( snip.parms[1] ){
+                    caretStart -= suggest.pfx.length;
 
-                if( !caret.thin ){
-                    p = snip.parms.shift();
-                    s = s.replace( p, txta.getSelection() );
                 }
 
+                //move the caret according to suggest pfx and match
+                setCaret( caretStart, caretStart +  selectionLength );
+                hasCaret = selectionLength > 0;
             }
 
-            txta.setSelection( s );
-
-            //when no selection, move caret after the inserted snippet,
-            //otherwise leave the selection unchanged
-
-            if( caret.thin ){
-
-                    console.log("move after", s.length, caret.start + s.length);
-                    txta.setSelectionRange( caret.start + s.length );
-
-            }
-
-            self.reset(); //CHECKME
-
-        }
-
-    },
-
-    /*
-    Function: toggleSnip
-        Toggle the prefix and suffix of a snippet.
-        Eg. toggle between {{__text__}} and {{text}}.
-        The selection will be matched against the snippet.
-
-    Precondition:
-        - the selection is not empty (caret.thin = false)
-        - the snippet has exatly one {parameter}
-
-    Arguments:
-        txta - Textarea object
-        snip - Snippet object
-        caret - Object {start, end, thin}
+            if( (snipArr = s.match( snipSelection )) ){
 
-    Returns:
-        - (string) replacement string for the selection. By default, returns snip.text
-        - the snip.parms will be set to [] is toggle was executed successfully
+                pfx = removeEscapeChar( snipArr[1] );
+                sel = hasCaret ?  txta.getSelection() : snipArr[2] ;
+                sfx = removeEscapeChar( snipArr[3] );
 
-        The selection will be extended if the prefix and suffix were just outside the selection.
-    */
-    toggleSnip: function(txta, snip, caret){
+                console.log("found a 'pfx{selection}sfx' snippet", snipArr, pfx, sel, sfx,hasCaret );
 
-        var s = snip.text,
-            //get the first and last textual parts of the snippet
-            arr = s.trim().split( snip.parms[0] ),
-            fst = arr[0],
-            lst = arr[1],
-            re = new RegExp( "^\\s*"
-                           + fst.trim().escapeRegExp()
-                           + "\\s*(.*)\\s*"
-                           + lst.trim().escapeRegExp()
-                           + "\\s*$" );
+                if( hasCaret ) {
 
-        if( (fst + lst) != "" ){
+                    if( sel.startsWith(pfx) && sel.endsWith(sfx) ){
 
-            s = txta.getSelection();
-            snip.parms = [];
+                        console.log("TOGGLE: pfx/sfx matched inside the selection",caret.start,caret.end);
+                        sel = sel.slice( pfx.length, -sfx.length );
+                        pfx = sfx = "";
 
-            // if pfx & sfx (with optional whitespace) are matched: remove them
-            if( s.test(re) ){
+                    } else if( txta.getFromStart().endsWith(pfx)
+                            && txta.getTillEnd().startsWith(sfx) ){
 
-                s = s.replace( re, "$1" );
+                        console.log("TOGGLE: pfx/sfx matched outside the selection",caret.start,caret.end);
+                        caretStart -= pfx.length;
+                        setCaret( caretStart, caret.end + sfx.length); //enlarge the selection
+                        pfx = sfx = "";
 
-            // if pfx/sfx are matched just outside the selection: extend selection
-            } else if( txta.getFromStart().test(fst.escapeRegExp() + "$")
-                    && txta.getTillEnd().test("^" + lst.escapeRegExp() ) ){
+                    }
+                }
 
-                txta.setSelectionRange( caret.start - fst.length, caret.end + lst.length);
+                s = pfx + sel + sfx;
+                caretStart += pfx.length;
+                selectionLength = sel.length;
 
-            // otherwise, insert snippet and set caret between pfx and sfx
             } else {
 
-                txta.setSelection( fst + lst ).setSelectionRange( caret.start + fst.length );
-            }
-        }
-        return s;
-
-    },
-
-    /*
-    Method: suggestAction
-        <todo>
-        suggest = { pfx: "prefix-string" , match:"full-string" }
-    */
-    suggestAction: function( cmd, valueArr ){
-
-console.log(this.context.suggest);
-        var suggest = this.context.suggest,
-            workarea = this.textarea,
-            start = workarea.getSelectionRange().start - suggest.pfx.length;
+                console.log("plain text snippet", hasCaret,s );
+                s = removeEscapeChar( s );
+                caretStart += hasCaret ? 0 : s.length;
+                selectionLength = hasCaret ? s.length : 0;
 
-        //jump to the matched string
-        start = workarea.indexOf( suggest.match, start );
+            }
 
-        if( start >= 0 ){
+            self.inject(s, caretStart, selectionLength);
+            self.reset();
 
-            workarea.setSelectionRange( start, start + suggest.match.length )
-                    .setSelection( valueArr )
-                    .setSelectionRange( workarea.getSelectionRange().end );
+            self.fireEvent("change");
+            //allow to finish the actions, before opening a new suggestion dialog
+            self.suggest.delay(10, self);
 
         }
-        return this.suggest();
 
     },
 
-    /*
-    CHECKME : remove..
-    Function: nextAction
-        Process the next ""{parameter}"" of the active snippet as you tab along
-        or after you clicked a button or closed a dialog.
-
-    Arguments:
-        txta - Textarea object
-        caret - caret object, indicating the start/end of the textarea selection
-    */
-    nextAction: function(txta, caret){
+    inject: function( snippet, start, selectionLength ){
 
         var self = this,
-            snip = self.context.snip,
-            parms = snip.parms,
-            dialog,
-            pos;
-
-        while( parms[0] ){
-
-            dialog = parms.shift();
-            pos = txta.getValue().indexOf(dialog, caret.start);
-
-            //console.log("next action: "+dialog+ " pos:" + pos + " parms: "+parms+" caret:"+caret.start);
-
-            //found the next {dialog} or possibly the end of the snippet
-            if( (dialog !="") && (pos > -1) ){
-
-                if( parms[0] ){
-
-                    // select the next {dialog}
-                    txta.setSelectionRange( pos, pos + dialog.length );
-
-                    //invoke the new dialog
-                    //console.log("next action: invoke "+dialog+" "+snip[dialog])
-                    self.commands.action( dialog, snip[dialog] );
-
-                    //remember every selected snippet dialog
-                    //self.undoredo.onChange();
-                    //self.fireEvent("change");
+            txta = self.textarea,
+            fromStart = txta.getFromStart(),
+            prevline = fromStart.split(/\r?\n/).pop(),
+            indentation = prevline.match(/^\s+/);
 
-                    return; // and retain the context snip for subsequent {dialogs}
+        //console.log(snippet,start,selectionLength);
 
-                } else {
+        //process whitespace before and after the snippet
+        //collapse \n of previous line if the snippet starts with \n
+        if( snippet.test(/^\n/) && ( fromStart.test( /(^|[\n\r]\s*)$/ ) ) ) {
+            //console.log("remove leading \\n", snippet);
+            snippet = snippet.slice( 1 );
+            start--;
+        }
 
-                    // no more {dialogs}, move the caret after the end of the snippet
-                    txta.setSelectionRange( pos + dialog.length );
+        //collapse \n of the next line when the snippet ends with a \n
+        if( snippet.test(/\n$/) && ( txta.getTillEnd().test( /^\s*[\n\r]/ ) ) ) {
+            //console.log("remove trailing \\n", snippet);
+            snippet = snippet.slice(0, -1);
+        }
 
-                }
-            }
+        //finally auto-indent the snippets internal newlines \n
+        if( indentation ){
+            snippet = snippet.replace( /\n/g, "\n" + indentation[0] );
         }
 
-        self.reset();
+        txta.setSelection( snippet )
+            .setSelectionRange( start, start + selectionLength );
+
     },
 
+
     /*
     Interface: Undoable
         Implemenent the "undoable" interface.
@@ -923,6 +830,7 @@ console.log(this.context.suggest);
         txta.setSelectionRange( state.cursor.start, state.cursor.end );
 
         self.fireEvent("change");
+        self.suggest();
     }
 
 });

Modified: jspwiki/trunk/jspwiki-war/src/main/scripts/wiki-edit/Wiki.Edit.js
URL: http://svn.apache.org/viewvc/jspwiki/trunk/jspwiki-war/src/main/scripts/wiki-edit/Wiki.Edit.js?rev=1732806&r1=1732805&r2=1732806&view=diff
==============================================================================
--- jspwiki/trunk/jspwiki-war/src/main/scripts/wiki-edit/Wiki.Edit.js (original)
+++ jspwiki/trunk/jspwiki-war/src/main/scripts/wiki-edit/Wiki.Edit.js Sun Feb 28 21:53:37 2016
@@ -26,6 +26,8 @@ Class: Wiki.Edit
     It uses an enhanced textarea based on the [Snipe] class.
 */
 
+/*eslint-env browser*/
+/*global Wiki, Snipe, Request */
 
 !function( wiki ){
 
@@ -58,7 +60,7 @@ wiki.add("#editform", function( element
 
         onChange: livepreview.debounce(500),
 
-        onConfig: config  //configuration callback
+        onConfig: config  //configuration callbacks
 
     });
 
@@ -74,6 +76,13 @@ wiki.add("#editform", function( element
 
     wiki.resizer( snipe.toElement(), function(h){ preview.setStyle("height", h); });
 
+    /*
+    $$("config[data-cmd]:checked").addEvent("configured", function(){
+        snipe.set(this.getAttribute("data-cmd"), this.checked).fireEvent("change") );
+    });
+    wiki.configuration( form );
+    */
+
     //Initialize the configuration checkboxes
     //Read the wiki-prefs cookie values.
     //EG: tabcompletion, smartpairs, autosuggest, livepreview, previewcolumn..
@@ -111,10 +120,13 @@ wiki.add("#editform", function( element
         The user gets a warning in case the textarea was changed, without saving.
 
         The onbeforeunload handler then gets removed on regular exit of the page.
+
+        wiki.editOBU(textarea);
+
     */
     function onbeforeunload( ){
 
-        window.onbeforeunload = function(event){
+        window.onbeforeunload = function(){
 
             if( textarea.value != textarea.defaultValue ){
 
@@ -127,58 +139,7 @@ wiki.add("#editform", function( element
     }
 
 
-    /*
-    Function: resizer
-        Activate the resize handle of the input textarea.
-        While dragging the resize handle, update the textarea and the
-        preview area. Store the new height in the "EditorSize" prefs cookie.
-
-    Arguments:
-        element - draggable resize handle (DOM element)
-        options - { cookie: name of the cookie to persist the editor size across pageloads }
-
-    Globals:
-        wiki - main wiki object, to get/set preference fields
-        textarea - resizable textarea (DOM element)
-        preview - preview (DOM element)
-    */
-    function resizer( resizableTextarea, handle, cookie ){
-
-        var height = "height",
-            size = wiki.prefs.get(cookie),
-            y;
-
-        function helpdragging(add){ handle.ifClass(add, "dragging"); }
-
-        if( size ){
-
-            resizableTextarea.setStyle(height, size);
-            preview.setStyle(height, size);
-
-        }
-
-        if( handle ){
-
-            //console.log("resizer ",textarea,preview);
-            resizableTextarea.makeResizable({
-                handle: handle,
-                modifiers: { x: null },
-                onDrag: function(){
-                    y = this.value.now.y;
-                    preview.setStyle(height, y);
-                    wiki.prefs.set(cookie, y);
-                },
-                onBeforeStart: helpdragging.pass(true),
-                onComplete: helpdragging.pass(false),
-                onCancel: helpdragging.pass(false)
-
-            });
-
-        }
-    }
-
-
-    /*
+   /*
     Function: livepreview
         Linked as onChange handler to the SnipEditor.
         Make AJAX call to the backend to convert the contents of the textarea
@@ -191,11 +152,12 @@ wiki.add("#editform", function( element
         var text = snipe.toElement().get("value"),
             loading = "loading";
 
-        console.log("**** change event", new Date().getSeconds(), previewcache, text.length );
+        console.log("**** change event", new Date().getSeconds() );
 
         if( !(getFormElement("[data-cmd=livepreview]") || {}).checked ){
 
             //cleanup the preview area
+            console.log("cleanup");
             if( previewcache ){
                 preview.empty();
                 previewcache = null;

Modified: jspwiki/trunk/jspwiki-war/src/main/scripts/wiki-edit/Wiki.Snips.js
URL: http://svn.apache.org/viewvc/jspwiki/trunk/jspwiki-war/src/main/scripts/wiki-edit/Wiki.Snips.js?rev=1732806&r1=1732805&r2=1732806&view=diff
==============================================================================
--- jspwiki/trunk/jspwiki-war/src/main/scripts/wiki-edit/Wiki.Snips.js (original)
+++ jspwiki/trunk/jspwiki-war/src/main/scripts/wiki-edit/Wiki.Snips.js Sun Feb 28 21:53:37 2016
@@ -16,6 +16,9 @@
     under the License.
 */
 
+/*eslint-env browser*/
+/*global Wiki, Dialog, Request  */
+
 /*
 DirectSnippet definitions for JSPWiki, aka ''smartpairs''.
 These snippets are directly expanded on keypress.
@@ -37,150 +40,6 @@ Wiki.DirectSnips = {
 Function: snippets
 
         Definitions for the JSPWiki editor commands.
-
-        A command consists of triggers, attributes, snippets, events and dialogs.
-
-        Following commands are predefined by the snipe editor:
-        - find : toggles the find and replace dialog
-        - sections : toggle sections dropdown dialog, which allows to switch
-            between certain sections of the document or the whole document
-        - undo : undo last command, set the editor to the previous stable state
-        - redo : revert last undo command
-
-
-Snippet Triggers :
-
-        Triggers can be click events, TAB-key, suggestion dialogs and shortcut-keys (ctrl+/meta+).
-
-        CLICK event:
-        Click events are attached to DOM elements with a {{data-cmd="cmd"}} attribute.
-
-        TAB key:
-        Enter a command followed by the TAB key.
-        TAB-completion can be turned on/off via the 'tabcompletion' flag.
-
-        KEYUP event, may trigger a suggestion dialog:
-        Suggestion dialogs are opened when the cursor is located 'inside' a command keyword.
-        Match function determines a valid suggestion command.
-
-        - the suggest(txta,caret) function validates the suggestion context
-          It returns true/false and can modify the snippet with
-             - snip.start : begin offset of the matched prefix
-             - snip.match : matched prefix (string)
-             - snip.tail: (optional) replaceable tail
-
-
-Snippet Attributes :
-        - initialize: function(cmd, snip){ return snippet } called once during initialisation
-        - key: shortcut key  (ctrl-key or meta-key)
-        - scope: returns TRUE when the command appears inside certain start and end pattern
-        - nscope: set to TRUE when the command is not inside certain start and end pattern
-        - cmdId: (wysiwyg mode only) corresponding commandIdentifier
-        - synonym:
-
-Snippet actions
-        Text, Event, Dialog (will be opened prior to insertion of the text)
-
-Snippet Text:
-        The snippet text contains the text to be inserted or replaced.
-        Add '\n' at the start or end of the snippet, if it need to appear on a new line.
-        - a {.description} (start with dot) will be replaced by the selected text, if any
-        - a {parameter} (not dot) will become the selected text AFTER insertion of the snippet
-        The snippet text can also be replace by a javascript function, so any manipulation
-        of the textarea is possible.
-
-Snippet Event :
-
-        Fires an event back to the invoking Object (Wiki.Edit in our case)
-        Example:
-            smartpairs: { event: 'config' }
-
-Snippet dialog:
-
-        Snippet dialog carry the name of the command.
-        (btw -- you do use unique names, do you?)
-        - <dialog-name>: [ Dialog.SubClass, {dialog-parameters, event-handlers} ]
-        - <dialog-name>: "dialog initialization string"
-          This is a short notation for Dialog.Selection, or..
-          [Selection, "put here your dialog initialization string"]
-
-        The Dialog Classes are subclass of Dialog. (eg. Dialog.Selection)
-
-
-Examples:
-
-    bold: '__{.bold}__'
-    bold: { snippet: '__{.bold}__' }
-
-    toc: { snippet: '\n[{TableOfContents}]\n' }
-
-    newline: {
-        key:'shift+enter',
-        snippet: '\\\\\n'
-    }
-    br: { synonym: 'newline' }
-
-
-    acl: {
-        nscope: { "[{" : "}]" },
-        snippet: "[{ALLOW {permission} {principal}  }]"
-     },
-     permission: {
-        scope: { "[{ALLOW" : "}]" },
-        suggest: 'ALLOW\s+(\w+)',
-        permission: "view|edit|delete"  //selection dialog
-     },
-     principal: {
-        scope: { "[{ALLOW" : "}]" },
-        suggest: 'ALLOW\s+\w+\s+(\w+)',
-        principals: [Dialog.Selection, {
-             onOpen: function(){ this.setBody( AJAX-request list of principals ); }
-        ]
-     },
-
-    link: {
-        key:'l',
-        scope: { '[':']' , '[':'\n' },
-        nscope: { '[{':'\n', '[[','\n' },
-        snippet: '[{.description} | {pagenameOrUrl} | linkAttributes ] ",
-        commandIdentifier:'createlink'
-    },
-    linkDlg: {
-        scope: { '[':']' , '[':'\n' },
-        //match [link] or [link,  do not match [{, [[
-        //match '[' + 'any char except \n, [, { or ]' at end of the string
-        suggest: '|?([^\\n\\|\\]\\[\\{]+)',
-        linkDlg: [Dialog.Link, {
-            onOpen: function(){
-                AJAX-retrieval of link suggestions
-            }
-         }]
-        ****
-            suggest: function(txta, caret){
-                //match [link] or [link,  do not match [{, [[
-                //match '[' + 'any char except \n, [, { or ]' at end of the string
-                var result = txta.getFromStart().match( /\[([^\[\{\]\n\r]*)$/ ),
-                    link;
-
-                if( result ){
-                    link = result[1].split('|').getLast(); //exclude "text|" prefix
-                    result = {
-                        start: caret.start - link.length ,
-                        //if no input yet, then get list attachments of this wikipage
-                        match: link,
-                        tail: txta.slice( caret.start ).search( /[\n\r\]]/ )
-                    };
-                }
-                return result;
-            },
-        ****
-    }
-    linkAttributes: {
-        scope: { '|':']'},
-        suggest: ...,
-        linkAttributes: 'class='', newpage ....'
-    }
-
 */
 
 Wiki.Snips = {
@@ -191,12 +50,12 @@ Wiki.Snips = {
         redo: { key: "y", event: "redo" },
 
         // Configuration commands
+        wysiwyg: { event: 'config' },
         smartpairs: { event: 'config' },
         livepreview: { event: 'config' },
         autosuggest: { event: 'config' },
         tabcompletion: { event: 'config' },
         previewcolumn: { event: 'config' },
-        wysiwyg: { event: 'config' },
 
 
         // Simple shortcuts
@@ -206,33 +65,47 @@ Wiki.Snips = {
         },
         hr: "\n----\n",
         lorem: "This is just some sample. Don’t even bother reading it; you will just waste your time. Why do you keep reading? Do I have to use Lorem Ipsum to stop you? OK, here goes: Lorem ipsum dolor sit amet, consectetur adipi sicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Still reading? Gosh, you’re impossible. I’ll stop here to spare you.",
-        Lorem: { synonym: "lorem" },
+        Lorem: { alias: "lorem" },
 
 
         // simple inline tab completion commands
-        bold:   { key: "b", snippet: "__{bold}__ " },
-        italic: { key: "i", snippet: "''{italic}'' " },
+        bold:   { key: "b", snippet: "__{bold}__" },
+        italic: { key: "i", snippet: "''{italic}''" },
 
-        mono:   { key: "m", snippet: "\\{\\{{monospaced text}}} " },
+        mono:   { key: "m", snippet: "{{{monospaced text}}} " },
         sub:    "%%sub {subscript text}/% ",
         sup:    "%%sup {superscript text}/% ",
         strike: "%%strike {strikethrough text}/% ",
 
         // simple block tab completion commands
-        quote:  "\n%%quote \n{Quoted text}\n/%\n",
-        dl:     "\n;{term}:{definition-text} ",
-        pre:    "\n\\{\\{\\{\n{some preformatted block}\n}}}\n",
-        code:   "\n%%prettify \n\\{\\{\\{\n{/* some code block */}\n}}}\n/%\n",
+        quote:  "\n%%quote\n{Quoted text}\n/%\n",
+        dl:     "\n;{term}:definition-text ",
+        pre:    "\n{{{\n{some preformatted block}\n}}}\n",
+        code:   "\n%%prettify \n{{{\n{/* some code block */}\n}}}\n/%\n",
         table:  "\n||{heading-1} ||heading-2\n|cell11     |cell12\n|cell21     |cell22\n",
-        t: { synonym: "table" },
+        t: { alias: "table" },
 
-        me: { alias: 'sign'},
+        me: { alias: "sign"},
         sign: function(){
             var name = Wiki.UserName || 'UserName';
             return "\n\\\\ &mdash;" + name + ", "+ new Date().toISOString() + "\\\\ \n";
         },
 
-        date: function(k) {
+        hDlg: {
+            suggest: { pfx:"(^|\n)([!]{1,3})$", match:"^([!]{1,3})(?:[^!])"},
+            hDlg: [Dialog.Selection, {
+                match: "=",  //exact match
+                body: {
+                    "!!!": "<span style='font-size:30px;xline-height:1;'>Header</span>",
+                    "!!": "<span style='font-size:24px;xline-height:30px;'>Title</span>",
+                    "!": "<span style='font-size:18px;xline-height:30px;'>Sub-title</span>",
+                    "{text}": "Normal Paragraph"
+                }
+            }]
+        },
+
+        now: { alias: "date" },
+        date: function( ){
             return new Date().toISOString()+' ';
             //return "[{Date value='" + d.toISOString() + "' }]"
             //return "[{Date " + d.toISOString() + " }]"
@@ -243,12 +116,10 @@ Wiki.Snips = {
                 "%%(":")",
                 "%%tabbedSection":"/%"
             },
-            snippet:"%%tabbedSection \n%%tab-{tabTitle1}\n{tab content 1}\n/%\n%%tab-{tabTitle2}\n{tab content 2}\n/%\n/%\n "
+            snippet:"%%tabbedSection \n%%tab-{tabTitle1}\ntab content 1\n/%\n%%tab-tabTitle2\ntab content 2\n/%\n/%\n "
         },
 
-
-
-        img: "\n[{Image src='img.jpg' width='400px' height='300px' align='{left}' }]\n ",
+        img: "\n[{Image src='{img.jpg}' width='400px' height='300px' align='left' }]\n ",
 
         imgSrcDlg:{
             scope: { "[{Image":"}]" },
@@ -258,16 +129,13 @@ Wiki.Snips = {
                 caption: "Image Source",
                 onOpen: function( dialog ){
 
-                    var //dialog = this,
-                        key = dialog.getValue();
+                    var key = dialog.getValue();
 
                     if( !key || (key.trim()=='') ){ key = Wiki.PageName + '/'; }
 
-                    //console.log('json lookup for '+key);
-             	   	//Wiki.ajaxJsonCall("/search/suggestions",[key,30], function(result) {
                     Wiki.jsonrpc("/search/suggestions", [key, 30], function( result ){
 
-                        console.log('jsonrpc result', result );
+                        //console.log('jsonrpc result', result );
                         if( result[1] /*length>1*/ ){
 
                             dialog.setBody( result );
@@ -282,18 +150,17 @@ Wiki.Snips = {
             }]
         },
 
-/*
         imgAlignDlg: {
             scope: { "[{Image":"}]" },
             suggest: "align='\\w+'",
             imgAlignDlg: "left|center|right"
         },
-*/
 
         font: {
-            nScope: { "%%(":")", },
-            snippet: "%%(font-family:{font};) body /% ",
+            nScope: { "%%(":")" },
+            snippet: "%%(font-family:{font};) body /% "
         },
+
         fontDlg: {
             scope: { "%%(":")" },
             suggest: { pfx: "font-family:([^;\\)\\n\\r]*)$", match:"^([^;\\)\\n\\r]*)" },
@@ -308,7 +175,7 @@ Wiki.Snips = {
             colorDlg: [ Dialog.Color , {} ]
          },
 
-        symbol: { synonym: "chars" },
+        symbol: { alias: "chars" },
         chars: "&entity;",
 
         charsDlg: {
@@ -316,7 +183,6 @@ Wiki.Snips = {
             charsDlg: [ Dialog.Chars, { caption:"Special Chars".localize() }]
         },
 
-
         icon: "%%icon-{}search /%",
         iconDlg: {
             scope: { "%%":"/%" },
@@ -375,7 +241,7 @@ Wiki.Snips = {
                     success:"<span class='success'>success</span>",
                     info:"<span class='info'>info</span>",
                     warning:"<span class='warning'>warning</span>",
-                    error:"<span class='error'>error</span>",
+                    error:"<span class='error'>error</span>"
                 }
             }]
         },
@@ -414,10 +280,9 @@ Wiki.Snips = {
             }]
         },
 
-
         cssDlg: {
             scope: { "%%":"/%" },
-            suggest: {pfx:"%%([\\da-zA-Z-_]*)$", match:"^[\\da-zA-Z-_]*"},
+            suggest: {pfx:"%%([\\da-zA-Z-_]*)$", match:"^[\\da-zA-Z-_]+"},
             cssDlg: {
                 "(css:value;)":"any css definitions",
                 "default":"contextual backgrounds",
@@ -448,13 +313,6 @@ Wiki.Snips = {
                 tabs:"Tabs",
                 viewer: "Media Viewer"
 
-//inline styles
-                //bold
-                //italic
-//                small:"<span class='small'>Smaller</span> text",
-//                sub:"2<span class='sub'>8</span> Sub-Script",
-//                sup:"2<span class='sup'>3</span> Super-Script",
-//                strike:"<span class='strike'>strikethrough</span>",
 //block styles
 //                quote:"<div class='quote'>Quoted paragraph</div>",
 //                lead:"<span class='lead'>LEAD text</span>",
@@ -465,9 +323,8 @@ Wiki.Snips = {
 
         link: {
             key:'l',
-            commandIdentifier:'createlink',
-            //snippet: "[{description|}{pagename or url}|{attributes}] ",
-            snippet: "[{pagename or url}] "
+            wysiwyg:'createlink',
+            snippet: "[description|{pagename or url}|options] "
         },
 
 
@@ -478,12 +335,12 @@ Wiki.Snips = {
             },
             linkPart3: {
                 //"class='category'": "Category link",
-                "class='viewer'": "View Linked content",
-                "class='slimbox'": "Add Slimbox link <span class='icon-slimbox'/> ",
-                "class='slimbox-link'": "Replace by Slimbox Link <span class='icon-slimbox'/> ",
+                "class='viewer'": "Embedded Viewer",
+                "class='slimbox'": "Add a Slimbox Link <span class='icon-slimbox'/> ",
+                "class='slimbox-link'": "Change to Slimbox Link <span class='icon-slimbox'/> ",
                 "divide1": "",
-                "class='btn btn-primary'": "Button Style",
-                "class='btn btn-xs btn-primary'": "Small Button Style",
+                "class='btn btn-primary'": "Button style (normal)",
+                "class='btn btn-xs btn-primary'": "Button style (small)",
                 "divide2": "",
                 "target='_blank'": "Open link in new tab"
             }
@@ -496,8 +353,8 @@ Wiki.Snips = {
             //match '[' + 'any char except \n, [, { or ]' at end of the string
             //note: do not include the [ in the matched string
             suggest: {
-                pfx: "\\[(?:[^\\|\\]]+\\|)?([^\\|\\[\\{\\]\\n\\r]*)$",
-                match: "^([^\\|\\[\\{\\]\\n\\r]*)(?:\\]|\\|)"
+                pfx: "\\[(?:[^\\|\\]]+\\|)?([^\\|\\[{\\]\\n\\r]*)$",
+                match: "^([^\\|\\[{\\]\\n\\r]*)(?:\\]|\\|)"
             },
 
             linkDlg: [ Dialog.Selection, {
@@ -534,14 +391,13 @@ Wiki.Snips = {
             variableDlg: "applicationname|baseurl|encoding|inlinedimages|interwikilinks|jspwikiversion|loginstatus|uptime|pagename|pageprovider|pageproviderdescription|page-styles|requestcontext|totalpages|username"
         },
 
-
         // Page access rights
-        allow: { synonym: "acl" },
-        acl: "\n[{ALLOW {permission} {principal} }]\n",
+        allow: { alias: "acl" },
+        acl: "\n[{ALLOW {permission} principal }]\n",
 
         permission: {
             scope:{ '[{ALLOW':'}]'},
-            suggest: { pfx:"ALLOW (\\w+)$", match:"^\\w+" },
+            suggest: { pfx:"ALLOW (\\w*)$", match:"^\\w+" },
             permission: [Dialog.Selection, {
                 cssClass:".dialog-horizontal",
                 body:"view|edit|modify|comment|rename|upload|delete"
@@ -579,41 +435,40 @@ Wiki.Snips = {
 
         toc: {
             nScope: { "[{":"}]" },
-            snippet:"\n[\\{TableOfContents }]\n"
+            snippet:"\n[~{TableOfContents }]\n"
         },
 
         tocParams: {
             scope:{ '[{TableOfContents':'}]'},
             suggest: "\\s",
             tocParams: [Dialog.Selection, {
-                caption: "TOC additional parameters",
+                caption: "TOC options",
                 body:{
-                " title='Page contents' ":"title",
+                " title='{Page contents}' ":"title",
                 " numbered='true' ":"numbered",
-                " prefix='Chap. ' ":"chapter prefix"
+                " prefix='{Chap. }' ":"chapter prefix"
                 }
             }]
         },
 
-
         plugin: "\n[{{plugin}}]\n",
 
         pluginDlg: {
             //match [{plugin}]  do not match [[{
             //match '[{' + 'any char except \n, or }]' at end of the string
             //note: do not include the [ in the matched string
-            //snippet: "\n[{{plugin}}]\n",
             suggest: {
-                pfx: "(^|[^\\[])\\[\\{([^\\[\\]\\n\\r]*)(?:\\|\\])?$",
+                pfx: "(^|[^\\[])\\[{(\\w*)(?:\\|\\])?$",
+                //pfx: "(^|[^\\[])\\[{([^\\[\\]\\n\\r]*)(?:\\|\\])?$",
                 match: "^([^\\[\\]\\n\\r]*)\\}\\]"
             },
             pluginDlg: [ Dialog.Selection, {
                 caption: "Plugin",
                 body: {
-                "ALLOW permission principal ": "Page Access Rights <span class='icon-unlock-alt' />",
-                "SET name='value'":"Set a Wiki variable",
-                "$varname":"Get a Wiki variable",
-                "If name='value' page='pagename' exists='true' contains='regexp'\n\nbody\n":"IF plugin",
+                "ALLOW {permission} principal ": "Page Access Rights <span class='icon-unlock-alt' />",
+                "SET {name}='value'":"Set a Wiki variable",
+                "${varname}":"Get a Wiki variable",
+                "If name='{value}' page='pagename' exists='true' contains='regexp'\n\nbody\n":"IF plugin",
                 "SET alias='${pagename}'":"Page Alias",
                 "SET sidebar='off'":"Collapse Sidebar",
                 //"Table":"Advanced Tables",
@@ -631,7 +486,7 @@ Wiki.Snips = {
                 "RecentChangesPlugin":"Displays the recent changed pages",
                 "ReferredPagesPlugin page='{pagename}' type='local|external|attachment' depth='1..8' include='regexp' exclude='regexp'":"Incoming Links (referred pages)",
                 "ReferringPagesPlugin page='{pagename}' separator=',' include='regexp' exclude='regexp'":"Outgoing Links (referring pages)",
-                "Search query='Janne' max='10'":"Insert a Search query",
+                "Search query='{Janne}' max='10'":"Insert a Search query",
                 "TableOfContents ":"Table Of Contents ",
                 "UndefinedPagesPlugin":"List pages that are missing",
                 "UnusedPagesPlugin":"List pages that have been orphaned",
@@ -644,67 +499,68 @@ Wiki.Snips = {
         },
 
         selectBlock: {
-            suggest: function(workarea, caret, fromStart){
+            suggest: function(workarea, caret /*, fromStart*/){
 
-                var cmd;
+                var selection = workarea.getSelection();
 
-                if(!caret.thin
-                && workarea.isCaretAtStartOfLine()
-                && workarea.isCaretAtEndOfLine() ){
+                if( !caret.thin
+                  && workarea.isCaretAtStartOfLine()
+                  && workarea.isCaretAtEndOfLine()
+                  && selection.slice(0,-1).indexOf("\n") > -1 ){
 
-                     console.log("got block selection" );
-                     return { pfx:"xx", match:workarea.getSelection() }
+                     //console.log("got block selection" );
+                     return { pfx:"", match:workarea.getSelection() }
                 }
             },
 
             selectBlock: [Dialog.Selection, {
                 cssClass: ".dialog-horizontal",
                 body:{
-                    "\\{\\{\\{\n{code block}\n}}}": "<span style='font-family:monospace;'>code</span>",
-                    "%%prettify\n\\{\\{\\{\n{pretiffied code block}\n}}}/%": "<span class='pun' style='font-family:monospace;'>prettify</span>"
+                    "\n{{{\n{code block}\n}}}\n": "<span style='font-family:monospace;'>code</span>",
+                    "\n%%scrollable\n{{{\n{code block}\n}}}/%\n": "<span style='font-family:monospace;'>scrollable-code</span>",
+                    "\n%%prettify\n{{{\n{pretiffied code block}\n}}}/%\n": "<span class='pun' style='font-family:monospace;'>prettify</span>"
                 }
             }]
         },
 
         selectStartOfLine: {
-            suggest: function(workarea, caret, fromStart){
+            suggest: function(workarea, caret/*, fromStart*/ ){
 
-                var cmd;
+                var selection = workarea.getSelection();
 
-                if(!caret.thin
-                && workarea.isCaretAtStartOfLine()
-                && !workarea.isCaretAtEndOfLine() ){
+                if( !caret.thin
+                  && workarea.isCaretAtStartOfLine()
+                  && workarea.isCaretAtEndOfLine() ){
 
-                     console.log("got start of line selection", caret);
-                     return { pfx:"xx", match:workarea.getSelection() }
+                     //console.log("got start of line selection", caret);
+                     return { pfx:"", match:selection }
                 }
             },
 
             selectStartOfLine: [Dialog.Selection, {
                 cssClass: ".dialog-horizontal",
                 body:{
-                    "!!!{header}": "H1",
-                    "!!{header}": "H2",
-                    "!{header}": "H3",
+                    "\n!!!{header}": "H1",
+                    "\n!!{header}": "H2",
+                    "\n!{header}": "H3",
                     "__{bold}__": "<b>bold</b>",
                     "''{italic}''": "<i>italic</i>",
-                    "\\{\\{{monospaced text}}} ": "<tt>mono</tt>",
+                    "{{{monospaced text}}} ": "<tt>mono</tt>",
+                    "{{{{code}}}}\n": "<span style='font-family:monospace;'>code</span>",
                     "[description|{link}|options]": "<span class='icon-link'/>",
-                    "[{Image src='${image.jpg}'}]": "<span class='icon-picture'/>"
+                    "[{Image src='${image.jpg}'}]": "<span class='icon-picture'/>",
+                    "\n[{{plugin}}]\n": "<span class='icon-puzzle-piece'></span>"
                 }
             }]
         },
         //Commands triggered by the selection of substrings:
         //    lowest priority vs. other snippets
         selectInline: {
-            suggest: function(workarea, caret, fromStart){
-
-                var cmd;
+            suggest: function(workarea, caret/*, fromStart*/ ){
 
                 if(!caret.thin){
-
-                     console.log("got selection", caret);
-                     return { pfx:"xx", match:workarea.getSelection() }
+                     //console.log("got selection", caret);
+                     return { pfx:"", match:workarea.getSelection() }
                 }
             },
 
@@ -713,13 +569,13 @@ Wiki.Snips = {
                 body:{
                     "__{bold}__":"<b>bold</b>",
                     "''{italic}''":"<i>italic</i>",
-                    "\\{\\{{monospaced text}}} ":"<tt>mono</tt>",
-                    "[description|{link}|options]":"<span class='icon-link'/>",
-                    "[{Image src='${image.jpg}'}]":"<span class='icon-picture'/>"
+                    "{{{monospaced text}}}":"<tt>mono</tt>",
+                    "{{{{code}}}}\n": "<span style='font-family:monospace;'>code</span>",
+                    "[description|{pagename or url}|options]":"<span class='icon-link'/>",
+                    "[{Image src='{image.jpg}'}]":"<span class='icon-picture'/>"
                 }
             }]
         }
 
-
 }
 

Modified: jspwiki/trunk/jspwiki-war/src/main/scripts/wiki/Search.js
URL: http://svn.apache.org/viewvc/jspwiki/trunk/jspwiki-war/src/main/scripts/wiki/Search.js?rev=1732806&r1=1732805&r2=1732806&view=diff
==============================================================================
--- jspwiki/trunk/jspwiki-war/src/main/scripts/wiki/Search.js (original)
+++ jspwiki/trunk/jspwiki-war/src/main/scripts/wiki/Search.js Sun Feb 28 21:53:37 2016
@@ -18,13 +18,13 @@
     specific language governing permissions and limitations
     under the License.
 */
+/*eslint-env browser*/
+/*global Class, Options, Events, Wiki, GraphBar  */
+/*exported Wiki.Search, SearchBox */
 /*
 Class: Wiki.Search
     ...
 
-Depends:
-    Graphbar
-
 DOM Structure:
     (start code)
     (end)

Modified: jspwiki/trunk/jspwiki-war/src/main/scripts/wiki/Wiki.Behaviors.js
URL: http://svn.apache.org/viewvc/jspwiki/trunk/jspwiki-war/src/main/scripts/wiki/Wiki.Behaviors.js?rev=1732806&r1=1732805&r2=1732806&view=diff
==============================================================================
--- jspwiki/trunk/jspwiki-war/src/main/scripts/wiki/Wiki.Behaviors.js (original)
+++ jspwiki/trunk/jspwiki-war/src/main/scripts/wiki/Wiki.Behaviors.js Sun Feb 28 21:53:37 2016
@@ -18,6 +18,12 @@
     specific language governing permissions and limitations
     under the License.
 */
+
+/*eslint-env browser*/
+/*global $$, Wiki, Cookie,
+         TableX, GraphBar, Tab, Accordion, Viewer, Collapsible,
+         prettyPrint, CommentBox, Columns, Tips, Flip, AddCSS */
+
 /*
 Wiki.Behaviours
     Contains all behaviours added by default to JSPWiki.
@@ -106,8 +112,8 @@ Credit: Lea Verou,  Static Pie
 */
     .add(".pie", function(pie){
 
-	    pie.style.animationDelay = '-' + parseFloat(pie.textContent) + 's';
-	    pie.setAttribute('data-percent', parseFloat(pie.textContent)+"%");
+        pie.style.animationDelay = '-' + parseFloat(pie.textContent) + 's';
+        pie.setAttribute('data-percent', parseFloat(pie.textContent)+"%");
 
     })
 
@@ -181,6 +187,21 @@ Behavior: Quote (based on Bootstrap)
     })
 
 
+    .add(".caps", function(element){
+
+        element.mapTextNodes( function(s){ return s.toLowerCase(); });
+
+    })
+
+
+    //FIXME  under construction
+    .add(".typography", function(element){
+
+        element.mapTextNodes( function(s){ return s.replace( /---/g, "&mdash;" );  });
+
+
+    })
+
 /*
 Behavior: Viewer
 >     %%viewer [link to youtube, vimeo, some-wiki-page, http://some-external-site ..] /%
@@ -542,13 +563,14 @@ Behavior: Font Icon style (based on BOOT
     //Font-Awesome: .fa.fa-<icon-name>
     FontJspwiki (via icomoon) : .icon-<icon-name>
 */
-    .add("[class^=icon-]", function(element){
+/*
+    .add("[class^=icon-]", function( element ){
 
         //element.className="glyphicon glyph"+element.className;
         //element.className = "fa fa-"+element.className.slice(5);
 
     })
-
+*/
 /*
 Behavior: List (based on BOOTSTRAP)
 
@@ -652,6 +674,64 @@ Behavior: Add-CSS
 */
     .add(".add-css", AddCSS)
 
+
+
+/*
+Behavior: Invisibles
+    Show hidden characters such as tabs and line breaks.
+    Credit: http://prismjs.com/plugins/show-invisibles/
+
+CSS:
+(start code)
+.token.tab:not(:empty):before,
+.token.cr:before,
+.token.lf:before { color: hsl(24, 20%, 85%); }
+
+.token.tab:not(:empty):before { content: '\21E5'; }
+.token.cr:before { content: '\240D'; }
+.token.lf:before { content: '\240A'; }
+(end)
+*/
+    .add(".invisibles pre", function(element){
+
+        var token = "<span class='token {0}'>$&</span>";
+
+        element.innerHTML = element.innerHTML
+            .replace( /\t/g, token.xsubs("tab") )
+            .replace( /\n/g, token.xsubs("lf") )
+            .replace( /\r/g, token.xsubs("cr") );
+
+    })
+
+
+/*
+Experimental
+svg pie,
+credit: lea verou
+
+*/
+    .add(".pie2", function( pie ){
+
+        var p = parseFloat(pie.textContent),
+            NS = "http://www.w3.org/2000/svg",
+            svg = document.createElementNS(NS, "svg"),
+            circle = document.createElementNS(NS, "circle"),
+            title = document.createElementNS(NS, "title");
+
+        circle.setAttribute("r", 16);
+        circle.setAttribute("cx", 16);
+        circle.setAttribute("cy", 16);
+        circle.setAttribute("stroke-dasharray", p + " 100");
+
+        svg.setAttribute("viewBox", "0 0 32 32");
+        title.textContent = pie.textContent;
+        pie.textContent = "";
+        svg.appendChild(title);
+        svg.appendChild(circle);
+        pie.appendChild(svg);
+
+    })
+
 /*
 Behavior:Flip, Flop
 

Modified: jspwiki/trunk/jspwiki-war/src/main/scripts/wiki/Wiki.js
URL: http://svn.apache.org/viewvc/jspwiki/trunk/jspwiki-war/src/main/scripts/wiki/Wiki.js?rev=1732806&r1=1732805&r2=1732806&view=diff
==============================================================================
--- jspwiki/trunk/jspwiki-war/src/main/scripts/wiki/Wiki.js (original)
+++ jspwiki/trunk/jspwiki-war/src/main/scripts/wiki/Wiki.js Sun Feb 28 21:53:37 2016
@@ -20,8 +20,8 @@
 */
 
 
-/*jshint forin:false, noarg:true, noempty:true, undef:true, unused:true, plusplus:false, immed:false, browser:true, mootools:true */
-/*global HighlightQuery, Behavior */
+/*eslint-env browser*/
+/*global $, $$, Form, Hash, Behavior, HighlightQuery, Accesskey */
 /*exported  Wiki */
 
 /*
@@ -73,7 +73,9 @@ var Wiki = {
 
 
         // add core jspwiki behaviors; needed to support the default template jsp's
-        wiki.add( "[accesskey]", Accesskey )
+        wiki.add( "body", wiki.caniuse )
+
+            .add( "[accesskey]", Accesskey )
 
             //.add("input[placeholder]", function(element){ element.placeholderX(); })
 
@@ -84,7 +86,7 @@ var Wiki = {
             })
 
             //generate modal confirmation boxes, eg prompting to execute
-            //unrecoverable actions such as deleting a page or attachment
+            //an unrecoverable action such as deleting a page or attachment
             //.add("[data-toggle]", "onModal", {attr:"data-modal"})
             .add( "[data-modal]", function(element){
                 element.onModal( element.get("data-modal") );
@@ -97,12 +99,12 @@ var Wiki = {
             })
 
             //make navigation bar sticky (simulate position:sticky; )
-            //.add("[data-toggle]", "onSticky" )
-            .add( ".sticky", function( element ){
+            //.add(".sticky", "onSticky" )
+            .add( ".sticky", function(element){
                 element.onSticky();
             })
 
-            //highlight previous search query in cookie or referrer page search query
+            //highlight previous search query in cookie or referrer page
             .add( ".page-content", function(element){
 
                 var previousQuery = "PrevQuery";
@@ -127,11 +129,10 @@ var Wiki = {
 
                 //activate Quick Navigation functionality
                 new wiki.Findpages(element, {
-
                     rpc: function(value, callback){
                         wiki.jsonrpc("/search/pages", [value, 16], callback);
                     },
-                    toUrl: wiki.toUrl.bind( wiki ),
+                    toUrl: wiki.toUrl.bind(wiki),
                     allowClone: function(){
                         return /view|preview|info|attach/.test( wiki.Context );
                     }
@@ -139,10 +140,9 @@ var Wiki = {
             })
 
             //activate ajax search routines on Search.jsp
-            .add( "#searchform2", function( form ){
+            .add( "#searchform2", function(form){
 
                 wiki.search = new wiki.Search( form, {
-
                     xhrURL: wiki.XHRSearch,
                     onComplete: function(){
                         //console.log(form.query.get("value"));
@@ -153,9 +153,9 @@ var Wiki = {
 
             //activate attachment upload routines
             .add( "#files", Form.File, {
-
                 max: 8,
                 rpc: function(progressid, callback){
+                    //console.log("progress", progressid);
                     wiki.jsonrpc("/progressTracker", [progressid], callback);
                 }
             });
@@ -165,6 +165,27 @@ var Wiki = {
             domready: wiki.domready.bind(wiki)
         });
 
+
+
+    },
+
+    caniuse: function( body ){
+
+        //Modernizr.addTest('flexbox', testAllProps('flexBasis', '1px', true));
+        var hasNativeFlex = document.createElement('b');
+
+        //hasNativeFlex.style.cssText = "flex-basis:1px;";
+        //if(!!hasNativeFlex.style.length){
+        //   console.log("i can flex");
+        //}
+        //
+
+        hasNativeFlex.style.display = "flex";
+        if( hasNativeFlex.style.display == "flex" ){
+            //console.log("i can flex");
+            body.addClass("can-flex");
+        };
+
     },
 
     /*
@@ -188,7 +209,7 @@ var Wiki = {
             duration: 20
         });
 
-        if( wiki.version != wiki.prefs.get('version') ){
+        if( wiki.version != wiki.prefs.get("version") ){
             wiki.prefs.empty();
             wiki.prefs.set("version", wiki.version);
         }
@@ -243,9 +264,9 @@ var Wiki = {
 
                 events = target.retrieve("events"); //mootools specific - to read registered events on elements
 
-                if( events && events[ popstate ] ){
+                if( events && events[popstate] ){
 
-                    target.fireEvent( popstate );
+                    target.fireEvent(popstate);
 
                 }
 
@@ -323,15 +344,15 @@ var Wiki = {
 
             var li, parentLi = ul.getParent();
 
-            while( li = ul.getFirst("li") ){
+            while( (li = ul.getFirst("li")) ){
 
                 if( li.innerHTML.trim() == "----" ){
 
-                    li.addClass( "divider" );
+                    li.addClass("divider");
 
                 } else if( !li.getFirst() || !li.getFirst("a") ){
 
-                    li.addClass( "dropdown-header" );
+                    li.addClass("dropdown-header");
 
                 }
                 li.inject(parentLi, "before");
@@ -442,7 +463,9 @@ var Wiki = {
 
     },
 
-
+    /*
+    Function: configuration
+    */
     configuration: function( form ){
 
         var wiki = this,
@@ -519,8 +542,8 @@ var Wiki = {
     /*
     Function: resizer
         Resize the target element, by dragging a .resizer handle.
-        More elements can be resized via the callback.
-        The .resizer can specify a prefs cookie to retrieve/store the height.
+        Multiple elements can be resized via the callback.
+        The .resizer element can specify a prefs cookie to retrieve/store the height.
         Used by the plain and wysiwyg editor.
 
     Arguments:
@@ -534,7 +557,7 @@ var Wiki = {
     */
     resizer: function( target, callback ){
 
-        var wiki = this,
+        var prefs = this.prefs,
             handle = document.getElement(".resizer"),
             pref = handle.getAttribute("data-resize-cookie"),
             h;
@@ -543,7 +566,7 @@ var Wiki = {
 
         //targets.setStyle(height, options.initial || "100%" );
         if( pref ){
-            h = Wiki.prefs.get(pref) || 300;
+            h = prefs.get(pref) || 300;
             target.setStyle("height", h );
             callback( h );
         }
@@ -554,7 +577,7 @@ var Wiki = {
             onDrag: function(){
                 h = this.value.now.y;
                 callback(h);
-                if(pref){ Wiki.prefs.set(pref, h); }
+                if(pref){ prefs.set(pref, h); }
             },
             onBeforeStart: helpdragging.pass(true),
             onComplete: helpdragging.pass(false),
@@ -587,27 +610,27 @@ var Wiki = {
 
         if( this.JsonUrl ){
 
-            console.log(method, JSON.stringify(params) );
+            //console.log(method, JSON.stringify(params) );
 
-    		//NOTE:  this is half a JSON rpc ... responseText is JSON formatted
+            //NOTE:  this is half a JSON rpc ... only responseText is JSON formatted
             new Request({
-    			url: this.JsonUrl + method,
-	    		//method:"post"     //defaults to "POST"
+                url: this.JsonUrl + method,
+                //method:"post"     //defaults to "POST"
                 //urlEncoded: true, //content-type header = www-form-urlencoded + encoding
                 //encoding: utf-8,
                 onSuccess: function( responseText ){
 
-                    console.log(responseText, JSON.decode( responseText ) );
+                    //console.log(responseText, JSON.parse( responseText ) );
                     callback( JSON.parse( responseText ) )
 
                 },
                 onError: function(error){
                     //console.log(error);
-                    throw new Error("Wiki rpc error: " + error);
                     callback( null );
+                    throw new Error("Wiki rpc error: " + error);
                 }
 
-    		}).send( "params=" + params );
+            }).send( "params=" + params );
 
             /* obsolete
             new Request.JSON({

Modified: jspwiki/trunk/jspwiki-war/src/main/styles/haddock/default/TOCPlugin.less
URL: http://svn.apache.org/viewvc/jspwiki/trunk/jspwiki-war/src/main/styles/haddock/default/TOCPlugin.less?rev=1732806&r1=1732805&r2=1732806&view=diff
==============================================================================
--- jspwiki/trunk/jspwiki-war/src/main/styles/haddock/default/TOCPlugin.less (original)
+++ jspwiki/trunk/jspwiki-war/src/main/styles/haddock/default/TOCPlugin.less Sun Feb 28 21:53:37 2016
@@ -44,7 +44,7 @@ DOM structure:
     (end)
 */
 .toc {
-    width:60%;
+    width: (100% - @wiki-commentbox-width);
 
     ul {
         .list-unstyled;

Modified: jspwiki/trunk/jspwiki-war/src/main/styles/haddock/default/Template.Edit.less
URL: http://svn.apache.org/viewvc/jspwiki/trunk/jspwiki-war/src/main/styles/haddock/default/Template.Edit.less?rev=1732806&r1=1732805&r2=1732806&view=diff
==============================================================================
--- jspwiki/trunk/jspwiki-war/src/main/styles/haddock/default/Template.Edit.less (original)
+++ jspwiki/trunk/jspwiki-war/src/main/styles/haddock/default/Template.Edit.less Sun Feb 28 21:53:37 2016
@@ -30,7 +30,7 @@ textarea { white-space: pre-wrap; }
 .editform, .dialog.find {
 
     input[type="text"]:focus, textarea:focus {
-        background:@highlight;
+        background:@wiki-editor-focus;
 
         //get rid of the default bootstrap highlight -- see forms.less and mixins/form-control-focus
         //outline:0;
@@ -53,6 +53,8 @@ textarea { white-space: pre-wrap; }
     padding: .5em;
 	resize: none !important; // disable resizable textareas in Webkit
     background: @wiki-editor-bg;
+    color:inherit;
+    font-size:90%;
 }
 
 //base styling similar to .page-content in Template.Content.less;
@@ -163,7 +165,7 @@ ul.dropdown-menu.dropdown-menu-horizonta
 /* Section command button and dropdown */
 .section-selected > .btn { color:@red; }  //red section button (bookmark) when a section is selected
 
-[data-sections] {
+.sections {
     //.indent-0 { }
     .indent-1 { text-indent:.5em; }
     .indent-2 { text-indent:1em; }

Modified: jspwiki/trunk/jspwiki-war/src/main/styles/haddock/default/Template.SearchBox.less
URL: http://svn.apache.org/viewvc/jspwiki/trunk/jspwiki-war/src/main/styles/haddock/default/Template.SearchBox.less?rev=1732806&r1=1732805&r2=1732806&view=diff
==============================================================================
--- jspwiki/trunk/jspwiki-war/src/main/styles/haddock/default/Template.SearchBox.less (original)
+++ jspwiki/trunk/jspwiki-war/src/main/styles/haddock/default/Template.SearchBox.less Sun Feb 28 21:53:37 2016
@@ -43,7 +43,6 @@ DOM structure:
         .opacity(0);
         width: 100%;
         //min-width:240px;
-        font-family: @wiki-logo-font-family;
 
         padding-right: 2em;
         .transition( all 0.5s ease );

Modified: jspwiki/trunk/jspwiki-war/src/main/styles/haddock/default/Template.View.less
URL: http://svn.apache.org/viewvc/jspwiki/trunk/jspwiki-war/src/main/styles/haddock/default/Template.View.less?rev=1732806&r1=1732805&r2=1732806&view=diff
==============================================================================
--- jspwiki/trunk/jspwiki-war/src/main/styles/haddock/default/Template.View.less (original)
+++ jspwiki/trunk/jspwiki-war/src/main/styles/haddock/default/Template.View.less Sun Feb 28 21:53:37 2016
@@ -45,7 +45,7 @@ Section: Title box
     The title box is an optional alert box at the top of the page, to put
     web-site messages, alerts, new-flashes etc.
     It contains the content of the [TitleBox] JSPWiki page.
-    Keep the styling minimal, as the TitleBox page itself can add any style it wants.
+    Keep the styling minimal, so the TitleBox page itself can add any style it wants.
 */
 //.titlebox { }
 
@@ -118,14 +118,11 @@ DOM structure:
 .header, .footer {
     .clearfix;
 	position: relative;
-    font-family: @wiki-header-font-family;
-    font-weight: 200;
-    letter-spacing: 1px;
     color: @wiki-header-color;
     a { color:inherit; }
 
     background-color:@wiki-header-bg;
-    #gradient .radial(@wiki-header-bg; darken(@wiki-header-bg,20%));
+    //#gradient .radial(@wiki-header-bg; darken(@wiki-header-bg,20%));
 
     //background-image:url(images/background.jpg);  //todo: read it from a cookie or so
     background-size:cover; //or contain;
@@ -154,9 +151,12 @@ a.logo {
     letter-spacing: .3em;
     text-decoration: none;
     padding: 0.15em 0.1em .25em .45em;
-    //border: 1px solid @white;
+    border: 1px solid @white;
     //border-radius: .5em;
     color: inherit;
+    background-image: @wiki-logo-image;
+    background-size: cover;
+    background-repeat: no-repeat;
 
     b {
         font-size: 150%;   //@font-size-base
@@ -221,13 +221,26 @@ Credits: https://philipwalton.github.io/
 */
 
 
-body > .container-fluid,
-body > .container {
+body.can-flex > .container-fluid,
+body.can-flex > .container {
+  display: -webkit-box;
+  display: -moz-box;
+  display: -ms-flexbox;
+  display: -webkit-flex;
   display: flex;
+
   min-height: 100vh;
+
+  -webkit-flex-flow: column;
+  -moz-flex-flow: column;
+  -ms-flex-flow: column;
   flex-flow: column;
 }
-.content {
+body.can-flex .content {
+  -webkit-box-flex: 1;
+  -moz-box-flex: 1;
+  -webkit-flex: 1;
+  -ms-flex: 1;
   flex: 1;
 }
 

Modified: jspwiki/trunk/jspwiki-war/src/main/styles/haddock/default/build.less
URL: http://svn.apache.org/viewvc/jspwiki/trunk/jspwiki-war/src/main/styles/haddock/default/build.less?rev=1732806&r1=1732805&r2=1732806&view=diff
==============================================================================
--- jspwiki/trunk/jspwiki-war/src/main/styles/haddock/default/build.less (original)
+++ jspwiki/trunk/jspwiki-war/src/main/styles/haddock/default/build.less Sun Feb 28 21:53:37 2016
@@ -158,6 +158,8 @@ Stylesheet: JSPWiki
 @import "Category.less";
 
 @import "Flip.less";
+@import "Invisibles.less";
+//@import "Pie.less";
 
 @import "prettify.less";
 

Modified: jspwiki/trunk/jspwiki-war/src/main/styles/haddock/default/type.less
URL: http://svn.apache.org/viewvc/jspwiki/trunk/jspwiki-war/src/main/styles/haddock/default/type.less?rev=1732806&r1=1732805&r2=1732806&view=diff
==============================================================================
--- jspwiki/trunk/jspwiki-war/src/main/styles/haddock/default/type.less (original)
+++ jspwiki/trunk/jspwiki-war/src/main/styles/haddock/default/type.less Sun Feb 28 21:53:37 2016
@@ -39,13 +39,6 @@ DOM structure:
         a.editsection[href="...&section=0"] [Edit]
 (end)
 */
-/* The original jspwiki margins on headers were  somewhat larger then bootstrap
-h2,h3,h4 {
-    margin:1em 0 0.5em 0;
-    line-height:1.5;
-}
-*/
-
 .hashlink { margin-left: 1em; }
 .editsection, .hashlink {
 
@@ -55,6 +48,13 @@ h2,h3,h4 {
     &:hover { .opacity(1); border-color:transparent; }
 
 }
+
+/* The original jspwiki margins on headers were  somewhat larger then bootstrap
+h2,h3,h4 {
+    margin:1em 0 0.5em 0;
+    line-height:1.5;
+}
+*/
 h2,h3,h4 {
 
     .editsection, .hashlink { .opacity(0); }
@@ -117,14 +117,14 @@ br { clear: both; }
 }
 
 //dl { .dl-horizontal; }
-dl dd { margin-left:2em; }   //reset flat style of bootstrap/type
+dl dd { margin-left: 2em; }   //reset flat style of bootstrap/type
 
 
 .hr {
   display: block;
-  margin-top: 10px 0;
+  margin-top: 10px;
   border: 0;
-  border-top: 1px solid #eeeeee;
+  border-top: 1px solid @hr-border;
 }
 
 
@@ -283,6 +283,8 @@ Section: Reusable Styles
 .sub { top: 0.4em; }
 
 
+.caps { font-variant: small-caps; }
+
 .strike { text-decoration:line-through; }
 
 //see also bootstrap .text-center
@@ -317,15 +319,15 @@ div.dropcaps {
 .page-break {
     display:block;
     height:2px;
-    /*background:url(page-break.jpg) 0 center repeat-x; */
-    border-top:2px dashed @table-border-color;
+    // background:url(page-break.jpg) 0 center repeat-x;
+    border-top:1px dashed @table-border-color;
     margin:1em 0;
 
     &:hover:after {
-        content:"page break";
-        text-align:center;
-        display:block;
-        color:@table-border-color;
+        content: "page break";
+        text-align: center;
+        display: block;
+        color: @table-border-color;
         .small;
     }
 

Modified: jspwiki/trunk/jspwiki-war/src/main/styles/haddock/default/variables.less
URL: http://svn.apache.org/viewvc/jspwiki/trunk/jspwiki-war/src/main/styles/haddock/default/variables.less?rev=1732806&r1=1732805&r2=1732806&view=diff
==============================================================================
--- jspwiki/trunk/jspwiki-war/src/main/styles/haddock/default/variables.less (original)
+++ jspwiki/trunk/jspwiki-war/src/main/styles/haddock/default/variables.less Sun Feb 28 21:53:37 2016
@@ -44,12 +44,21 @@
 @black:  #111;
 
 
+//Apache new logo styles
+/*
+COLORS: Red: #d22027 | Dark Gray: #6d6e70
+TYPEFACES:
+"APACHE" wordmark = Raleway Regular [tracking set to -40]
+"THE",  "SOFTWARE FOUNDATION" & URL = Montserrat Light [tracking set to 215]
+*/
+
 //JSPWiki paths
 @imagePath: "./images";
 @icon-font-path: "./fonts/";
 
 // Might as well use the nicest Helvetica you can... http://css-tricks.com/snippets/css/better-helvetica/
-@font-family-sans-serif: "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif;
+@font-family-sans-serif: "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", HelveticaNeue, Segoe UI, Helvetica, Arial, sans-serif;
+@font-size-base: 16px;
 
 //softer gray-tones
 @pre-bg:                      #f7f7f9; //#f2f2f2;
@@ -61,7 +70,7 @@
 
 // JPSWiki variables
 // Main color scheme
-@wiki-header-bg:    @brand-primary; //#1976D2;
+@wiki-header-bg:    #4A89DC; //@brand-primary;
 @wiki-header-color: @white;
 @wiki-page-bg:      @white;
 @wiki-sidebar-bg:   #e5e8ed;
@@ -91,6 +100,7 @@
 @wiki-logo-font-family: 'HelveticaNeue-UltraLight', 'Helvetica Neue UltraLight', 'Helvetica Neue', Arial, Helvetica, sans-serif;
 @wiki-logo-font-size: 20px;
 @wiki-logo-padding: 5px;
+@wiki-logo-image: url("@{imagePath}/feather-small.png");
 @breadcrumb-color: @white;
 
 //TODO: Stacking...
@@ -109,16 +119,17 @@
 @wiki-recentchanges-date-bg: @wiki-sidebar-bg;
 @wiki-link-createpage: @red;
 @wiki-diff-bg:         @pre-bg;
-@wiki-diff-add:        #9f9; //diff inserted lines
-@wiki-diff-delete:     #f93; //diff deleted lines
+@wiki-diff-add:        @state-success-bg; //#eaffea; //#9f9; //diff inserted lines
+@wiki-diff-delete:     @state-danger-bg; //#fdd; //#f93; //diff deleted lines
 @wiki-captcha-bg:      @gray-lighter;
 @wiki-captcha-width:   125px;
 
+
 @pre-scrollable-max-height: 240px;  //bootstrap default is 340px
 
 @dropcaps-color:       @text-color;
 @dropcaps-font-size:   500%;
-@dropcaps-font-weight: thin;
+@dropcaps-font-weight: 700;
 @dropcaps-font-family: @wiki-logo-font-family; //Georgia
 
 // Viewer
@@ -152,3 +163,4 @@
 @wiki-editor-bg : @white;
 @wiki-preview-bg : transparent; //@white;
 @wiki-resizer:  @btn-primary-bg;
+@wiki-editor-focus: rgba(243, 156, 18, 0.1);
\ No newline at end of file

Modified: jspwiki/trunk/jspwiki-war/src/main/webapp/templates/haddock/AttachmentTab.jsp
URL: http://svn.apache.org/viewvc/jspwiki/trunk/jspwiki-war/src/main/webapp/templates/haddock/AttachmentTab.jsp?rev=1732806&r1=1732805&r2=1732806&view=diff
==============================================================================
--- jspwiki/trunk/jspwiki-war/src/main/webapp/templates/haddock/AttachmentTab.jsp (original)
+++ jspwiki/trunk/jspwiki-war/src/main/webapp/templates/haddock/AttachmentTab.jsp Sun Feb 28 21:53:37 2016
@@ -66,7 +66,7 @@
       <input class="form-control form-col-50" type="text" name="changenote" id="changenote" maxlength="80" size="60" />
     </div>
     <div class="form-group">
-      <input class="btn btn-primary form-col-offset-20 form-col-50"
+      <input class="btn btn-success form-col-offset-20 form-col-50"
              type="submit" name="upload" id="upload" disabled="disabled" value="<fmt:message key='attach.add.submit'/>" />
     </div>
     <div class="hidden form-col-offset-20 form-col-50 progress progress-striped active">




Mime
View raw message