Opened 5 years ago

Last modified 5 years ago

#12046 confirmed New Feature

Using figure wrapper even if there is no caption

Reported by: Albert Skibinski Owned by:
Priority: Normal Milestone:
Component: UI : Widgets Version:
Keywords: Image2 Cc: a.nowodzinski@…

Description

First of all, big thumbs up for the new image2.plugin and also for the great inline documentation in it!

Currently, the image2 plugin only creates a figure wrapper if there is a caption. Otherwise, the default paragraph wrapper is used.

I have a use case which requires to have a figure wrapper *always*, even if there is no caption. This is mainly because we want consistency and it helps to have better styling options (now, an image can have a paragraph wrapper with or without text which leads to styling problems depending where exactly a person inserts an image).

I looked into the code to see if there is a clean way to do this, maybe through an option, but couldn't find one.

What would be the best way to approach this?

Change History (4)

comment:1 Changed 5 years ago by Piotrek Koszuliński

Cc: a.nowodzinski@… added
Keywords: Image2 added; image2 removed
Status: newconfirmed
Version: 4.4.1

Added @oleq to CC, since he's an author. I also like his ASCII art :).

If you'd be satisfied by just changing the HTML which is output from editor, then overriding image2's downcast and upcast methods would be solution. Drupal does this here:

They have two versions of image plugin - one with captions one without. Both output <img> tag with everything stored in data-* attributes. And both reuse the image2 plugin. So that's definitely doable what you want to achieve.

However, changing the way how image2 is represented inside editor is much harder, because this is implemented by a state machine which shifts one form to another (the shifting is complicated because widget changes its nature when figure is added and removed from a block to an inline element). You'll always have it as a block, so you'd actually make your implementation much, much simpler. I even think that you could get rid of 50% of the code :D

So, if changing internal representation is also important for you, then you will need to modify image2's code. How? Oleq may have more tips.

comment:2 Changed 5 years ago by Albert Skibinski

Thanks for the fast reply!

Coming from the Drupal world myself, I see what you mean with your examples. While this is an example for Drupal 8 (currently still in alpha) it should also be possible to do this using Drupal 7 with a plugin. I don't think I need to change the internals if I can alter the output.

I'll dive into it!

comment:3 Changed 5 years ago by Albert Skibinski

Allright, got it working! Posting here for reference:

Custom drupal_image2.js plugin:

// The upcast override creates a figure wrapper and put all the stuff inside it:

CKEDITOR.plugins.add( 'drupal_image2', {
    requires: 'image2',

    beforeInit: function (editor) {

      editor.on('widgetDefinition', function (event) {
        var widgetDefinition = event.data;
        if (widgetDefinition.name !== 'image') {
          return;
        }

        widgetDefinition.upcast = function (element, data) {
          if (element.name !== 'img') {
            return;
          }

          var retElement = element;

          if (element.name !== 'figure') {
            var figure = new CKEDITOR.htmlParser.element('figure');
            element.replaceWith(figure);
            figure.add(element);
            retElement = figure;
          }

          return retElement;
        };

      });

    },

});


// below function is used because I wanted to alter the dialog and is not
// mandatory for the 'figure' wrapper above.

CKEDITOR.on( 'dialogDefinition', function( ev ) {
    var dialogName = ev.data.name;
    var dialogDefinition = ev.data.definition;
    if ( dialogName == 'image2' ) {

      dialogDefinition.onShow = function () {
        // this.getContentElement("info","src").getElement().hide(); 
      }

    }
});

Just one problem with the second part (dialog alter). I'm getting a "Uncaught TypeError: Cannot read property 'data' of undefined" because of the "dialogDefinition.onShow" function, but I can't figure out why. But I'll create a seperate ticket for that.

comment:4 Changed 5 years ago by Piotrek Koszuliński

Please don't create a separate ticket for a custom plugin error, because very likely this is a bug in your code, not CKEditor.

Note: See TracTickets for help on using tickets.
© 2003 – 2019 CKSource – Frederico Knabben. All rights reserved. | Terms of use | Privacy policy