Custom plugin with DOM manipulation CKEditor 4.x

2019-07-16 15:34发布

问题:

I am developing one custom plugin for the CKEditor 4.7 which do a simple think take in case user select some stuff it will put it in a div with specific class, else it will put a div with same class just with text like 'Add content here' I try to use some functions according to CKEditor docs but have something really wrong. here is the code for the plugin folder name=> customdiv, file=> plugin.js

CKEDITOR.plugins.add('customdiv', {
    icons: 'smile',
    init: function (editor) {

        editor.addCommand( 'customdiv',{
            exec : function( editor ){ 
                var selection = editor.getSelection();
                if(selection.length>0){
                    selection='<div class="desktop">'+selection+'</div>';
                }else{
                     selection='<div class="desktop">Add your text here </div>';
                }
                return {
                    selection
                };
            }
        });


        editor.ui.addButton( 'Customdiv',
        {
                label : 'Custom div',
                command : 'customdiv',
                toolbar: 'customdiv',
                icon : this.path + 'smile.png'
        });

        if (editor.contextMenu) {

            editor.addMenuGroup('divGroup');
            editor.addMenuItem('customdiv', {
                label: 'Customdiv',
                icon: this.path + 'icons/smile.png',
                command: 'customdiv',
                group: 'divGroup'
            });
            editor.contextMenu.addListener(function (element) {
                if (element.getAscendant('customdiv', true)) {

                }
            });
        }

    }
});

According to some docs it have to return the result good. Also this is how I call them in my config.js file

CKEDITOR.editorConfig = function (config) {

    config.extraPlugins = 'templates,customdiv';  
    config.allowedContent = true;
    config.toolbar = 'Custom';
    config.toolbar_Custom = [
        { name: 'divGroup', items: [ 'Customdiv' ] },

        {name: 'document', items: ['Source', '-', 'Save', 'Preview', '-', 'Newplugin']},
        /* MOre plugins options here */
    ];
};

Note: the official forum was close and moved here :(

UPDATE I have change the function like this

exec : function( editor ){ 
          var selection = editor.getSelection();
          if(selection.length>0){
             selection='<div class="desktop">'+selection+'</div>';
             CKEDITOR.instances.editor1.insertHtml( selection );
          }else{
             selection='<div class="desktop">Add your text here </div>';
             CKEDITOR.instances.editor1.insertHtml( selection );
          }                   
      }

This makes it work for the else part, but still can't get the selected one.

UPDATE 2
After change of the if I can get data if is selected, but when I do insert selected between <div> I face a problem.

var selection =   editor.getSelection();

give like result an object, and I funded out a more complex function and I get collected data like this

var selection = editor.getSelection().getNative();
alert(selection);

from this in alert I see the proper selection and not just object,but when I insert it like

CKEDITOR.instances.editor1.insertHtml('<div class="desktop">' + selection + '</div>');

it just put all selected in one line and not adding the div, new div for else case working with this syntax.

UPDATE 3
The problem now is this function

CKEDITOR.instances.editor1.insertHtml('<div>' + selection + '<div>');

it delete all existing HTML tags even if I add just selection without <div>
I am not sure if this is because of the way I insert data or way I collect data, just in alert when I collect data I see correct space like in the editor.

回答1:

user select some stuff it will put it in a div with specific class

If you want to check if selection is not empty, please instead of selection.length>0 try using !selection().getRanges()[0].collapsed.

If you need something more advanced you could also try using !!CKEDITOR.instances.editor1.getSelection().getSelectedText() to see if any text was selected and !!CKEDITOR.instances.editor1.getSelection().getSelectedElement() to see if any element like e.g. image, tabl,e widget or anchor was selected.

EDIT: If you need selected HTML please use CKEDITOR.instances.editor1.getSelectedHtml().getHtml();

Please also have a look at CKEditor documentation:

  • https://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-getSelectedHtml
  • https://ckeditor.com/docs/ckeditor4/latest/api/CKEDITOR_dom_documentFragment.html#method-getHtml
  • https://docs.ckeditor.com/#!/api/CKEDITOR.dom.selection-method-getSelectedText
  • https://docs.ckeditor.com/#!/api/CKEDITOR.dom.selection-method-getSelectedElement