spohlenz / tinymce-rails

Integration of TinyMCE with the Rails asset pipeline
Other
815 stars 256 forks source link

Dropdown not loading with Turbolinks #257

Open bharget opened 5 years ago

bharget commented 5 years ago

Dropdowns on the tinymce editor appear to be broken until after a hard page refresh when coming from a turbolinks:load event.

I have tried removing any editors with the tinymce.remove() call as well as making sure to only initialize editors that appear on the page.

To me it looks as if the html that get's appended to the body is only loaded after a refresh.

I am using Rails 5.2.3, tubolinks 5.2.0, and tinymce-rails 5.0.5.

To initialize my editors, I use the following code:

$(document).on("turbolinks:load", function() {
  function tiny(editors) {
    const defaultOptions = {
      width: "100%",
      height: 100,
      plugins: [
        "advlist autolink link image lists charmap print preview hr anchor pagebreak spellchecker",
        "wordcount visualblocks visualchars code fullscreen insertdatetime media nonbreaking",
        "save table directionality template paste code importcss"
      ],
      powerpaste_word_import: "clean",
      powerpaste_html_import: "clean",
      toolbar:
        "insertfile undo redo | styleselect | bold italic strikethrough underline forecolor | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image | preview code",
      default_link_target: "_blank",
      menubar: false,
      extended_valid_elements:
        "span[!class],a[href|target=_blank|class=link],img[src|class=img-responsive|width=540|style=max-width:540px|alt=],sub[class=sub-text],sup[class=sub-text]",
      valid_styles: "max-width,list-style-type",
      paste_data_images: true,
      entity_encoding: "raw",
      content_css: "/assets/tinymce.css?" + new Date().getTime(),
      inline_styles: false,
      importcss_append: true,
    };

    // Only load the ones present on the page
    let filtered = editors.filter(function(editor) {
      return document.getElementById(editor.selector.substr(1)) != null;
    });

    filtered.forEach(function(options) {
      tinymce.init({ ...defaultOptions, ...options });
    });
  }

  const tiny_editors = [
    {
      selector: "#content",
      height: 500
    },
    {
      selector: "#title",
      toolbar: "link"
    },
    {
      selector: "#source",
      toolbar: "italic code",
      extended_valid_elements: "strong[!class],p[!class]",
      forced_root_block: false,
      valid_styles: "max-width"
    }
  ];

  // Only run if editors are present on the page
  if ($(".tinymce").length) {
    tiny(tiny_editors);
  }
});
spohlenz commented 4 years ago

Sorry for taking so long to check this out. I can reproduce this, however I believe the problem is in tinymce itself, and I haven't been able to successfully work around it so far.

What seems to be happening is that the 'sink' container element used for dropdowns, dialogs, etc. is not being recreated once Turbolinks replaces the body element. It looks like the body element itself may be cached (https://github.com/tinymce/tinymce/blob/master/modules/sugar/src/main/ts/ephox/sugar/api/node/Body.ts#L18-L20).

When I get a few more spare moments, I'll put together a bug report or PR for upstream and hopefully this can finally be fixed.