0

I am trying to customize the behavior of an editor button in a plugin. On click, it opens a modal where the user can input some text. On confirmation, I want to wrap this text into code tags. But I don't want to take this text as if it comes from a text editor, I want to handle it as visual text. This means, I want to preserve any formatting (whitespaces and linebreaks) but not accept any other tags besides the code tags that I add afterward.

function showDialog() {
    var win = ed.windowManager.open({
            title: "Insert code",
            body: {
                type: 'textbox',
                name: 'code',
                multiline: true,
                minWidth: ed.getParam("code_dialog_width", 600),
                minHeight: ed.getParam("code_dialog_height", Math.min(tinymce.DOM.getViewPort().h - 200, 500)),
                spellcheck: false,
                style: 'direction: ltr; text-align: left'
            },
            onSubmit: function(e) {
                ed.focus();

                ed.undoManager.transact(function() {
                    ed.insertContent('<code>' + e.data.code + '</code>');
                });

                ed.selection.setCursorLocation();
                ed.nodeChanged();
            }
        });
    }
  • You mean like this? – Sally CJ Feb 20 at 10:39
  • @SallyCJ Close! I also want to keep whitespaces in the beginning of each line if that's possible! – Florian Walther Feb 20 at 10:47
1

(Revised answer)

You can use tinymce.DOM.encode() to convert all HTML tags to their entities, e.g. &lt; for < and &gt; for >:

var html = tinymce.DOM.encode(e.data.code);

Then to preserve trailing white-spaces:

html = html.replace(/(^ +| +$)/gm, function(match, p1){
  return p1.replace(/ /g, '&nbsp;');
});

And this to convert all line breaks to <br>:

html = html.replace(/(?:\r\n|\r|\n)/g, '<br>');

So your onSubmit would look like, which you can try here:

onSubmit: function(e) {
  ed.focus();

  ed.undoManager.transact(function() {
    // Encode all HTML tags to their entities.
    var html = tinymce.DOM.encode(e.data.code);

    // Then convert trailing whitespaces to `&nbsp;`.
    html = html.replace(/(^ +| +$)/gm, function(match, p1){
      return p1.replace(/ /g, '&nbsp;');
    });

    // Finally, convert line breaks to `<br>`.
    html = html.replace(/(?:\r\n|\r|\n)/g, '<br>');

    // Make sure the format is "raw".
    ed.insertContent('<code>' + html + '</code> ');
  });

  ed.selection.setCursorLocation();
  ed.nodeChanged();
}

Credit to this SO answer for the line breaks conversion.

  • I think the whitespaces have to be converted to <p> </p> because I get &nbsp; everywhere in my output. – Florian Walther Feb 20 at 11:26
  • So multiple white-spaces become a <p> </p> and not for each white-space - e.g. ` ` (three spaces) is not <p> </p><p> </p><p> </p> (three ps)? – Sally CJ Feb 20 at 11:32
  • Right, it becomes <p> </p> which contains all the empty spaces for that line – Florian Walther Feb 20 at 11:33
  • Check the updated answer and new demo. – Sally CJ Feb 20 at 11:49
  • 1
    It seems to work, thank you! It doesn't actually work properly in my plugin editor but I guess this is a problem on my side! Thank you very much! – Florian Walther Feb 20 at 12:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.