встроенная проблема добавления пользовательского style_format к tinymce - PullRequest
4 голосов
/ 01 апреля 2011

Я пытаюсь добавить собственный стиль в меню стилей.

style_formats : [
                {title:'Estilos'},
                    {title : 'Bold text', inline : 'b'},
                    {title : 'Blue text', inline : 'span', styles : {color : '#006'}},
                    {title : 'Blue header', block : 'h1', styles : {color : '#006'}},
   /*this one*/     {title : 'Codigo fuente', inline : 'code', classes : 'prettyprint', exact: true}
                 ],

В основном я хочу, чтобы выбранный текст превращался в:

<code class="prettyprint"> 
 codeline1
 codeline2
 codeline3 
</code>

Но я получаю:

<code class="prettyprint"> codeline1</code>
<code class="prettyprint"> codeline2</code>
<code class="prettyprint"> codeline3 </code>

Как мне сделать, чтобы весь выбор был вставлен в тот же <code> ??

пробовал также: {title : 'Codigo fuente', block : 'code', classes : 'prettyprint', exact: true} И я получаю тот же результат, но без пробелов или \n

Если вы хотите увидеть почему я спрашиваю это

Спасибо!

Ответы [ 2 ]

2 голосов
/ 20 апреля 2011

Я работал над этим в течение нескольких дней, но до сих пор не могу получить полностью рабочее решение. Я думаю, что это близко, но у меня просто нет больше времени на это тратить. Это также кажется довольно хакерским, поэтому я должен спросить, есть ли не просто более простой способ сделать это, то есть действительно ли ему нужен TinyMCE ? Может быть проще просто использовать <textarea> и prettify .

Я также использовал несколько советов по этому другому вопросу: Удаление стилей при вставке из Word или другого источника

Идея, с которой я экспериментировал, состояла в том, чтобы манипулировать контентом TinyMCE, если код был «предварительно сертифицирован», так что редактирование происходит на необработанном тексте, а не на предварительно оптимизированной версии. Поэтому я подключился к обратным вызовам TinyMCE onchange и onKeyDown, чтобы переключить содержимое обратно на unpretty версию. Единственная проблема состоит в том, что первое нажатие клавиши не будет зарегистрировано, поскольку оно поглощено действием замены контента. Есть способ Программно отправить ключи в поле ввода? , но он не поддерживается в Webkit!

Кроме того, кажется, что есть некоторые ошибки, поскольку он все еще добавляет кратные элементы <code>, если код вводится непосредственно в TinyMCE. Тем не менее, вставка кода и последующее редактирование работают нормально. Так что если вы набираете код, а затем применяете стиль «Исходный код». все возвраты каретки удалены (вероятно, такая же проблема, как и у @ András).

Итак, вот мое частичное решение:

<code><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Title</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <style type="text/css">
        pre {
            width:500px;
        }

        code {
            white-space:pre;
            line-height:1;
            margin:0;
            padding:0;
        }

        #pretty {
            display:block;
        }
    </style>
    <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js"></script>
    <script type="text/javascript" src="tiny_mce/tiny_mce.js"></script>
    <link type="text/css" rel="stylesheet" href="prettify/prettify.css" />
    <script type="text/javascript" src="prettify/prettify.js"></script> <!-- from http://code.google.com/p/google-code-prettify/ -->
    <script type="text/javascript">
        var plainContent = null;

        function applyPrettyPrint(inst) {
            if (tinyMCE.activeEditor.isDirty()) {
                var content = tinyMCE.activeEditor.getContent({format : 'raw'});
                if (content.indexOf('prettyprint') > 0) {
                    $('#pretty').html(content);
                    prettyPrint();
                    tinyMCE.activeEditor.setContent($('#pretty').html(), {format : 'raw'});
                } else {
                    plainContent = content;
                }
           }
        }

        tinyMCE.init({
            // General options
            mode:'textareas',
            theme:'advanced',
            forced_root_block:false,
            force_br_newlines:true,
            force_p_newlines:false,
            content_css:'prettify/prettify.css',
            // http://tinymce.moxiecode.com/wiki.php/Plugin:paste
            plugins:'paste',
            onchange_callback:'applyPrettyPrint',
            setup:function(ed) {
                ed.onKeyDown.add(function(ed, e) {
                    if (ed.getContent().indexOf('prettyprint') > 0) {
                        ed.setContent(plainContent, {format : 'raw'});
                    }
                });
            },
            style_formats:[
                {title : 'Source Code', block : 'code', classes : 'prettyprint', exact: true}
            ]
        });
    </script>
