When you begin typing in a CKEditor textarea and go over the character limit, the editor begins to blink and starts moving your cursor in and out. It only happens with the truncate html option enabled.

It seems once it pass the character limit, the process (in maxlength.js) enter and endless loop where the function ml.ckeditorChange() is called over and over, calling ml.calculate() again and again. Every time the cursor enters the textarea ml.ckeditorChange() is called, and when the limit is reached, for some reason related to the truncateHtml option, the cursor goes in and out of the textarea, endlessly.

Comments

juanolalla created an issue. See original summary.

juanolalla’s picture

Issue summary: View changes
juanolalla’s picture

When the limit is reached, the truncate html option is acting on the editor, replacing the data which has two effects:
1. The cursor goes to the beginning of the text.
2. The editor looses focus and gets focus, and that throws an event in code (elementsPathUpdate), which repeats the truncating again, entering in a loop.

neetu morwani’s picture

I am also facing the same issue.

dawehner’s picture

If someone wants to have real extra kudos, try to write some automated javascript test coverage. Otherwise, of course some bug fix would be super nice.

juanolalla’s picture

Status: Active » Needs review
StatusFileSize
new1.4 KB

I've made two fixes for this, one is ensuring ml.ckeditor() runs just once, which was not working due to the use of a local variable for checking.

The other fix is trimming newlines at the beginning and at the end of the wysiwyg html piece of code, because they are useless out the html tags, and that was causing the problem. CKEditor adds a \r\n after the last tag, and that was increasing the count of characters causing confusion. And what it worse, the ml.truncate_html() function was removing those newline characters instead of the last character introduced over the limit, causing the endlessly blinking.

Now it's working well for me. The cursor is still being placed at the beginning of the editor every time the text is truncated, but that seems to be the way setData() works on the editor. I haven't found a way to put the cursor where it was after truncating. But anyway, that would be another issue for improvement, in case there was actually a trick that could work for that.

icicleking’s picture

I think the problems are deeper than this. The patch above does not seem to change the rapidly flashing cursor. Also, I think placing the cursor at the front of the text, then cutting off the text at the back is problematic for the user. Finally, on Chrome the module is causing major CPU usage, every time I exceed the max-length on a truncated field I get a Google Chrome Helper running at 100+% CPU usage.

juanolalla’s picture

I agree there is a deeper UX problem with the cursor placed at the beginning of the editor after the content is truncated. I pointed that out in my previous comment, but that is not something that I've done, is something that it was there and it's not part of this specific issue. As I said, using CKEditor setData() method to replace the content has this effect of placing the cursor at the beginning, and I haven't found a quick workaround to place the cursor where it was after that, or another method to replace the data that would keep the cursor at the same place. Anyhow, this would be another issue that we could report appart, as an UX improvement.

So keeping the focus on the problem of this issue, isn't the patch working for you? Once you exceed the maxlength the cursor starts to go in and out in a javascript loop? That is what I fixed and it is working for us on the project we are using it. If after exceeding the maxlength you're writting characters at the beginning of the text and see the text being cut at the end, then it means the patch is working. Before the patch you could not even use the editor.

juanolalla’s picture

StatusFileSize
new1.79 KB

Updated patch to include UX improvements from https://www.drupal.org/node/2823849, which is the same issue in D7. Now the cursor is placed at the end after truncating, which is where the text is being cut.

icicleking’s picture

Tested and it works as expected.

icicleking’s picture

Status: Needs review » Reviewed & tested by the community
dawehner’s picture

The code looks pretty decent,

+++ b/js/maxlength.js
@@ -341,7 +344,12 @@
+    e.editor.setData(data, {callback: function() {
+      e.editor.focus();
+      var range = e.editor.createRange();
+      range.moveToElementEditablePosition(e.editor.editable(), true);
+      e.editor.getSelection().selectRanges([range]);
+    }});

I'm wondering whether we could add some form of documentation to make it clearer what is going on here. Maybe explain why setData doesn't work.

+++ b/js/maxlength.js
@@ -285,15 +287,16 @@
     // We only run it once
-    var onlyOnce = false;

Not a problem of the current patch, but this is one of these examples, where it would be cool to document why we want this code to just render once. Why is it potentially executed more than once?

juanolalla’s picture

Yes of course, I'm doing that.

I'm not sure way that code is executed more than once, and the once check was already there, but it wasn't working. I'll try to figure that out.

juanolalla’s picture

StatusFileSize
new2.13 KB

Added documentation.

  • dawehner committed 051c0ac on 8.x-1.x authored by juanolalla
    Issue #2804757 by juanolalla: Truncate option makes CKEditor cursor...
dawehner’s picture

Status: Reviewed & tested by the community » Fixed
  1. +++ b/js/maxlength.js
    @@ -120,6 +120,8 @@
    +    // Remove all newlines, spaces and tabs from the beginning and end of html.
    +    input = $.trim(input);
    

    Nice!

  2. +++ b/js/maxlength.js
    @@ -341,7 +345,15 @@
    +    // Calling setData() will place the cursor at the beginning, so we need to
    +    // implement a callback to place it at the end, which is where the text is
    +    // being truncated.
    +    e.editor.setData(data, {callback: function() {
    

    I just love that

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.

robmccreary’s picture

None of these patches seem to be working for me with 8.x-1.0-beta1 and drupal 8.4.0 with the seven theme (or any other theme).

When the force truncate option is enabled for a field.

bajah1701’s picture

Version 8.x-1.0-beta2 doesn't work with Drupal 8.4.8. Blinking still exist and cursor returns to the start. Clicking on source does stop the blinking but it starts again if any new character is added.

wombatbuddy’s picture

As a workaround, the 'CKEditor Wordcount' module can be used instead. It works good with the CKEditor.

cedewey’s picture

I just tested this with Drupal 8.9.18 and is working as expected. The cursor does not return to start or blink rapidly.