1

I'm copying instagram embed code in tinymce source code and i can see the block of instagram but couldn't able to see the image. Please help me fix this issue

Arpit Sethi
  • 116
  • 2
  • 9

5 Answers5

4

The problem is that when you add the embed code to tinymce. The code gets rendered in an iframe and the source code does not execute. The best approach in this case is to add a popup to take the embed code, extract the src from it and append it to the head of the iframe. This way the source code will execute and you will get a rendered html.

var editor_id = "";
tinymce.PluginManager.add('instagram', function(editor, url) {
    // Add a button that opens a window
    editor.addButton('instagram', {
        text: 'Instagram',
        icon: false,
        onclick: function() {
            // Open window
            editor.windowManager.open({
                title: 'Instagram Embed',
                body: [
                    {   type: 'textbox',
                        size: 40,
                        height: '100px',
                        name: 'instagram',
                        label: 'instagram'
                    }
                ],
                onsubmit: function(e) {
                    // Insert content when the window form is submitted
                    var embedCode = e.data.instagram;
                    var script = embedCode.match(/<script.*<\/script>/)[0];
                    var scriptSrc = script.match(/".*\.js/)[0].split("\"")[1];
                    var sc = document.createElement("script");
                    sc.setAttribute("src", scriptSrc);
                    sc.setAttribute("type", "text/javascript");

                    var iframe = document.getElementById(editor_id + "_ifr");
                    var iframeHead = iframe.contentWindow.document.getElementsByTagName('head')[0];

                    tinyMCE.activeEditor.insertContent(e.data.instagram);
                    iframeHead.appendChild(sc);
                    // editor.insertContent('Title: ' + e.data.title);
                }
            });
        }
    });
});
tinymce.init({
    selector:'textarea',
    toolbar: 'bold italic | alignleft aligncenter alignright alignjustify | undo redo | link image media | code preview | fullscreen | instagram',
    plugins: "wordcount fullscreen link image code preview media instagram",
    menubar: "",
    extended_valid_elements : "script[language|type|async|src|charset]",
    setup: function (editor) {
        console.log(editor);
        editor.on('init', function (args) {
            editor_id = args.target.id;
        });
    }
});

Refer the JSFiddle - https://jsfiddle.net/z3o2odhx/1/

You can add the embed html from the Instagram toolbar button and get the rendered html, but this also messes the source code. Hope this is helpful.

Ananth Pai
  • 1,939
  • 14
  • 15
  • It's not working for multiple instagram embed. Please let me know what can be done – Arpit Sethi Aug 31 '16 at 10:56
  • @ArpitSethi I had the same problem with multiple instagram images, however twitter embeds seems to work fine using the same method. There was nothing i could do about it, instagram doesn't rerender the html in this case. – Ananth Pai Aug 31 '16 at 11:07
  • 1
    [http://stackoverflow.com/questions/27408917/instagram-embeds-not-working-when-adding-embeds-dynamically](http://stackoverflow.com/questions/27408917/instagram-embeds-not-working-when-adding-embeds-dynamically) I think this is the solution but couldn't implement it. – Arpit Sethi Aug 31 '16 at 14:16
  • 1
    Thanks for the info, here is the update fiddle - https://jsfiddle.net/z3o2odhx/1/ – Ananth Pai Aug 31 '16 at 14:44
  • 1
    it gets resized on clicking the source code. Please help me to resolve it. – Arpit Sethi Sep 27 '16 at 12:57
  • using same code twitter post also rendering but when i click on source, then all code auto removing, is there any way to do the same thing for twitter? please help – dharmx Jan 23 '18 at 08:25
1

Alternatively, if you have the option of adjusting the html of the page, you can just add <script async defer src="//www.instagram.com/embed.js"></script> somewhere on that page, since it looks like TinyMCE is stripping the js include.

If you want to selectively include it, you can also use something like this in that page's js:

if($(".instagram-media").length) {
    var tag = document.createElement('script');
    tag.src = "//www.instagram.com/embed.js";
    tag.defer = true;
    tag.async = true;
    var firstScriptTag = document.getElementsByTagName('script')[0];
    firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
}
cMarius
  • 1,090
  • 2
  • 11
  • 27
0

TinyMCE changed a bit in the last version (v5) - here is updated version of working Ananth Pais' solution:

tinymce.PluginManager.add('instagram', function(editor, url) {
    editor.ui.registry.addButton('instagram', {
        text: 'Instagram',
        onAction: function() {
            editor.windowManager.open({
                title: 'Instagram Embed',
                body: {
                    type: 'panel',
                    items: [
                        {
                            type: 'textarea',
                            height: '300px',
                            name: 'instagram',
                            label: 'Instagram embed code',
                        }
                    ],
                },
                buttons: [
                        {
                            type: 'submit',
                            name: 'submitButton',
                            text: 'Embed',
                            disabled: false,
                            primary: true,
                            align: 'start',
                        }
                ],
                onSubmit: function(e) {
                    var data = e.getData();
                    var embedCode = data.instagram;
                    var script = embedCode.match(/<script.*<\/script>/)[0];
                    var scriptSrc = script.match(/".*\.js/)[0].split("\"")[1];
                    var sc = document.createElement("script");
                    sc.setAttribute("src", scriptSrc);
                    sc.setAttribute("type", "text/javascript");

                    var iframe = document.getElementById(editor_id + "_ifr");
                    var iframeHead = iframe.contentWindow.document.getElementsByTagName('head')[0];

                    tinyMCE.activeEditor.insertContent(data.instagram);
                    iframeHead.appendChild(sc);
                    e.close();
                }
            });
        }
    });
});
tinymce.init({
selector:'textarea',
toolbar: 'bold italic | alignleft aligncenter alignright alignjustify | undo redo | link image media | code preview | fullscreen | instagram',
plugins: "wordcount fullscreen link image code preview media instagram",
menubar: "",
extended_valid_elements : "script[language|type|async|src|charset]",
setup: function (editor) {
    console.log(editor);
    editor.on('init', function (args) {
        editor_id = args.target.id;
    });
}
});
hrkisk
  • 1
  • 1
  • 1
0

https://www.tiny.cloud/docs/configure/content-filtering/#usingextended_valid_elementstoallowscriptelements

by default tinmye prevent script codes. enable them on tinymce options

 extended_valid_elements : 'script[src|async|defer|type|charset]'
Sparkz
  • 83
  • 2
  • 11
0

You can do this within the setup and will work with the standard embed button...

tinymce.init({
    setup: (editor) => {

        let iframe;

        editor.on('init', function (args) {
            iframe = document.getElementById(editor.id + "_ifr");
            let iframeHead = iframe.contentWindow.document.getElementsByTagName('head')[0];
            let sc = document.createElement("script");
            sc.setAttribute("src", 'https://www.instagram.com/embed.js');
            sc.setAttribute("type", "text/javascript");
            iframeHead.appendChild(sc);
        });

        editor.on('Change', (e) => {
            iframe.contentWindow.instgrm.Embeds.process()
        });
    }
});