Search code examples
javascriptckeditormonkeypatching

Monkey patching CKEditor to embed YouTube videos


I'm trying to configure CKEditor so that it could embed YouTube videos directly... I saw there's a proposed patch but I want to keep the original CKEditor distribution as it is, so I was wondering if it's possible to "monkey patch" CKEditor at runtime so that if the user types a YouTube URL inside the Flash dialog, the URL gets transformed to allow embedding.

I've tried this:

CKEDITOR.on('dialogDefinition', function(ev){
    if (dialogName == 'flash'){
        var infotab = dialogDefinition.getContents('info');
        var f = dialogDefinition.onOk;
        dialogDefinition.onOk = function(ev) {
            var cur = this.getContentElement('info', 'src').getValue();
            var newurl = cur.replace('youtube.com/watch?v=', 'youtube.com/v/'); 
            if (cur != newurl) { 
                this.getContentElement('info', 'src').setValue(newurl);
            };
            f(ev);
       }
    }
}

but it won't work, since inside f the code uses this, and my "patch" changes it...


Solution

  • If you attach the onOK to another property of dialogDefinition, this will be correct within it (I think).

    CKEDITOR.on('dialogDefinition', function(ev){
        if (dialogName == 'flash'){
            var infotab = dialogDefinition.getContents('info');
            dialogDefinition.oldOnOk = dialogDefinition.onOk; //change here
            dialogDefinition.onOk = function(ev) {
                var cur = this.getContentElement('info', 'src').getValue();
                var newurl = cur.replace('youtube.com/watch?v=', 'youtube.com/v/');
                if (cur != newurl) { 
                    this.getContentElement('info', 'src').setValue(newurl);
                };
               dialogDefinition.oldOnOk(ev); //and change here
           }
        }
    }
    

    Or use Function.apply:

    CKEDITOR.on('dialogDefinition', function(ev){
        if (dialogName == 'flash'){
            var infotab = dialogDefinition.getContents('info');
            var f = dialogDefinition.onOk; 
            dialogDefinition.onOk = function(ev) {
                var cur = this.getContentElement('info', 'src').getValue();
                var newurl = cur.replace('youtube.com/watch?v=', 'youtube.com/v/');
                if (cur != newurl) { 
                    this.getContentElement('info', 'src').setValue(newurl);
                };                
                f.apply(this, ev);  //change here
           }
        }
    }