How to load TypeKit fonts into a CKEditor instance using jQuery

妖精的绣舞 提交于 2019-12-04 20:49:12

Here what I've managed to assemble after 3 hours of digging over Internet:

CKEDITOR.on(
    'instanceReady',
    function(ev) {
        var $script = document.createElement('script'),
            $editor_instance = CKEDITOR.instances[ev.editor.name];

        $script.src = '//use.typekit.com/MYKEY.js';
        $script.onload = function() {
            try{$editor_instance.window.$.Typekit.load();}catch(e){}
        };

        $editor_instance.document.getHead().$.appendChild($script);
    }
);

Trick here is to use CKEditor's "window" object, that comes from iframe.

CKEDITOR.scriptLoader appears to be used to load assets to the parent window, not into the iframe'd document. This causes your code above to execute and re-apply the Typekit font to the parent window instead of the iframe.

My solution for this is to set document.domain in your parent window, create <script> elements dynamically, append them to the <head> of the iframe document.

1. Your Typekit has a domain whitelist. CKEditor will not set set the <iframe> tag's src attribute to return a valid value in this whitelist unless you specify document.domain in your parent window to be a domain on that whitelist.

document.domain = "example.com";

2. I created the scripts with lines like

script1      = document.newElement('script');
script1.src  = "https://use.typekit.com/MYKEY.js";

script2      = document.newElement('script');
script2.text = "try{Typekit.load();}catch(e){}";

3. I then append these to the dom (I use jQuery in my project, so that's how I target the element)

head = jQuery('textarea.editor').ckeditorGet().document.getHead().$;
head.appendChild(script1);
head.appendChild(script2);

The Typekit fonts are now applied.

Modified for use within the CKEditor setup

  editors.ckeditor(function(){
    var head         = this.document.getHead().$,
        script1      = document.newElement("script"),
        script2      = document.newElement("script");

    script1.src  = sprintf("https://use.typekit.com/%s.js", app_typekit_id);
    script2.text = "setTimeout(function(){ try{Typekit.load();}catch(e){} }, 0);";

    head.appendChild(script1);
    head.appendChild(script2);
  },
  {
    //... your custom config
  });

Maybe there is a better way than the setTimeout(function(){ ... }, 0); (a 0ms delay), but leaving just the try{Typekit.load();}catch(e){} does not give script1 enough time to be appended and interpreted by the browser to begin blocking. Also note, my use of sprintf() above comes from a library (not native JS).

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!