web-dev-qa-db-fra.com

Préservation des tabulations et des sauts de ligne dans <pre> <code> lors du passage de HTML à Visual Editor

Les onglets placés dans un bloc <pre><code></code></pre> sont supprimés et les sauts de ligne sont supprimés pour ne laisser qu'une seule ligne de texte continue. Cela se produit lorsque vous passez du code HTML aux éditeurs visuels. Existe-t-il un paramètre dans TinyMCE pour éviter cela?

AVANT:

enter image description here

APRÈS: enter image description here

Ici, il gâche même le code et en crache une partie du <pre>...

EDIT:

Il semble que la meilleure option consiste à supprimer complètement la balise <code> et à laisser le pré. Cela pose toujours le problème de la suppression des lignes vierges en double, mais cela garde le pré intact, même lors du passage d’un éditeur à l’autre.

1
Aram Kocharyan

Ajouter à function.php

add_filter('tiny_mce_before_init', 'tiny_mce_before_init');

Et la fonction tiny_mce_before_init:

function tiny_mce_before_init($init) {
 $init['setup'] = "function(ed) {
     ed.onBeforeSetContent.add(function(ed, o) {
     if ( o.content.indexOf('<pre') != -1) {
     o.content = o.content.replace(/<pre[^>]*>[\\s\\S]+?<\\/pre>/g, function(a) {
     return a.replace(/(\\r\\n|\\n)/g, '<br />');
    });
   }
  });
 }";
 return $init;
}

http://core.trac.wordpress.org/ticket/19666 - c'est un bogue connu, il existe une solution de contournement mais ne corrige pas les onglets mais uniquement les nouveaux caractères de ligne

3
OzzyCzech

J'ai également ajouté des codes courts personnalisés à functions.php pour éviter que des choses ne se cassent lors du passage du HTML aux éditeurs visuels. J'ai principalement utilisé cela pour iFrame, mais peut-être que ce serait utile ici aussi.

1
Donna

Ce plugin semble préserver l'espace blanc entre les balises <pre>.

Conserver la mise en forme du code

0
Martin York

Pour tous ceux qui luttent avec coller ou travailler avec un code <pre> formaté dans Editeur visuel . Cette solution fonctionne depuis plusieurs années pour moi et je l’adore . Cette approche utilise un "intermédiaire" pour fournir un pré-contenu et des caractères corrects entre les éditeurs et l'interface wpautop().

Il suffit de coller dans functions.php

Cela semble lourd, mais c’est la raison pour laquelle jQuery doit avoir une portée mondiale, car il parle avec l’API tinMCE. Le dollarign $ ne peut PAS être utilisé et le texte jQuery encombrer le code . C'est principalement la création d'éléments HTML qui prend de la place.

Comment ça marche: Assez simple, Sans "le toucher" -TinyMCE ne plaisante pas avec . Ça vaut le coup d'essayer!

/**
 * PRE Handler
 * Solves <pre> handle in Wordpress tinyMCE editor
 * TAB support
 * TAB support to TEXT editor
 * Simple cleanup with Undo
 * Push cleanup (experimental)
 * Moves empty code chunks to beginning
**/


function entex_tiny_mce_before_init(){
    add_filter('tiny_mce_before_init', function($mceInit){
        $mceInit['setup'] = 'ua_TinyMCE_setup_callback';
        return $mceInit;
    });
    add_action('before_wp_tiny_mce', 'entex_TinyMCE_javascript');
}
add_action('after_setup_theme', 'entex_tiny_mce_before_init');


