Implemented Redactor Jquery editor instead of Tinymce

This suggestion has been implemented. Votes are no longer accepted.
Woah woah woah. As a consumer it's not my job to consider all the implications of my outrageous requests. Geez.
But you have to live with the fact that others will say their opinion about your request. This is a discussion forum after all, is it not? Geez.

And it indeed would be a nightmare to code addons that need tying into the editor (an additional button, for example) for a whole bunch of different editors.
 
Well, I've bought Redactor to try it's functions and API. It's fast & light (good for mobiles), easy to configure but the editor doesn't provide a multiline configuration for buttons. It can only have one line. I've contacted the support to see if it was a function they planned to add. They didn't reply me directly to that question, but told me there is a css workaround (still 1 line but will continue on another line if space is not enough) or recommended me to use less buttons...

If TinyMCE must be replaced, may be CK Editor would be better then.
 
I've just added a "real" (certainly not perfect but better than only a css workout) multiline buttons mode to Redactor. Since it's using jQuery it reminds me a lot MarkItUp and the solution is quite similar, except it's easier because Redactor js/css code is well structured.

multi_lines.webp
To do it,

In the Javascript
Step 1
Search:
Code:
            $.each(this.opts.buttons, $.proxy(function(i,key)
            {
 
                if (key !== '|' && typeof this.opts.toolbar[key] !== 'undefined')
                {
                    var s = this.opts.toolbar[key];
 
                    if (this.opts.fileUpload === false && key === 'file')
                    {
                        return true;
                    }
 
                    this.$toolbar.append($('<li>').append(this.buildButton(key, s)));
                }
 
 
                if (key === '|')
                {
                    this.$toolbar.append($('<li class="redactor_separator"></li>'));
                }
 
            }, this));

Replace (last modification: 2013/04/02):
Code:
            var $line = {}, line = 1, n = (this.opts.buttons.length - 1);
            $line[line] = $('<ul>').addClass('redactor_tmp');
     
            $.each(this.opts.buttons, $.proxy(function(i,key)
            {
                if (key !== '|' && key !== '#'  && typeof this.opts.toolbar[key] !== 'undefined')
                {
                    var s = this.opts.toolbar[key];
 
                    if (this.opts.fileUpload === false && key === 'file')
                    {
                        return true;
                    }
 
                    $line[line].append($('<li>').append(this.buildButton(key, s)));
                }
 
                if (key === '|')
                {
                    $line[line].append($('<li class="redactor_separator"></li>'));
                }
 
                if (key === '#' || i === n)
                {
                    this.$toolbar.append($line[line]);
                    line++;
                    $line[line] = $('<ul>').addClass('redactor_tmp');
                }
 
            }, this));
 
            this.$toolbar.find('.redactor_tmp')
                .removeAttr('class')
                .wrap('<li class="redactor_line" />')
                .end()
                .children('.redactor_line').each(function(index) {
                    $(this).addClass('redactor_line_'+(index+1));
                    //$(this).css('z-index', 99 - index);
                });

Step 2
Search:
Code:
                var left = this.getBtn(key).offset().left;
 
                if (this.opts.air)
                {
                    var air_top = this.air.offset().top;
 
                    $(dropdown).css({ position: 'absolute', left: left + 'px', top: air_top+30 + 'px' }).show();
                }
                else if (this.opts.fixed && this.fixed)
                {
                    $(dropdown).css({ position: 'fixed', left: left + 'px', top: '30px' }).show();
                }
                else
                {
                    var top = this.$toolbar.offset().top + 30;
                    $(dropdown).css({ position: 'absolute', left: left + 'px', top: top + 'px' }).show();
                }

Replace (last modification: 2013/04/02):
Code:
                var left = this.getBtn(key).offset().left,
                defaultTop = 30 + (this.getBtn(key).parents('.redactor_line').offset().top - this.$toolbar.find('.redactor_line_1').offset().top);
 
                if (this.opts.air)
                {
                    var air_top = this.air.offset().top;
 
                    $(dropdown).css({ position: 'absolute', left: left + 'px', top: air_top+defaultTop + 'px' }).show();
                }
                else if (this.opts.fixed && this.fixed)
                {
                    $(dropdown).css({ position: 'fixed', left: left + 'px', top: defaultTop + 'px' }).show();
                }
                else
                {
                    var top = this.$toolbar.offset().top + defaultTop;
                    $(dropdown).css({ position: 'absolute', left: left + 'px', top: top + 'px' }).show();
                }

