内联问题将自定义style_format添加到tinymce

时间:2011-04-01 13:35:29

标签: css tinymce inline

我正在尝试在样式菜单中添加自定义样式。

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></code>

还尝试了:{title : 'Codigo fuente', block : 'code', classes : 'prettyprint', exact: true} 我得到相同的结果,但没有空格或\n

如果你想查看why我正在问这个

谢谢!

2 个答案:

答案 0 :(得分:2)

嗯,我只有部分答案,但它仍然可能对你有所帮助。从我收集的内容来看,您希望能够将一些代码键入或粘贴到tinyMCE文本区域(而不是编辑器字段的原始html代码),然后将一些样式应用于该块,因此它将是美化。

(作为旁注,我认为任何有资格在富文本编辑器字段中添加代码块的人都应该能够按下“原始html”按钮,粘贴他的代码并将其包装到<pre>或者<code>标签。特别是如果你在编辑区域的上方或下方添加了一些关于该做什么的指令。那么你就可以免费回家了。每个人都这样做。)

尽管如此,回到最初的问题。如果您在tinyMCE textarea中输入代码行,则在每次输入时,您都会将您的行包装成<p>标记。

所以如果你输入:

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

然后按回车键,你就会得到

<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>

我们得到答案(即使答案只有答案的一半),所以不要放弃。

最好的方法是在代码块周围使用<div>包装器。这是合法的,tinyMCE很乐意为你做,请看下面(注意包装属性!):

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

我们现在可以开始庆祝了,但是您选择的插件(代码解码器)只处理来自html的<pre><code>标记,所以不幸的是这些<div>包装的代码块不会很漂亮哦,太漂亮......

你可以a)入侵美化插件并强制它吞下具有某些类的div标签或b)强制tinyMCE忘记这些<p>包装。

现在,使用第二个选项,您可以使用以下参数初始化tinyMCE:

forced_root_block : false,
force_br_newlines : true,
force_p_newlines : false

并且您可以使用<br>标记分隔您的行,而不是将其包含在<p>标记中。由于各种原因(参考FAQ),tinyMCE的作者强烈反对这一点,但它仍然是一个有效的选择。

现在你可以欺骗tinyMCE将整个内容包装到一个<code>块中,具有以下配置(这本身就是一些黑客攻击,但主要是有效的):

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

应用此样式的唯一问题是从文本选择中删除现有的<br>标记。没错,您可以将所有选定的代码压缩成一行。我尝试了许多方法来保留这些微小的悲惨的<br>标签,但是不能追求tinyMCE这样做。这是我放弃的地方,因此是“半答案”。祝你好运!

答案 1 :(得分:2)

我一直在打开和关闭这几天,仍然无法获得完全可行的解决方案。我认为它很接近,但我没有时间花在它上面了。它似乎也相当hacky,所以我不得不问是否有更简单的方法来做到这一点,也就是说,它真的需要TinyMCE吗?可能更容易使用<textarea>prettify

我还从其他问题中使用了一些建议:Remove styles when pasting from Word or other source

我正在尝试的想法是在代码被“美化”时操纵TinyMCE内容,以便在原始文本而不是美化版本上进行编辑。所以我已经迷上了TinyMCE onchangeonKeyDown回调,将内容切换回 unstty 版本。唯一的问题是第一个按键不能注册,因为它被替换内容的行为吞没了。有一种方法可以Programmatically sending keys to input field?,但Webkit不支持它。

此外,似乎存在一些错误,因为如果代码直接输入到TinyMCE中,它仍会添加多个<code>元素。但是,粘贴代码然后编辑似乎工作正常。 因此,如果您键入代码然后应用“源代码”样式。所有的回车都被删除了(可能与@András确定的问题相同)。

所以这是我的部分解决方案:

<!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; } }
</pre>
</body>
</html>

注意:您需要下载TinyMCE并进行美化,并确保.js.css资源的路径正确无误。

希望它有所帮助!