If you have 10 fieldsets and 40 editors, you don't want all editors to init immediately, because that makes the page crazy slow. Instead, the editor should only load when the parent fieldset opens. Or in another very smart way that a developer should decide.

To allow for this, a specific CKEditor instance must be disabled by default. There is an option for this: 'autostart'. Autostart is populated in ckeditor_load_by_field() by $ckeditor_on per element, so that's perfect. BUT it can't be altered or preset. It comes from the CKEditor profile, which is global.

A very simple, completely backward compatible check would make this possible:

  // Allow per-element 'autostart'.
  if (isset($field['#ckeditor_on'])) {
    $ckeditor_on = $field['#ckeditor_on'];
  }

(It's called #ckeditor_on because that's the variable name and it includes "ckeditor", so it's better than #autostart.)

By disabled your 40 ckeditors, a developer could add this JS in the form to make them lazy load:

// Lazy loading CKEditors in fieldsets.
// Add listener to <form>, because event bubbles up from any <fieldset> to the <form>.
$('#domain-locale-conf-all-form', context).bind('collapsed', function(e) {
  if (!e.value) {
    var fs = this;
    setTimeout(function() {
      // Find all newly visible editors.
      var ids = $('textarea.ckeditor-mod:not(.ckeditor-processed):visible', fs).map(function(i, ta) {
        return ta.id;
      });
      if (ids.length) {
        console.debug('Lazy loading ' + ids.length + ' CKEditors.');

        // Need ckeditorToggle(), because ckeditorOn() won't change the toggle label.
        Drupal.ckeditorToggle(ids, Drupal.t('Switch to plain text editor'), Drupal.t('Switch to rich text editor'));
      }
    }, 1);
  }
});

I'll try to make a patch, but I use a severely hacked 1.16, so I'm not sure it'll apply or even match at all.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

jcisio’s picture

Added two related issues.

- #1063986: Allow user to choose which textarea is enable by default was in D6 which I decided not to forward port to D7 because the architecture has completely changed.
- #1145132: Disable for certain textareas? in about to permanently disable CKEditor in some fields.

rudiedirkx’s picture

#1063986 used config, which is unnecessary IMO, and often not good enough, because on/off state depends on some runtime logic.

#1145132 does what I need, I think..., but a hook seems expensive and misses a lot of context. You can choose which one to keep open. I think this one's a duplicate. I'll comment in the other.

rudiedirkx’s picture

Nope. Not a duplicate. But it might be nice to combine the 2 features:

  • completely disable CKEditor for one specific element
  • disable autostart for one specific element
annya’s picture

Version: 7.x-1.16 » 7.x-1.x-dev
Status: Active » Needs review
FileSize
717 bytes

rudiedirkx helps me, thanks. I did patch from his code. But in general we have to do find flexible solution to change CKEditor settings for separate field.

rudiedirkx’s picture

Status: Needs review » Needs work

That's not good enough, because this if cancels out the next if, which loads $settings, which means $settings exist only for fields that don't have isset($field['#ckeditor_on']).

Two ways to fix this:

1. Positition the if like I did in OP, or
2. Always load $settings, no matter the source of $ckeditor_on. This is harder, because $settings has 2 different sources too.

And a way to test this:

1. Make sure your CKEDITOR settings have the Show the disable/enable rich text editor toggle option enabled.
2. Add '#ckeditor_on' => FALSE, for 1 WYSIWYG element.
3. Load page: the #ckeditor_on won't have the toggle link, and the other elements will.

rudiedirkx’s picture

Status: Needs work » Needs review
FileSize
553 bytes

Original solution in a patch.