1

Topic: If you have troubles placing the cursor after the last table...

If you have problems placing cursor after a table at the very end of the document, create this plugin and add it to the configuration.

TinyMCE expects two files: editor_plugin_src.js and editor_plugin.js.

The first is the source code in "readable" format, the second is expected to be the first with all whitespaces and comments stripped out.
If you don't like to "compress" the file too often (just as I do), you may just create a symbolic link or copy *_src.js to *.js.

tinyMCE.init({
  plugins : "trailing",
});

plugins/trailing/editor_plugin_src.js:

/**
 * $Id$
 *
 * Add trailing element while editing, to enable placing the cursor at the end of the body.
 *
 * The original code and idea comes from EditorEnhancements plugin by tan@enonic.com
 * https://sourceforge.net/tracker/index.php?func=detail&aid=2005530&group_id=103281&atid=738747
 * http://www.enonic.com
 *
 * Author: Mariusz P?kala (Arsen7) <skoot@qi.pl>
 */
(function() {
        tinymce.create('tinymce.plugins.Trailing', {
                init : function(ed, url) {
                        var t = this;
                        ed.onSetContent.add( function(ed,o) {
                                t._insertTrailingElement(ed);
                        });
                        ed.onNodeChange.add( function(ed, cm, e) {
                                t._insertTrailingElement(ed);
                        });
                        ed.onBeforeGetContent.add( function(ed, o) {
                                t._removeTrailingElement(ed);
                        });
                },

                getInfo : function() {
                        return {
                                longname : 'Trailing Element Fix (based on EditorEnhancements by tan@enonic.com)',
                                author : 'm.pekala@idelfi.com',
                                authorurl : 'http://idelfi.com',
                                infourl : 'http://idelfi.com/tiny_mce/trailing_plugin.html',
                                version : '1.0'
                        };
                },

                /* Private methods */

                _insertTrailingElement : function(ed) {
                        var body = ed.getBody();
                        var lc = body && body.lastChild;
                        var fc = body && body.firstChild;

                        if(!body || !lc || !fc)
                                return;
                        try {
                                if( lc.nodeType == 1 && lc.nodeName.toLowerCase() != 'p' && (!lc.innerHTML.match(/^(\s|<br\s*\/?>| )*$/i) || !lc.firstChild) ) {
                                        body.appendChild( ed.dom.create('p',{},'<br/>') );
                                }
                                if( fc.nodeType == 1 && fc.nodeName.toLowerCase() != 'p' && (!fc.innerHTML.match(/^(\s|<br\s*\/?>| )*$/i) || !fc.firstChild) ) {
                                        body.insertBefore( ed.dom.create('p',{},'<br/>') , fc);
                                }
                        } catch(err) {
                                if( typeof(console) == 'object' && console.error )
                                        console.error("TrailingPlugin._insertTrailingElement (ignored) : " + err);
                        }
                },

                _removeTrailingElement : function(ed) {
                        var body = ed.getBody();
                        if(!body)
                                return;
                        var last, limit_l = 1, first, limit_f = 1;
                        try {
                                while( (last = body.lastChild) && last.nodeType == 1 && last.nodeName.toLowerCase() == 'p' &&
                                                last.innerHTML.match(/^(\s|<br\s*\/?>| )*$/i) ) {
                                        body.removeChild(last);
                                        if(limit_l-- < 1)
                                                break;
                                }
                                while( (first = body.firstChild) && first.nodeType == 1 && first.nodeName.toLowerCase() == 'p' &&
                                                first.innerHTML.match(/^(\s|<br\s*\/?>| )*$/i) ) {
                                        body.removeChild(first);
                                        if(limit_f-- < 1)
                                                break;
                                }
                        } catch(err) {
                                if( typeof(console) == 'object' && console.error )
                                        console.error("TrailingPlugin._removeTrailingElement (ignored) : " + err);
                        }
                }
        });

        tinymce.PluginManager.add('trailing', tinymce.plugins.Trailing);
})();

// vim: ts=8 sw=8 sts=8 expandtab

Last edited by Arsen7 (2009-06-16 11:03:18)

2

Re: If you have troubles placing the cursor after the last table...

Hi Arsen

Great to see that you developed the code further wink
You should post it as a plug in on SourceForge

tan

3

Re: If you have troubles placing the cursor after the last table...

Maybe you should add a test for any attributes on the <br>
I think I have seen that in Gecko sometimes

and a case sensitive flag, just in case

Suggestion:

^(\s|<br.*?\s*\/?>| )*$/i

regards tan

Last edited by tan (2009-06-11 20:35:22)