In the Css:
Step 1
Search:
Code:
.redactor_toolbar li {

Replace with:
Code:
.redactor_toolbar .redactor_line li {

Step 2
Create:
Code:
.redactor_toolbar .redactor_line {
    height:34px;
}

Step 3
In this css ".redactor_toolbar", delete:
Code:
height: 32px !important;

Step 4 (Edit 2013/04/01)
Search:
Code:
.redactor_toolbar li.redactor_btn_right {
    float: none;
    float: right !important;
}

Replace with:
Code:
.redactor_toolbar li.redactor_btn_right {
    position: absolute;
    top: 1px;
    right: 1px;
    float: none;
    float: right !important;
}

Step 5 (Edit 2013/04/02)
Change the z-index of ".redactor_dropdown" to 10000


That's all. Then to configure new lines, it's super easy (perfect for a buttons manager):
newlines.webp
 
Well, I've bought Redactor to try it's functions and API. It's fast & light (good for mobiles), easy to configure but the editor doesn't provide a multiline configuration for buttons. It can only have one line. I've contacted the support to see if it was a function they planned to add. They didn't reply me directly to that question, but told me there is a css workaround (still 1 line but will continue on another line if space is not enough) or recommended me to use less buttons...

If TinyMCE must be replaced, may be CK Editor would be better then.
Thanks for this excellent analysis.
 
I've just tested the Redactor Fullscreen plugin and it needs to be slightly updated to be compatible with XenForo and to avoid a bug.

In the Css:
Create a new class
HTML:
.redactor_toolbar_fullscreen {
    overflow: hidden !important;
}

In the plugin Javascript Code:
Step 1
Search:
Code:
            $('body, html').css('overflow', 'hidden');
Replace with:
Code:
            $('body, html').addClass('redactor_toolbar_fullscreen');


Step 2
Search:
Code:
            $('body, html').css('overflow', '');
Replace with:
Code:
            $('body, html').removeClass('redactor_toolbar_fullscreen');

Step 3
Important => will avoid a js error if no padding is defined
Search
Code:
      var pad = this.$editor.css('padding-top').replace('px', '');

Replace with
Code:
        var pad = parseInt(this.$editor.css('padding-top'));

Step 4
Search
Code:
        var height = $(window).height() - 34;

Add below
Code:
        var toolbar = this.$toolbar.height();
        this.$content.height(height-toolbar);



Edit: Oups... Forgot some steps and bugs too
Step 5
Search
Code:
            this.fsheight = this.$editor.height();

Add below
Code:
            this.fcheight = this.$content.height();

Step 6
Search
Code:
                this.$editor.css('height', 'auto');

Add below
Code:
                this.$content.css('height', 'auto');//Need to be check for autoresize

Step 7
Search
Code:
            this.fsheight = this.$editor.height();

Add below
Code:
                this.$content.css('height', this.fcheight);

Step 8
Search the last:
Code:
            this.$editor.focus();

Add below
Code:
            $('html, body').animate({ scrollTop: this.$box.offset().top }, 500, 'easeInOutCubic');


Now there is a bug when the IFRAME mode is activated: the content is not copied when the editor window is toggled. To fix this, there's a last step and the original redactor Javascript file must be modified. I'm not sure if the following modifications are the best ones but they work.


Step 9
Search:
Code:
    },
    fullScreenResize: function()
    {

Add above:
Code:
        this.setCode(this.getCode());


In the original Redactor JS file:
Search:
Code:
        setCode: function(html)
        {
            html = this.stripTags(html);
            this.$editor.html(html).focus();
 
            this.syncCode();
        },

Replace:
Code:
        setCode: function(html)
        {
            html = this.stripTags(html);
            this.$editor.html(html).focus();
 
            this.syncCode();
 
            if(this.opts.iframe === true)
            {
                var t = this;
                setTimeout(function ()
                    { t.$content.contents().find('body').html(html) }, 600
                );
            }         
        },
 
@KAM

For you consideration, I would suggest and recommend that you hire cclaerhout should you feel the need to hire more developers. If only because he's been able to spit out editors as add-ons (5 I think). Which I understand is no easy task and yet he does it with so much ease.

Just an option and thought.
 
The jokes day was three days ago :rolleyes: It's not hard to guess that the priority of XenForo founders is going to wait to strengthen their company so they can earn their life with it, then it should be nice they start to pay their moderators. Once this done, like any successful sme they might need to focus to target and develop foreign markets or may be to target companies (in a clever way than IB tried to do). So there's no need to hire any developer, unless if they find a good one that accepts to work for free nights and days in a cellar to develop a portal. Of course, if XenForo is really rich, I accept to do coffee and copies for them so I can spy them and write a book after.

Now for the above customization of Redactor, it's just to try to get ready when XenForo will change their editor because learning how works an editor takes time. Anyone who knows conditionals&loops and takes time to read php/jquery/scripts documentation is able to do what I did. Again, I'm not a professional developer.

Now to come back to the subject, Redactor integration might take more time since the new version of Redactor has been delayed (read here). They want to totally rewrite their script. The above modifications have been submitted to them by email and I've been said they are going soon to integrate a bug tracker to their website.
 
The jokes day was three days ago :rolleyes: It's not hard to guess that the priority of XenForo founders is going to wait to strengthen their company so they can earn their life with it, then it should be nice they start to pay their moderators. Once this done, like any successful sme they might need to focus to target and develop foreign markets or may be to target companies (in a clever way than IB tried to do). So there's no need to hire any developer, unless if they find a good one that accepts to work for free nights and days in a cellar to develop a portal. Of course, if XenForo is really rich, I accept to do coffee and copies for them so I can spy them and write a book after.

Now for the above customization of Redactor, it's just to try to get ready when XenForo will change their editor because learning how works an editor takes time. Anyone who knows conditionals&loops and takes time to read php/jquery/scripts documentation is able to do what I did. Again, I'm not a professional developer.

Now to come back to the subject, Redactor integration might take more time since the new version of Redactor has been delayed (read here). They want to totally rewrite their script. The above modifications have been submitted to them by email and I've been said they are going soon to integrate a bug tracker to their website.
XenForo.... Such a judgmental community. lol :p

Please take credit where credit is due and please learn to take a complement from someone who admires the work you do. :)
 
For those who would like to test, I've put a part of the integration on Github without including the redactor JS and CSS files* (the above mods for the JS file must still be done manually).
What's new:
  • New buttons with plugins: remove format, redo, undo, RTE/BbCode editor toggledemo.webp
* It seems the old version of Redactor license is under Creative Commons Attribution-NonCommercial 3.0 but the new version is a private license and can't be shared even for a non-commercial usage.
 
Some Redactor style functions don't work with the XenForo html=>bbcode parser:
1) Color to fix this go to the Redactor JS file
Search:
Code:
                    if (_self.browser('msie') && mode === 'BackColor')
                    {
                        _self.$editor.find('font').replaceWith(function() {
 
                            return $('<span style="' + $(this).attr('style') + '">' + $(this).html() + '</span>');
 
                        });
                    }
