Redactor editor text format issues with Chrome version 58

All we need is an easy explanation of the problem, so here it is.

We’re using Redactor(https://imperavi.com/redactor/) version 10.1.1 and not migrated to Redactor II due to lot of dependencies on project.

Recently We’re facing a very weird issue with Chrome version 58. Issues are:

— Not able to format bold, italic, underline, sup, sub etc. for selected text

Kindly let us know is there any fix for this. Any kind of help would be greatly appreciated.

Update as per accepted work around solution:

// Provided solution is tested for Redactor version 10.1.1
createMarkers: function()
{
    this.selection.get();

    var node1 = this.selection.getMarker(1);

    this.selection.setMarker(this.range, node1, true);

    if (this.range.collapsed === false) {
        var node2 = this.selection.getMarker(2);
        this.selection.setMarker(this.range, node2, false);

        // Fix for Chrome58 Issues
        if (this.utils.browser('chrome')) {
              this.caret.set(node1, 0, node2, 0);
         }
         // End Chrome58 Issues
    }

    this.savedSel = this.$editor.html();
},

How to solve :

I know you bored from this bug, So we are here to help you! Take a deep breath and look at the explanation of your problem. We have many solutions to this problem, But we recommend you to use the first method because it is tested & true method that will 100% work for you.

Method 1

I think I may have found the solution: It seems that Chrome 58 (sometimes) resets the selection when we call Range.insertNode.

The solution I suggest is to restore the selection when the Redactor adds the selection markers: In the createMarkers function, right after setting the node2 marker, you can add this function call:
this.caret.set(node1, 0, node2, 0);

Here’s the solution that should fix Redactor for concrete5 (but it should also work for other projects too).

Method 2

instead of this in 10.2.5 version

Overall you can do like that:
rewrite setMarker function:

   setMarker: function (range, node, type) {
          var nclone = window.getSelection().getRangeAt(0).cloneRange();
          range = range.cloneRange();
          try {
            var selection = window.getSelection();
            range.collapse(type);
            range.insertNode(node);

            selection.removeAllRanges();
            selection.addRange(nclone);
          }
          catch (e)
          {
            this.focus.setStart();
          }
        },

or add fix in createMarkers function:
// Provided solution is tested for Redactor version 10.1.1

createMarkers: function()
    {
      this.selection.get();

      var node1 = this.selection.getMarker(1);

      this.selection.setMarker(this.range, node1, true);

      if (this.range.collapsed === false)
      {
        var node2 = this.selection.getMarker(2);
        this.selection.setMarker(this.range, node2, false);

        // Fix for Chrome58 Issues
        if (this.utils.browser('chrome')) {
              this.caret.set(node1, 0, node2, 0);
         }
         // End Chrome58 Issues
      }

      this.savedSel = this.$editor.html();
    },

this is working and tested on chrome 60.

Method 3

original code is like this in both 10.2.2 and 10.2.5

    getNodes: function()
                    {
                        this.selection.get();

                        var startNode = this.selection.getNodesMarker(1);
                        var endNode = this.selection.getNodesMarker(2);

                        if (this.range.collapsed === false)
                        {
                            if (window.getSelection) {
                                var sel = window.getSelection();
                                if (sel.rangeCount > 0) {

                                    var range = sel.getRangeAt(0);
                                    var startPointNode = range.startContainer, startOffset = range.startOffset;

                                    var boundaryRange = range.cloneRange();
                                    boundaryRange.collapse(false);
                                    boundaryRange.insertNode(endNode);
                                    boundaryRange.setStart(startPointNode, startOffset);
                                    boundaryRange.collapse(true);
                                    boundaryRange.insertNode(startNode);

                                    // Reselect the original text
                                    range.setStartAfter(startNode);
                                    range.setEndBefore(endNode);
                                    sel.removeAllRanges();
                                    sel.addRange(range);

                                }
                            }
                        }
                        else
                        {
                            this.selection.setNodesMarker(this.range, startNode, true);
                            endNode = startNode;
                        }

how to change it?

Note: Use and implement method 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply