javascriptiframegoogle-chrome-extensiontinymce

tinymce not loaded inside the iframe chrome extension - "tinymce should have been loaded into global scope"


I am trying to place an tinymce editor inside an iframe of the chrome extension application. But when I load the application, tinymce textArea tag has been set as hidden and in the console "tinymce should have been loaded into global scope" error has been raised. It is not opening the tinymce editor.

Tried inserting the cdn link of the tinymce in the manifest.json, tried adding script to the "tinymce.min.js" js file but nothing works.

Can any one help to support on this?


Solution

  • I'm not sure what exactly causes this "tinymce should have been loaded into global scope" error, but since you're using build system already, I'd suggest using npm module to integrate TinyMCE into extension. As far as I remember most of problems with TinyMCE (in context of browser extension) was because

    1. TinyMCE tries to load a bunch of files using http (like styles or plugins) and this won't work in context of extension. So we need to disable this feature and load them manually.
    2. For some reason TinyMCE wan't to be in global context, even if loaded from npm module, so we manually assign it to window.tinymce

    In our project we're using React, so also using tinymce-react, but I hope this snippet will help you even if you're stick to plain TinyMCE.

    import React from "react";
    
    import tinymce from 'tinymce/tinymce.min.js';
    
    // TinyMCE wants to be in global scope, even if loaded from npm module
    window.tinymce = tinymce;
    
    import { Editor } from '@tinymce/tinymce-react';
    
    // We're manually importing theme, icons and plugins because otherwise TinyMCE tries to resolve 
    // them himself and load throught http, but this won't work with chrome extension
    // Theme
    import 'tinymce/themes/silver/theme.min.js';
    // Toolbar icons
    import 'tinymce/icons/default/icons.min.js';
    
    // importing the plugin js.
    import 'tinymce/plugins/paste/plugin.min.js';
    import 'tinymce/plugins/link/plugin.min.js';
    import 'tinymce/plugins/lists/plugin.min.js';
    import 'tinymce/plugins/advlist/plugin.min.js';
    import 'tinymce/plugins/anchor/plugin.min.js';
    import 'tinymce/plugins/autolink/plugin.min.js';
    import 'tinymce/plugins/charmap/plugin.min.js';
    import 'tinymce/plugins/code/plugin.min.js';
    import 'tinymce/plugins/codesample/plugin.min.js';
    import 'tinymce/plugins/colorpicker/plugin.min.js';
    import 'tinymce/plugins/table/plugin.min.js';
    import 'tinymce/plugins/wordcount/plugin.min.js';
    import 'tinymce/plugins/textcolor/plugin.min.js';
    import 'tinymce/plugins/image/plugin.min.js';
    import 'tinymce/plugins/imagetools/plugin.min.js';
    import 'tinymce/plugins/contextmenu/plugin.min.js';
    
    // We're also importing styles manually and later attach them to editor. `?raw` here means that we're not using 
    // any kind of style-loader (webpack) and just want to import content of file as plain string
    // This requires additional setup in webpack and might look different for other build systems
    import contentCss from 'tinymce/skins/content/default/content.min.css?raw';
    import contentUiCss from 'tinymce/skins/ui/oxide/content.min.css?raw';
    
    // This is our wrapper component to not copy-past this whole process of initialization to each file where we need tinymce
    export const TinyMceEditor = (props) => {
    
        return (
            <Editor
                {...props}
                init={{
                    skin: false,
                    content_css: false,
                    menubar: false,
                    toolbar: 'undo redo | bold italic underline strikethrough | alignleft aligncenter alignright ' +
                        'alignjustify | outdent indent |  numlist bullist checklist link | forecolor backcolor casechange ' +
                        'removeformat | charmap | fullscreen | fontselect fontsizeselect formatselect',
                    plugins: [
                        'paste link lists advlist anchor autolink charmap code codesample ' +
                        'table wordcount'
                    ],
                    content_style: [contentCss.toString(), contentUiCss.toString()].join(''),
                }}
            />);
    };
    

    We're using "tinymce": "^5.9.2" and "@tinymce/tinymce-react": "^3.13.0"

    To enable webpack to load files as strings with this ?raw query you need to add this in your webpack config module.rules array

    {
        resourceQuery: /raw/,
        type: 'asset/source',
    }