Add below:
Code:
                    _self.syncCode();
It might be fixed directly from the XenForo parser but this one would not be easy.

2) Strike edit XenForo_Html_Renderer_BbCode
Search:
PHP:
      's'          => array('wrap' => '[S]%s[/S]'),

Add below:
PHP:
        'strike'      => array('wrap' => '[S]%s[/S]'),
 
There is a very annoying bug with Redactor & caret position on autofocus, to correct this:
In the main JS file,

Find:
Code:
                // enable
                if (this.$editor)
                {
                    this.$editor.html(html);
                }

Replace:
Code:
                // enable
                if (this.$editor)
                {
                    this.$editor.html(html);
                    var node = this.$content.children(":first").get(0);
                    this.setSelection(node, 0, node, 0);
                }

It seems it's working fine after that (blank editor or edit). This setSelection command can in fact be used to position the caret.
 
Version 0.05 released on Github
  • Color buttons (font-color & background-color) and functions have been rewritten
  • The TinyMCE color picker has been ported to jQuery & Redactor (the Redactor "Color Picker" was not enough good... and the css was buggy)
  • The Redactor "none" (color) functions have been disabled (too "buggy" => it's really hard to get nodes and to manipulate them ; TinyMCE was may be too much complicated but it was working quite nice)
 

Attachments

  • demo1.webp
    demo1.webp
    11.2 KB · Views: 36
  • demo2.webp
    demo2.webp
    22.7 KB · Views: 37
  • demo3.webp
    demo3.webp
    20.2 KB · Views: 35
Top Bottom