function entex_TinyMCE_javascript() {

    echo '<script type="text/javascript">'."\n";
    ?>

    var ua_tinyMCE_invoked = 0;

    function ua_tinyMCE_focusbutton(){
        if(jQuery('ua-id-mce-focusbutton').get(0)) return;
        var jQueryE = jQuery('<a />').addClass('button ua-id-mce-focusbutton').css('float', 'right').on('click', function(){
            jQuery('html, body').stop().animate({ scrollTop: (jQuery('#wp-content-wrap').offset().top) - 20 }, 500);
            tinymce.activeEditor.focus();
            return false;
        }).attr('title', 'Scroll and focus the editor Toolbar in view').text('Toolbar focus').css('margin', '5px');
        jQuery('.mce-statusbar .mce-flow-layout').prepend(jQueryE);
    }

    function ua_TinyMCE_setup_callback(ed){

        if(ua_tinyMCE_invoked) return;
        ua_tinyMCE_invoked = 1;

        ed.on('init', function(e) {
            jQuery(ed.getBody()).on('click', 'pre', function() {
                ua_TinyMCE_edit_pre(ed, this);
                return false;
            });
            ua_tinyMCE_focusbutton();
        });
    }

    function ua_TinyMCE_helper_cleanBeginnings(str, find, replace){
        return str.replace(new RegExp(find, 'g'), replace);
    }

    function ua_TinyMCE_edit_pre(ed, obj) {
        var jQueryE = jQuery(obj); 
        var jQueryB = jQuery(ed.getBody());
        var content = jQuery('<textarea/>').html(jQueryE.html()).text();
        content = content.replace(/(<br>)/g, '');
        //content = content.replace(/   /g, '\t');
        var data = content;


        var jQueryL = jQuery('<div />').css({
            'position': 'fixed',
            'box-sizing': 'border-box',
            'background-color': 'rgba(255, 255, 255, 0.85',
            'border': '3px solid #ccc',
            'padding': '10px',
            'z-index': '9992',
            'height': 'auto',
            'width': '80%',
            'left': '50%',
            'margin-left': '-40%',
            'top': '5%'
        });

        var jQueryT = jQuery('<textarea />').keydown(function(e){

            if ( e.which != 9 ) return;
            var start = this.selectionStart;
            var end = this.selectionEnd;
            this.value = this.value.substr( 0, start ) + "\t" + this.value.substr( end );
            this.selectionStart = this.selectionEnd = start + 1;
            e.preventDefault();
            return false;

        }).attr('wrap', 'soft').css({
            'height': '98%',
            'width': '88%',
            'min-height': '300px',
            'tab-size': '3',
            'font-family': 'courier new',
            'box-sizing': 'border-box'
        });

        jQuery('#wpcontent').css('position', 'relative').append(jQueryL);
        jQueryL.append(jQueryT);
        jQueryL.append(
            jQuery('<div />').css({
                'width': '10%',
                'height': '100%',
                'position': 'absolute',
                'top': '0px',
                'right': '10px',
                'padding-top': '10px',
                'box-sizing': 'border-box'
            }).append(
                jQuery('<a />').attr('title', 'Send to element').click(function(){

                    var encodedStr = jQueryT.val().replace(/[\u00A0-\u9999<>\&]/gim, function(i) {
                        return '&#'+i.charCodeAt(0)+';';
                    });

                    jQueryE.html(encodedStr);
                    ed.focus();
                    jQueryL.remove();
                    return false;

                }).text('Send').addClass('button button-primary').css({
                    'display': 'block',
                    'width': '100%',
                    'margin-bottom': '5px',
                    'text-align': 'center',
                    'box-sizing': 'border-box'
                }), 

                jQuery('<a />').attr('title', 'Cleanup').click(function(){

                    var data = jQueryT.val();
                    var original = data;
                    data = data.replace(/(\r\n|\n|\r)/gm, "\r\n");
                    var workspace = data.replace(/(\r\n|\n|\r)/gm, '');

                    if(/^\s/.test(workspace)) {
                        var search_string = workspace.replace(/^\s+|\s+$/g, '');
                        if(search_string){
                            var firstChar = search_string[0];
                            var remove = workspace.substr(0, workspace.indexOf(firstChar));
                            remove = "\r\n" + remove;
                            data = ua_TinyMCE_helper_cleanBeginnings(data, remove, "\r\n");
                        }
                        data = data.replace(/   /g, "\t");
                        data = data.replace(/^\s+|\s+$/g, '');
                    } else {
                        data = data.replace(/^\s+|\s+$/g, '');
                    }
                    if(data != original){
                        jQueryT.data('original', original);
                        if(!jQuery('#ua-TinyMCE-btt-undo').get(0)){
                        jQuery(this).after(
                            jQuery('<a />').attr('title', 'Undo').click(function(){
                                jQueryT.val(jQueryT.data('original'));
                                jQuery(this).remove();
                                return false;

                            }).text('Undo').addClass('button').css({
                                'display': 'block',
                                'width': '100%',
                                'margin-bottom': '5px',
                                'text-align': 'center',
                                'box-sizing': 'border-box'
                            }).attr('id', 'ua-TinyMCE-btt-undo')
                        );
                        }
                    }
                    data = data.replace(/   /g, "\t");
                    jQueryT.val(data);
                    return false;

                }).text('Cleanup').addClass('button').css({
                    'display': 'block',
                    'width': '100%',
                    'margin-bottom': '5px',
                    'text-align': 'center',
                    'box-sizing': 'border-box'
                }),

                jQuery('<a />').attr('title', 'Close').click(function(){

                    ed.focus();
                    jQueryL.remove();
                    return false;

                }).text('Close').addClass('button').css({
                    'display': 'block',
                    'width': '100%',
                    'margin-bottom': '5px',
                    'text-align': 'center',
                    'box-sizing': 'border-box'
                }),

                jQuery('<a />').attr('title', 'Remove all data').click(function(){

                    jQueryT.val('').focus();
                    return false;

                }).text('Delete').addClass('button').css({
                    'display': 'block',
                    'width': '100%',
                    'margin-bottom': '0px',
                    'position': 'absolute',
                    'bottom': '10px',
                    'background-color': '#D54E21',
                    'color': '#fff',
                    'text-align': 'center',
                    'box-sizing': 'border-box'
                })
            )
        );
        jQueryT.val(content).focus();
        return false;
    }

    // WP EDITOR
    jQuery(document).ready(function($){
        if($('textarea#content').get(0)){
            $('textarea#content').on('keydown', function(e){
                if ( e.which != 9 ) return;
                var start = this.selectionStart;
                var end = this.selectionEnd;
                this.value = this.value.substr( 0, start ) + "\t" + this.value.substr( end );
                this.selectionStart = this.selectionEnd = start + 1;
                e.preventDefault();
                return false;
            }).css('tab-size', '3');
        }
    });

    <?php
    echo '</script>'."\n";
}

