jaheraho
jaheraho

Reputation: 550

TinyMCE: how to let user mark text when "readonly: true;"

I want to let users select (and copy) text within TinyMCE.

I'm not quite sure, but it seems regarding security that browsers don't allow that.

This Codepen is from the official TinyMCE site: https://codepen.io/tinymce/pen/NGegZK

Here you can select text.

When you add there the following parameter in the 2nd line of the JavaScript as followed, then you can't longer select text.

  readonly: true,

How can I set "readonly: true" and let the user still select text?

I appreciate any help.

Upvotes: 4

Views: 1243

Answers (4)

Spyder
Spyder

Reputation: 1902

It was previously possible to select text in readonly mode, until the fix for #4249 broke it in 4.7.12.

We've just started tracking a fix that allows text to be selected and links to be clicked, follow either of the tickets linked here to be updated when we release a fix.

Upvotes: 0

hh54188
hh54188

Reputation: 15626

I solved this issue for achieve readonly mode by myself, I would create an iframe dom node and put the editor's html segment into it.

  renderReportPreview = contentHtml => {
    const iframe = document.querySelector('iframe[name=preview]')
    if (iframe) {
      const cssLink = document.createElement('link')
      // cssLink.href = 'https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css'
      // I prefer semantic-ui, semantic-ui is more like tinyMce style
      cssLink.href = 'https://cdn.bootcss.com/semantic-ui/2.3.1/semantic.min.css'
      cssLink.rel = 'stylesheet'
      cssLink.type = 'text/css'
      iframe.contentWindow.document.head.appendChild(cssLink)
      // I escape the origin editor's content, so I need decode them back
      iframe.contentWindow.document.body.innerHTML = htmlDecode(contentHtml)
      const allTables = iframe.contentWindow.document.body.querySelectorAll(
        'table'
      )
      Array.from(allTables).forEach(table => {
        // ui celled table for compatible semantic-ui
        // table table-bordered for compatible bootstrap
        table.className = 'ui celled table table-bordered'
      })
      this.setState({
        previewRendered: true,
      })
    }
  }

More detail on https://github.com/tinymce/tinymce/issues/4575

Upvotes: 0

thorn0
thorn0

Reputation: 10397

I faced this problem too. Moreover, the inability to select text is nothing compared to the inability to click links. I've submitted an issue about this a while ago, but there is still no reaction.

You can use a workaround for now (codepen):

  readonly: 1,
  setup: function(editor) {
    editor.on('SwitchMode', function() {
      if (editor.readonly) {
        editor.readonly = 1;
      }
    });
  }

It exploits the fact that the event-blocking code uses strict comparison internally (readonly === true) while the rest of the code works fine with any other truthy value, e.g. 1. Of course, this hack might stop working after an update in the future, but it's much better than nothing.

Update: better switch to the inline mode (codepen) if you use this hack. Otherwise clicking links leads to a mess.

Upvotes: 4

Hypergraphe
Hypergraphe

Reputation: 153

I have checked the source code of the lastest nightly and it seems that the behavior is hardcoded. All events are discarded if the editor is in readonly mode. Which means that selection events are discarded too :

  var isListening = function (editor) {
    return !editor.hidden && !editor.readonly;
  };
  var fireEvent = function (editor, eventName, e) {
    if (isListening(editor)) {
      editor.fire(eventName, e);
    } else if (isReadOnly(editor)) {
      e.preventDefault();
    }
  };

I might be wrong but I don't think you can change this behavior through customization.

Regards

Upvotes: 2

Related Questions