Search code examples
javascriptextjsckeditorresponsive-imagessrcset

ckeditor 4.4 responsive image upload with old image plugin and custom filemanager to add srcset, sizes attribute


I have ckeditor 4.4, Old Image plugin (Not Image2), and I am using custom filamanager to upload files.

How can I add responsive images to ckeditor. I mean, I have to add sizes and srcset attributes automatically to img tag.

Image preview also should work.


Solution

  • 1) In Ckeditor config.js do handle onOk and onShow events

    CKEDITOR.on('dialogDefinition', function (ev) {
        var dialogDefinition = ev.data.definition;
        var editor = ev.editor;
        var sizes = '(min-width: 36em) 33.3vw, 100vw';
    
        //Check if its image dialog only
        if (ev.data.name == 'image') {
            //whenever image dialog is shown, show srcset urls in it (if a image has) and disable unnecessory styling fields
            dialogDefinition.dialog.on('show', function(e){
                var imgElement = editor.getSelection().getStartElement();
                var dialogBox = e.sender;
                var srcOrSrcset = '';
    
                if ((srcOrSrcset = imgElement.getAttribute('srcset'))) {
                    //This line is very important to handle show event, because there is no originalElement in dialogBox
                    //Other wise it will throw `called setCustomData on null` from original Image.js @ line 306 plugin
                    //https://github.com/ckeditor/ckeditor-dev/blob/master/plugins/image/dialogs/image.js
                    dialogBox.originalElement = imgElement;
                    dialogBox.originalElement.data('cke-saved-src', srcOrSrcset);
                    
                    //disable content elements, because no use of inline style in case of responsive image
                    dialogBox.getContentElement('info','txtHeight').disable();
                    dialogBox.getContentElement('info','txtWidth').disable();
                    dialogBox.getContentElement('info','txtBorder').disable();
                    dialogBox.getContentElement('info','txtHSpace').disable();
                    dialogBox.getContentElement('info','txtVSpace').disable();
                    dialogBox.getContentElement('info','cmbAlign').disable();
    
                    //dialog.preview is not exists yet, so delaying execution. meanwhile original image.js show handler will attach preview dialogBox
                    window.setTimeout(function () {
                        dialogBox.preview.setAttribute('srcset', srcOrSrcset);
                    }, 0);
                }
            });
    
            //on click of ok button of image dialog, add srcset attribute to the selected img
            //srcset should be in specific format i.e. img1.jpg, img2.jpg, img3.jpg
            //images should be seperated by comma followed by space (, )
            //default src will be first url of srcset
            dialogDefinition.onOk = function (e) {
                var dialogBox = e.sender;
                var imgUrl = dialogBox.getContentElement('info','txtUrl').getValue();
                var altTxt = dialogBox.getContentElement('info','txtAlt').getValue();
                var imgHtml = '';
                var indexOfFirstUrlEnd;
    
                //If entered url is like srcset
                if((indexOfFirstUrlEnd = imgUrl.indexOf(', ')) > -1) {
                    imgHtml = '<img src="' + imgUrl.substr(0, indexOfFirstUrlEnd) + '"' +
                        'srcset="' + imgUrl + '"' +
                        'alt="' + altTxt + '"' +
                        'sizes="' + sizes + '"/>';
                } else {
                    //if its normal src url
                    var style = dialogBox.getContentElement('advanced','txtdlgGenStyle').getValue();
                    imgHtml = '<img src="' + imgUrl + '" alt="' + altTxt + '" style="' + style + '" />';
                }
                editor.insertElement(CKEDITOR.dom.element.createFromHtml(imgHtml));
            };
        }
    });

    2) In myCustomFileManager.js I have

    var imageSrcOrSrcset = '';
    if(urls.length > 1) {
        for (var key in urls) {
            imageSrcOrSrcset += ', ' + urls[key];
        }
      dialog.getContentElement('info','txtHeight').disable();
      dialog.getContentElement('info','txtWidth').disable();
      dialog.getContentElement('info','txtBorder').disable();
      dialog.getContentElement('info','txtHSpace').disable();
      dialog.getContentElement('info','txtVSpace').disable();
      dialog.getContentElement('info','cmbAlign').disable();
    } else {
        imageSrcOrSrcset = urls['0'];
      dialog.getContentElement('info','txtHeight').enable();
      dialog.getContentElement('info','txtWidth').enable();
      dialog.getContentElement('info','txtBorder').enable();
      dialog.getContentElement('info','txtHSpace').enable();
      dialog.getContentElement('info','txtVSpace').enable();
      dialog.getContentElement('info','cmbAlign').enable();
    }
                
    //pass url/urls to image properties dialog
    window.opener.CKEDITOR.tools.callFunction(params.CKEditorFuncNum, imageSrcOrSrcset);
    
    //set preview in case of srcset (multiple urls)
    if(urls.length > 1) {
        window.opener.CKEDITOR.dialog.getCurrent().preview.setAttribute('srcset', imageSrcset);
    }
    window.close();