Cette approche n’est pas un hack ni une solution de correspondance approximative. Il produit les mêmes conversions que l'API par défaut.

Le nettoyage Push fonctionne si vous collez un code d'une classe PHP ou autre, et que la fonction de bloc ou de fonction coupée que vous voulez présenter présente beaucoup d'espace ou de tabulations " avant". Il calcule l'espace qui se produit sur la première ligne existante.

Fait ceci:

                    if(search_string){
                        var firstChar = search_string[0];
                        var remove = workspace.substr(0, workspace.indexOf(firstChar));
                        remove = "\r\n" + remove;
                        data = ua_TinyMCE_helper_cleanBeginnings(data, remove, "\r\n");
                    }

Dans ceci:

if(search_string){
    var firstChar = search_string[0];
    var remove = workspace.substr(0, workspace.indexOf(firstChar));
    remove = "\r\n" + remove;
    data = ua_TinyMCE_helper_cleanBeginnings(data, remove, "\r\n");
}

BTW , il est livré avec un bouton de mise au point pratique , apparaît en bas de l'éditeur et est utile lorsque vous travaillez avec une grande quantité de fragments de code <pre>. Désactiver les paramètres d’écran "Activer les fonctionnalités de l'éditeur pleine hauteur et sans distraction." pour une meilleure interface utilisateur.

0
Jonas Lundman