开发者

inline Problem adding custom style_format to tinymce

I'm trying to add a custom style in the style men开发者_开发百科u.

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}
                 ],

Basically i want selected text to turn in:

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

But i get:

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

How can i make to all selection to be inserted in same <code></code> ??

tried also: {title : 'Codigo fuente', block : 'code', classes : 'prettyprint', exact: true} And i get same result but just with no blank spaces or \n

If you want to see why i'm asking this

Thanks!


I've been working on this on and off for a few days and still cannot get a fully working solution. I think it's close but I just don't have any more time to spend on it. It also seems to be rather hacky, so I have to ask if there is not just a more simple way to do this, that is, does it really need TinyMCE? Might be easier to just use a <textarea> and prettify.

I also used a bit of advice from this other question: Remove styles when pasting from Word or other source

The idea I was experimenting with was to manipulate the TinyMCE content if the code was "prettified" so that editing occurs on the raw text rather than the prettified version. So I have hooked into the TinyMCE onchange and onKeyDown callbacks to switch the content back to an unpretty version. The only problem is that the first keypress will not register as it is swallowed by the act of replacing the content. There is a way to Programmatically sending keys to input field? but it is not supported in Webkit!

Also, there seems to be some bugs, as it still adds multiples <code> elements if code is typed directly into the TinyMCE. However, pasting code and then editing seems to work OK. So if you type code and then apply the "Source Code" style. all the carriage returns are removed (probably same issue as @András identified).

So here is my partial solution:

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

Note: You will need to download TinyMCE and prettify and make sure the paths to the .js and .css resources are correct for this to work.

Hope it helps!


Well I only have a partial answer, but it still might help you a bit. From what I gather, you'd like to be able to type or paste some code into the tinyMCE text area (and not the raw html code of the editor field), and then apply some styles to that block afterwards, so it will be prettified.

(As a sidenote, I think anyone who qualifies adding a code block to a richt text editor field, should be able to press the "raw html" button, paste his code, and wrap it into a <pre> or <code> tag. Especially if you add a bit of instruction on what to do, just above or below the editor area. And then you'd be home free. And everyone does it this way.)

Nonetheless, going back to the original problem. If you enter lines of codes into the tinyMCE textarea, upon each enter pressed you'll get your line wrapped into a <p> tag.

So if you type:

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

and press enter, you'll get

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

So, using your example, you would never actually see this

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

but rather this

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

The problem with the latter, that it is not valid HTML, never was, never will be, and tinyMCE rightfully will not produce that code. Reason being <pre> and <code> are inline elements, and <p> being block level element, hence <pre> and <code> can not contain any <p>s.

We're getting to the answer (even if it's only half an answer), so don't give up.

Best approach would be to use <div> wrappers around your code block. This is legal, tinyMCE will happily do it for you, see below (note the wrapper attribute!):

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

We could start celebrating right now, but your chosen plugin, the code prettifier, only processes <pre> and <code> tags from your html, so unfortunately these <div> wrapped code blocks would not be pretty, oh so pretty...

You could a) hack into the prettify plugin and force it to swallow div tags having certain classes or b) force tinyMCE to forget about these <p> wrappers.

For now, going with the second option, you can initialize tinyMCE with the following parameters:

forced_root_block : false,
force_br_newlines : true,
force_p_newlines : false

and with that you'll have your lines separated with <br> tags instead of wrapped in <p> tags. This is highly discouraged by the authors of tinyMCE for various reasons (refer to the FAQ), but it is still a valid option.

Now you can trick tinyMCE to wrap the whole content into a <code> block, with the following configuration (which is a bit of hack in itself, but works, ahemm mostly):

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

Your only problem that applying this style will strip the existing <br> tags from within your text selection. That's right, you'll have all your selected code compressed into one line. And I tried many ways to keep these tiny little miserable <br> tags, but could not pursuade tinyMCE to do so. This is where I gave up, hence the "half answer". Good luck!

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