</head>
<body>
    <form method="post" action="somepage">
        <div><textarea name="content" cols="50" rows="15"></textarea></div>
    </form>
    <p id="pretty" ></p>
    <p>Plain code to copy inside textarea</p>
    <pre>
class Foo {
    private int bar = 0;
    public doSomething() {
        return bar;
    }
}

class Foo { private int bar = 0; public doSomething() { return bar; } }

Примечание: Вам нужно будет загрузить TinyMCE, предварительно откорректировать и убедиться, что пути к ресурсам .js и .css указаны правильно, чтобы это работало.

Надеюсь, это поможет!

2 голосов
/ 16 апреля 2011

Ну, у меня есть только частичный ответ, но он все еще может вам помочь. Исходя из того, что я понял, вы хотели бы иметь возможность набирать или вставлять некоторый код в текстовую область tinyMCE (а не необработанный HTML-код поля редактора), а затем применять некоторые стили к этому блоку, так что это будет prettified.

(Как примечание, я думаю, что любой, кто квалифицирует добавление блока кода в поле текстового редактора richt, должен иметь возможность нажать кнопку «raw html», вставить свой код и обернуть его в <pre> или * Тег 1004 *. Особенно, если вы добавите немного инструкций о том, что делать, чуть выше или ниже области редактора. И тогда вы будете свободны дома. И все так поступают.)

Тем не менее, возвращаясь к исходной проблеме. Если вы вводите строки кодов в текстовую область tinyMCE, то при каждом нажатии вы вводите свою строку в тег <p>.

Так что если вы наберете:

if (this_is_the_best_line_ever == true) { ... }

и нажмите Enter, вы получите

<p>if (this_is_the_best_line_ever == true) { ... }</p>

Итак, используя ваш пример, вы бы никогда не увидели это

<code class="prettyprint"> 
 codeline1
 codeline2
 codeline3 
</code>

а точнее это

<code class="prettyprint"> 
  <p>codeline1</p>
  <p>codeline2</p>
  <p>codeline3</p> 
</code>

Проблема с последним в том, что это недействительный HTML, никогда не было, никогда не будет, и tinyMCE по праву не будет генерировать этот код. Причина в том, что <pre> и <code> являются встроенными элементами, а <p> является элементом блочного уровня, поэтому <pre> и <code> не могут содержать <p> s.

Мы подходим к ответу (даже если это только половина ответа), поэтому не сдавайтесь.

Лучшим подходом было бы использовать <div> обертки вокруг вашего блока кода. Это законно, tinyMCE с радостью сделает это за вас, см. Ниже (обратите внимание на атрибут обертки!):

style_formats : [
  {title : 'Codigo fuente', block : 'div', classes : 'prettyprint', wrapper: 1}
]

Мы могли бы начать праздновать прямо сейчас, но выбранный вами плагин, префтификатор кода, обрабатывает только теги <pre> и <code> из вашего html, так что, к сожалению, эти <div> обернутые блоки кода не будут красивыми, о, так красиво ...

Вы можете а) взломать плагин prettify и заставить его проглотить теги div, имеющие определенные классы, или б) заставить tinyMCE забыть об этих <p> оболочках.

Пока, перейдя ко второму варианту, вы можете инициализировать tinyMCE со следующими параметрами:

forced_root_block : false,
force_br_newlines : true,
force_p_newlines : false

и с этим ваши строки будут разделены тегами <br> вместо обернутых тегами <p>. Это очень не одобряется авторами tinyMCE по разным причинам (см. FAQ ), но это все еще допустимый вариант.

Теперь вы можете обмануть tinyMCE, чтобы обернуть весь контент в блок <code>, со следующей конфигурацией (что само по себе немного взломано, но в основном работает, ахмм):

style_formats : [
  {title : 'Codigo fuente', block : 'code', classes : 'prettyprint', wrapper: 1}
]

Ваша единственная проблема в том, что применение этого стиля лишит существующие теги <br> из выделенного вами текста. Все верно, у вас будет весь выбранный вами код, сжатый в одну строку. И я попробовал много способов сохранить эти крошечные жалкие <br> теги, но не смог уговорить tinyMCE сделать это. Вот где я сдался, отсюда и «полуответ». Удачи!

...