4

Re: If you have troubles placing the cursor after the last table...

Hi tan!
Thanks for your plugin, it saved me some work, some time ago wink

I have corrected the regexen with case-insensitivity flag, as you suggested.
Yeah, I develop for some specific application, and it's really easy to forget that others may need to edit not-so-cleaned-code wink

About sourceforge: Maybe it would be better to keep the code in your plugin?
Hmm.. I see the URL I have put in the header is no longer accessible - SourceForge says "Not found".

And for attributes: You say, the BR tag should also be removed if it has any attribute? I am not sure about this. If the attribute has been added automagically by the editor (TinyMCE or that 'editor mode'), than yes - such tag should be removed.
But if it was the user, who added some attribute, then this tag can no longer be considered 'empty', neither can be recognized as 'the one I have just inserted here'.

The Right-Thing-To-Do is to check whether some attributes are automagically added by the editor.

Last edited by Arsen7 (2009-06-18 19:54:17)

5

Re: If you have troubles placing the cursor after the last table...

Hi all,

pls I need help.. how can I run this plugin? I try almost everything and no success.

Examples of my codes:

tinyMCE.init({
...
extended_valid_elements : "div[class|style],iframe[name|width|height|frameborder|scrolling|marginheight|marginwidth|src|id|style|align],br,object[type|data|align|width|height],param[name|value|allowscriptaccess|allowfullscreen],embed[src|type|wmode|width|height],script[type|src]",
    plugins : "table,trailing",

and the source code of plugin is in ./plugins/trailing/editor_plugin_src.js and editor_plugin.js.

I don't know where is problem.

Thx a lot

6

Re: If you have troubles placing the cursor after the last table...

Hard to say - your configuration looks OK.
Are the files readable for your browser? If you type http://...../tiny_mce/plugins/trailing/editor_plugin.js then can you see the code?

I assume there are some other plugins in your ./plugins/ directory, right? Is your TinyMCE in version 3.x ?

7

Re: If you have troubles placing the cursor after the last table...

Arsen7 wrote:

Hard to say - your configuration looks OK.
Are the files readable for your browser? If you type http://...../tiny_mce/plugins/trailing/editor_plugin.js then can you see the code?

I assume there are some other plugins in your ./plugins/ directory, right? Is your TinyMCE in version 3.x ?

Yes, if I type exact URL of javascript file, I see the code..

If you want to see all plugins what I have, so they are folders:
advhr
advimage
advlink
autosave
bbcode
compat2x
contextmenu
directionality
emotions
example
fullpage
fullscreen
iespell
inlinepopups
insertdatetime
layer
media
nonbreaking
noneditable
pagebreak
paste
preview
print
safari
save
searchreplace
spellchecker
style
table
template
TRAILING
visualchars
xhtmlxtras

Version of my TinyMCE is 3.2.1.1 (2008-11-27). It's not the newest, but not the oldies..

By the way, I use this TinyMCE in own CMS.

Thanks for any advice :-)

P.S. : I'm Czech so I'm sorry for my english :-)

8

Re: If you have troubles placing the cursor after the last table...

I see you have TRAILING in upper-case. Since you said that when you type the URL by hand, the file can be seen, I guess it's not a problem. Anyway it looks suspiciously.

Time to debug.

If you don't have Firebug plugin (in case you are using Firefox browser) then put some alert("I am here!") statements in the code, to ensure it is, or is not, executing.
Place the first alert in the init function [ alert("I am in init()"); ], the second and third just before and after "tinymce.PluginManager.add..." statement [ alert("I am before registering plugin"); ... alert("I have just registered the plugin") ]

Having these popups you will be sure the plugin is initialized. The second step would be to ensure it's handlers are called (place some alerts in _insertTrailingElement and _remove... functions).

The main problem is that "it works for me" wink, so we have to find out what significant difference on your side is causing problems.

I work only on Firefox, and I usually use plain DOM functions, so it's possible that I slipped some browser specific bugs (however this code snippet is so small, and simple... )

9

Re: If you have troubles placing the cursor after the last table...

also, when using firebug, click the net tab and look after any 404 - not found(red lines).

10

Re: If you have troubles placing the cursor after the last table...

Hi

I just wanted to say that the plug in is now added to SourceForge

https://sourceforge.net/tracker/?func=d … tid=738747

11

Re: If you have troubles placing the cursor after the last table...

I know this post is old but is still very useful. Thanks so much for this!

I contributed by posting a short step by step guide on how to add it to WordPress:

http://wordpress.org/support/topic/wysiwyg-14?replies=2#post-2705058