[SPIP][PLUGINS] v3.0-->v3.2
[lhc/web/www.git] / www / plugins-dist / porte_plume / javascript / jquery.markitup_pour_spip.js
index 023ef64..0a4ab63 100644 (file)
@@ -1,9 +1,9 @@
 // ----------------------------------------------------------------------------
 // markItUp! Universal MarkUp Engine, JQuery plugin
-// v 1.1.12
+// v 1.1.14 ( c014800b - 02/06/2014 )
 // Dual licensed under the MIT and GPL licenses.
 // ----------------------------------------------------------------------------
-// Copyright (C) 2007-2011 Jay Salvat
+// Copyright (C) 2007-2012 Jay Salvat
 // http://markitup.jaysalvat.com/
 // ----------------------------------------------------------------------------
 // Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -26,7 +26,7 @@
 // ----------------------------------------------------------------------------
 
 /*
- *   Le code original de markitup 1.1.12
+ *   Le code original de markitup 1.1.14
  *   a ete modifie pour prendre en compte
  * 
  *   1) la langue utilisee dans les textarea :
  *   3) eviter a Opera de gerer les evenements apres tabulation ou entree...
  *      il ne sait pas gerer (v11.51)
  * 
- *             
+ *   4) ajout d'un <em> supplĂ©mentaire sur le html des boutons de la barre d'outil, pour des histoires de sprites
  */
 ;(function($) {
        $.fn.markItUp = function(settings, extraSettings) {
-               var options, ctrlKey, shiftKey, altKey;
-               ctrlKey = shiftKey = altKey = false;
+               var method, params, options, ctrlKey, shiftKey, altKey; ctrlKey = shiftKey = altKey = false;
+               markitup_prompt = false; // variable volontairement globale
+               
+               if (typeof settings == 'string') {
+                       method = settings;
+                       params = extraSettings;
+               } 
 
                options = {     id:                                             '',
                                        nameSpace:                              '',
                                        root:                                   '',
                                        lang:                                   '',
+                                       previewHandler:                 false,
                                        previewInWindow:                '', // 'width=800, height=600, resizable=yes, scrollbars=yes'
+                                       previewInElement:               '',
                                        previewAutoRefresh:             true,
                                        previewPosition:                'after',
                                        previewTemplatePath:    '~/templates/preview.html',
                                        previewParser:                  false,
                                        previewParserPath:              '',
                                        previewParserVar:               'data',
+                                       previewParserAjaxType:  'POST',
                                        resizeHandle:                   true,
                                        beforeInsert:                   '',
                                        afterInsert:                    '',
                        });
                }
 
+               // Quick patch to keep compatibility with jQuery 1.9
+               var uaMatch = function(ua) {
+                       ua = ua.toLowerCase();
+
+                       var match = /(chrome)[ \/]([\w.]+)/.exec(ua) ||
+                               /(webkit)[ \/]([\w.]+)/.exec(ua) ||
+                               /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) ||
+                               /(msie) ([\w.]+)/.exec(ua) ||
+                               ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) ||
+                               [];
+
+                       return {
+                               browser: match[ 1 ] || "",
+                               version: match[ 2 ] || "0"
+                       };
+               };
+               var matched = uaMatch( navigator.userAgent );
+               var browser = {};
+
+               if (matched.browser) {
+                       browser[matched.browser] = true;
+                       browser.version = matched.version;
+               }
+               if (browser.chrome) {
+                       browser.webkit = true;
+               } else if (browser.webkit) {
+                       browser.safari = true;
+               }
+
                return this.each(function() {
                        var $$, textarea, levels, scrollPosition, caretPosition,
                                clicked, hash, header, footer, previewWindow, template, iFrame, abort,
                        options.previewParserPath = localize(options.previewParserPath);
                        options.previewTemplatePath = localize(options.previewTemplatePath);
 
+                       if (method) {
+                               switch(method) {
+                                       case 'remove':
+                                               remove();
+                                       break;
+                                       case 'insert':
+                                               markup(params);
+                                       break;
+                                       default: 
+                                               $.error('Method ' +  method + ' does not exist on jQuery.markItUp');
+                               }
+                               return;
+                       }
+
                        // apply the computed path to ~/
                        function localize(data, inText) {
                                if (inText) {
                                $(dropMenus(options.markupSet)).appendTo(header);
                                // remove empty dropMenu
                                $(header).find("li.markItUpDropMenu ul:empty").parent().remove();
-                               
+
                                // add the footer after the textarea
                                footer = $('<div class="markItUpFooter"></div>').insertAfter($$);
 
                                // add the resize handle after textarea
-                               
-                               if (options.resizeHandle === true && $.browser.safari !== true) {
+                               if (options.resizeHandle === true && browser.safari !== true) {
                                        resizeHandle = $('<div class="markItUpResizeHandle"></div>')
                                                .insertAfter($$)
-                                               .bind("mousedown", function(e) {
+                                               .on("mousedown.markItUp", function(e) {
                                                        var h = $$.height(), y = e.clientY, mouseMove, mouseUp;
                                                        mouseMove = function(e) {
                                                                $$.css("height", Math.max(20, e.clientY+h-y)+"px");
                                                                return false;
                                                        };
                                                        mouseUp = function(e) {
-                                                               $("html").unbind("mousemove", mouseMove).unbind("mouseup", mouseUp);
+                                                               $("html").off("mousemove.markItUp", mouseMove).off("mouseup.markItUp", mouseUp);
                                                                return false;
                                                        };
-                                                       $("html").bind("mousemove", mouseMove).bind("mouseup", mouseUp);
+                                                       $("html").on("mousemove.markItUp", mouseMove).on("mouseup.markItUp", mouseUp);
                                        });
                                        footer.append(resizeHandle);
                                }
 
                                // listen key events
-                               $$.keydown(keyPressed).keyup(keyPressed);
+                               $$.on('keydown.markItUp', keyPressed).on('keyup', keyPressed);
                                
                                // bind an event to catch external calls
-                               $$.bind("insertion", function(e, settings) {
+                               $$.on("insertion.markItUp", function(e, settings) {
                                        if (settings.target !== false) {
                                                get();
                                        }
                                });
 
                                // remember the last focus
-                               $$.focus(function() {
+                               $$.on('focus.markItUp', function() {
                                        $.markItUp.focused = this;
                                });
+
+                               if (options.previewInElement) {
+                                       refreshPreview();
+                               }
                        }
 
                        // recursively build header with dropMenus from markupset
                                        // pas de langue ou dans la langue ; et uniquement si langue autorisee
                                        if ((!lang || !button.lang || ($.inArray(lang, button.lang) != -1))
                                                && (!button.lang_not || ($.inArray(lang, button.lang_not) == -1))) {
-                                               title = (button.key) ? (button.name||'')+' [Ctrl+'+button.key+']' : (button.name||'');
+                                               button.title ? title = (button.key) ? (button.title||'')+' [Ctrl+'+button.key+']' : (button.title||'') : title = (button.key) ? (button.name||'')+' [Ctrl+'+button.key+']' : (button.name||'');
                                                key   = (button.key) ? 'accesskey="'+button.key+'"' : '';
                                                if (button.separator) {
                                                        li = $('<li class="markItUpSeparator">'+(button.separator||'')+'</li>').appendTo(ul);
                                                        for (j = levels.length -1; j >= 0; j--) {
                                                                t += levels[j]+"-";
                                                        }
-                                                       li = $('<li class="markItUpButton markItUpButton'+t+(i)+' '+(button.className||'')+'"><a href="" '+key+' title="'+title+'"><em>'+(button.name||'')+'</em></a></li>')
-                                                       .bind("contextmenu", function() { // prevent contextmenu on mac and allow ctrl+click
+                                                       li = $('<li class="markItUpButton markItUpButton'+t+(i)+' '+(button.className||'')+'"><a href="#" '+key+' title="'+title+'"><em>'+(button.name||'')+'</em></a></li>')
+                                                       .on("contextmenu.markItUp", function() { // prevent contextmenu on mac and allow ctrl+click
                                                                return false;
-                                                       }).click(function() {
-                                                               return false;
-                                                       }).bind("focusin", function(){
+                                                       }).on('click.markItUp', function(e) {
+                                                               e.preventDefault();
+                                                       }).on("focusin.markItUp", function(){
                                                                $$.focus();
-                                                       }).mouseup(function() {
+                                                       }).on('mouseup', function(e) {
                                                                if (button.call) {
-                                                                       eval(button.call)();
+                                                                       eval(button.call)(e); // Pass the mouseup event to custom delegate
                                                                }
                                                                setTimeout(function() { markup(button) },1);
                                                                return false;
-                                                       }).hover(function() {
+                                                       }).on('mouseenter.markItUp', function() {
                                                                        $('> ul', this).show();
                                                                        $(document).one('click', function() { // close dropmenu if click outside
                                                                                        $('ul ul', header).hide();
                                                                                }
                                                                        );
-                                                               }, function() {
+                                                       }).on('mouseleave.markItUp', function() {
                                                                        $('> ul', this).hide();
-                                                               }
-                                                       ).appendTo(ul);
+                                                       }).appendTo(ul);
                                                        if (button.dropMenu) {
                                                                levels.push(i);
                                                                $(li).addClass('markItUpDropMenu').append(dropMenus(button.dropMenu));
                                                        if (abort === true) {
                                                                return false;
                                                        }
+                                                       
+                                                       // On prĂ©vient qu'un prompt s'ouvre
+                                                       markitup_prompt = true;
+                                                       
                                                        value = prompt(b[0], (b[1]) ? b[1] : '');
                                                        if (value === null) {
                                                                abort = true;
                                                        }
+                                                       
+                                                       // On attend un peu avant de dire que le prompt est fermĂ©
+                                                       // pour ne pas que Ă§a soit pris en compte en mĂŞme temps que la fermeture du prompt
+                                                       setTimeout(function(){markitup_prompt = false;}, 500);
+                                                       
                                                        return value;
                                                }
                                        );
                                var openBlockWith               = prepare(clicked.openBlockWith);
                                var closeBlockWith              = prepare(clicked.closeBlockWith);
                                var multiline                   = clicked.multiline;
-
+                               
                                if (replaceWith !== "") {
                                        block = openWith + replaceWith + closeWith;
                                } else if (selection === '' && placeHolder !== '') {
                                } else if (multiline === true) {
                                        string = string || selection;
 
-                                       var lines = selection.split(/\r?\n/), blocks = [];
-
-                                       for (var l=0; l < lines.length; l++) {
+                                       var lines = [string], blocks = [];
+                                       
+                                       if (multiline === true) {
+                                               lines = string.split(/\r?\n/);
+                                       }
+                                       
+                                       for (var l = 0; l < lines.length; l++) {
                                                line = lines[l];
                                                var trailingSpaces;
                                                if (trailingSpaces = line.match(/ *$/)) {
                                                        blocks.push(openWith + line + closeWith);
                                                }
                                        }
-
+                                       
                                        block = blocks.join("\n");
                                } else {
                                        block = openWith + (string || selection) + closeWith;
                                }
 
                                block = openBlockWith + block + closeBlockWith;
-                               
+
                                return {        block:block, 
+                                                       openBlockWith:openBlockWith,
                                                        openWith:openWith, 
                                                        replaceWith:replaceWith, 
                                                        placeHolder:placeHolder,
-                                                       closeWith:closeWith
+                                                       closeWith:closeWith,
+                                                       closeBlockWith:closeBlockWith
                                        };
                        }
 
 
                        function selectWord(){
                                selectionBeforeAfter(/\s|[.,;:!¡?Âż()]/);
-                               selectionSave();                                
+                               selectionSave();
                        }
                        function selectLine(){
                                selectionBeforeAfter(/\r?\n/);
-                               selectionSave();                                
-                       }                       
-                       
+                               selectionSave();
+                       }
+
                        function selectionRemoveLast(pattern){
                                        // Remove space by default
                                        if (!pattern) pattern = /\s/;
                                                set(caretPosition, selection.length-1);
                                                get();
                                                $.extend(hash, { caretPosition:caretPosition, scrollPosition:scrollPosition } );
-                                       }                               
+                                       }
                        }
-                       
+
                        function selectionBeforeAfter(pattern) {
                                if (!pattern) pattern = /\s/;
 
                                sautAvantIE = sautApresIE = 0;
-                               if ($.browser.msie) {
+                               if (browser.msie) {
                                                // calcul du nombre reel de caracteres pour le substr()
                                                // IE ne compte pas les sauts de lignes pour definir les selections
                                                // mais les compte dans la fonction length()
                                        before = textarea.value.substring(0, caretPosition);
                                        after = textarea.value.substring(caretPosition + selection.length - fixIeBug(selection));
                                }
-                                               
+
                                before = before.split(pattern);
                                after = after.split(pattern);
                                // ajouter ce fichu saut de ligne pour IE
                                if (sautAvantIE) before.push("");
                                if (sautApresIE) after.unshift("");
-                                       
+
                        }
-                       
+
                        function selectionSave(){
                                nb_before = before ? before[before.length-1].length : 0;
                                nb_after = after ? after[0].length : 0;
                                get();
                                $.extend(hash, { selection:selection, caretPosition:caretPosition, scrollPosition:scrollPosition } );
                        }
-                       
+
                        // define markup to insert
                        function markup(button) {
                                var len, j, n, i;
                                                                        altKey:altKey
                                                                }
                                                        );
-
+                                                       
                                // corrections des selections pour que
                                // - soit le curseur ne change pas
                                // - soit on prend le mot complet (si pas de selection)
                                                        // win/ff add space on double click ? (hum, seems strange)
                                                        selectionRemoveLast(/\s/);
                                                }
-                                       }                               
+                                       }
                                        if (button.selectionType == "line") {
                                                selectLine();
                                        }
                                                // c'est extremement vilain a chaque saut de ligne
                                                // des qu'il y a un texte volumineux.
                                                // on dit tant pis pour lui.
-                                               if (!$.browser.msie) {
+                                               if (!browser.msie) {
                                                        selectionBeforeAfter(/\r?\n/);
                                                        before_last = before[before.length-1];
                                                        after = '';
                                prepare(clicked.beforeInsert);
                                if ((ctrlKey === true && shiftKey === true) || button.multiline === true) {
                                        prepare(clicked.beforeMultiInsert);
-                               }                       
+                               }
                                $.extend(hash, { line:1 });
 
                                if ((ctrlKey === true && shiftKey === true) || button.forceMultiline === true) {
                                                        lines[i] = "";
                                                }
                                        }
+
                                        string = { block:lines.join('\n')};
                                        start = caretPosition;
-                                       len = string.block.length + (($.browser.opera) ? n-1 : 0);
+                                       len = string.block.length + ((browser.opera) ? n-1 : 0);
                                } else if (ctrlKey === true) {
                                        string = build(selection);
                                        start = caretPosition + string.openWith.length;
                                        len = 0;
                                        start -= fixIeBug(string.block);
                                }
-
+                               
                                if ((selection === '' && string.replaceWith === '')) {
                                        caretOffset += fixOperaBug(string.block);
-                                       
-                                       start = caretPosition + string.openWith.length;
-                                       len = string.block.length - string.openWith.length - string.closeWith.length;
+
+                                       start = caretPosition + string.openBlockWith.length + string.openWith.length;
+                                       len = string.block.length - string.openBlockWith.length - string.openWith.length - string.closeWith.length - string.closeBlockWith.length;
 
                                        caretOffset = $$.val().substring(caretPosition,  $$.val().length).length;
                                        caretOffset -= fixOperaBug($$.val().substring(0, caretPosition));
                                if (previewWindow && options.previewAutoRefresh) {
                                        refreshPreview(); 
                                }
-                               
+
                                // reinit keyevent
                                shiftKey = altKey = ctrlKey = abort = false;
-                               
                        }
 
                        // Substract linefeed in Opera
                        function fixOperaBug(string) {
-                               if ($.browser.opera) {
+                               if (browser.opera) {
                                        return string.length - string.replace(/\n*/g, '').length;
                                }
                                return 0;
                        }
                        // Substract linefeed in IE
                        function fixIeBug(string) {
-                               if ($.browser.msie) {
+                               if (browser.msie) {
                                        return string.length - string.replace(/\r*/g, '').length;
                                }
                                return 0;
                        function set(start, len) {
                                if (textarea.createTextRange){
                                        // quick fix to make it work on Opera 9.5
-                                       if ($.browser.opera && $.browser.version >= 9.5 && len == 0) {
+                                       if (browser.opera && browser.version >= 9.5 && len == 0) {
                                                return false;
                                        }
                                        range = textarea.createTextRange();
                                scrollPosition = textarea.scrollTop;
                                if (document.selection) {
                                        selection = document.selection.createRange().text;
-                                       if ($.browser.msie) { // ie
+                                       if (browser.msie) { // ie
                                                var range = document.selection.createRange(), rangeCopy = range.duplicate();
                                                rangeCopy.moveToElementText(textarea);
                                                caretPosition = -1;
                                        }
                                } else { // gecko & webkit
                                        caretPosition = textarea.selectionStart;
+
                                        selection = textarea.value.substring(caretPosition, textarea.selectionEnd);
-       
                                } 
                                return selection;
                        }
 
                        // open preview window
                        function preview() {
-                               if (!previewWindow || previewWindow.closed) {
+                               if (typeof options.previewHandler === 'function') {
+                                       previewWindow = true;
+                               } else if (options.previewInElement) {
+                                       previewWindow = $(options.previewInElement);
+                               } else if (!previewWindow || previewWindow.closed) {
                                        if (options.previewInWindow) {
                                                previewWindow = window.open('', 'preview', options.previewInWindow);
                                                $(window).unload(function() {
                                                        iFrame.insertAfter(footer);
                                                } else {
                                                        iFrame.insertBefore(header);
-                                               }
+                                               }       
                                                previewWindow = iFrame[iFrame.length - 1].contentWindow || frame[iFrame.length - 1];
                                        }
                                } else if (altKey === true) {
 
                        // refresh Preview window
                        function refreshPreview() {
-                               renderPreview();
+                               renderPreview();
                        }
 
                        function renderPreview() {
                                var phtml;
-                               if (options.previewParser && typeof options.previewParser === 'function') {
+                               if (options.previewHandler && typeof options.previewHandler === 'function') {
+                                       options.previewHandler( $$.val() );
+                               } else if (options.previewParser && typeof options.previewParser === 'function') {
                                        var data = options.previewParser( $$.val() );
-                                       writeInPreview( localize(data, 1) ); 
+                                       writeInPreview(localize(data, 1) ); 
                                } else if (options.previewParserPath !== '') {
                                        $.ajax({
-                                               type: 'POST',
+                                               type: options.previewParserAjaxType,
                                                dataType: 'text',
                                                global: false,
                                                url: options.previewParserPath,
                                        });
                                } else {
                                        if (!template) {
-                                               $.ajax( {
+                                               $.ajax({
                                                        url: options.previewTemplatePath,
                                                        dataType: 'text',
                                                        global: false,
                                }
                                return false;
                        }
-
+                       
                        function writeInPreview(data) {
-                               if (previewWindow.document) {                   
+                               if (options.previewInElement) {
+                                       $(options.previewInElement).html(data);
+                               } else if (previewWindow && previewWindow.document) {                   
                                        try {
                                                sp = previewWindow.document.documentElement.scrollTop
                                        } catch(e) {
                                        previewWindow.document.documentElement.scrollTop = sp;
                                }
                        }
-                                               
+                       
                        // set keys pressed
-                       function keyPressed(e) {
+                       function keyPressed(e) { 
                                shiftKey = e.shiftKey;
                                altKey = e.altKey;
                                ctrlKey = (!(e.altKey && e.ctrlKey)) ? (e.ctrlKey || e.metaKey) : false;
 
                                if (e.type === 'keydown') {
                                        if (ctrlKey === true) {
-                                               li = $('a[accesskey="'+String.fromCharCode(e.keyCode)+'"]', header).parent('li');
+                                               li = $('a[accesskey="'+((e.keyCode == 13) ? '\\n' : String.fromCharCode(e.keyCode))+'"]', header).parent('li');
                                                if (li.length !== 0) {
                                                        ctrlKey = false;
                                                        setTimeout(function() {
                                        
                                        // si opera, on s'embete pas, il cree plus de problemes qu'autre chose
                                        // car il ne prend pas en compte l'arret de ces evenements
-                                       if (!$.browser.opera) { 
+                                       if (!browser.opera) {
                                                if (e.keyCode === 13 || e.keyCode === 10) { // Enter key
                                                        if (ctrlKey === true) {  // Enter + Ctrl
                                                                ctrlKey = false;
                                                        if (shiftKey == true || ctrlKey == true || altKey == true) {
                                                                // permettre un retour a l'action naturelle
                                                                // du navigateur via shift+tab 
-                                                               return true; 
+                                                               return false; 
                                                        }
                                                        if (caretOffset !== -1) {
                                                                get();
                                }
                        }
 
+                       function remove() {
+                               $$.off(".markItUp").removeClass('markItUpEditor');
+                               $$.parent('div').parent('div.markItUp').parent('div').replaceWith($$);
+
+                               var relativeRef = $$.parent('div').parent('div.markItUp').parent('div');
+                               if (relativeRef.length) {
+                                   relativeRef.replaceWith($$);
+                               }
+                               
+                               $$.data('markItUp', null);
+                       }
+
                        init();
                });
        };
 
        $.fn.markItUpRemove = function() {
                return this.each(function() {
-                               var $$ = $(this).unbind().removeClass('markItUpEditor');
-                               $$.parent('div').parent('div.markItUp').parent('div').replaceWith($$);
+                               $(this).markItUp('remove');
                        }
                );
        };
                        $('textarea').trigger('insertion', [options]);
                }
        };
-
+       
 })(jQuery);