Use case:
I just drop an atom (image) from the library in my ckeditor text area.
I would like to right align this image without having the text at the left of it:

.dnd-atom-wrapper{
	float: right;
	margin-left: 100%;
}

But I would like to have this behaviour ONLY for this image.
Thus, it would be nice to have the opportunity to add a class and/or style definition in the atom property dialog.

Comments

nagy.balint’s picture

Usually the atom properties dialog is handled by content editors. So it is maybe not the best to simply include a textbox to define additional css classes in that dialog.

I have the following ideas:
- An extra select option which would define whether to have a clear after the float for each type of alignment.

- Or simply to add an atom specific class to the wrapper automatically, like scald-atom-156 so the atom with the sid 156 would have that class. Then css rules could be defined for that single atom. However maybe the issue is in this case that then each time such a behavior is needed you would need to specify rules for it.

gifad’s picture

How to implement

- An extra select option

Sample (real) code to implement a framing option :
Two steps :
1 - Override atomProperties.js, or inject definition (like scald_image.module do)

          id: 'cmbBorder',
          type: 'select',
          label: 'Border',
          items: [['None', 'none'], ['Line', 'line'], ['Frame', 'frame']],
          setup: function(widget) {
            var options = JSON.parse(widget.data.options);
            if (options.border && options.border != '')
              this.setValue(options.border);
            else
              this.setValue('none');
          },
          commit: function(widget) {
            var options = JSON.parse(widget.data.options);
            var value = this.getValue();
            if (value == 'none')
              delete options.border;
            else
              options.border = value;
            widget.setData('options', JSON.stringify(options));
          }

2 - override the theme function :

function your_override_of_theme_mee_widget_embed($vars) {
  $options = $vars['options'];
  if ($options && is_array($decoded = drupal_json_decode($options))) {
    $options = $decoded;
  }
  else {
    $options = NULL;
  }
  $border = 'none';
...
  if ($options) {
    if (!empty($options['border'])) {
      $border = $options['border'];
    }
...
  $classes = array('dnd-widget-wrapper', 'context-' . $vars['context'], 'type-' . $vars['atom']->type);
  if ($vars['align'] != 'none') {
    $classes[] = 'atom-align-' . $vars['align'];
  }
  if ($border != 'none') {
    $classes[] = 'atom-border-' . $border;
  }
...

finally, write the corresponding css rules...

Now, should scald core implement a generic "Additional classes" textfield to the standard atomProperties dialog ?

nagy.balint’s picture

I think additional classes should not be on a dialog that is meant for content editors and not for site builders.

However we can consider this extra option.

nagy.balint’s picture

@gifad : can you describe what 'Line' and 'Frame' means in this context?

gifad’s picture

@nagy.balint :

.dnd-widget-wrapper {
  border: 1px solid transparent;
	border-radius: 3px;
}
.dnd-widget-wrapper.atom-border-line {
  border: 1px solid #ccc;
}
.dnd-widget-wrapper.atom-border-frame {
  border: 1px solid #ddd;
  background-color: #eee;
}

NB: there is actually a "CSS class" textfield in the "Advanced" tab of the CKEditor image plugin, which is (or at least was) targeted to the end user;
In the new image2 plugin, though, those "advanced options" have disappeared - the official word from CKEditor team is : "We provide only basic, simple options, and allow site builders to easily develop specific options, targeted to their users..."
Now it depends on how you define "easy"...

dunebl’s picture

@gifad
Many thanks for your example...
But I have to say that I don't understand what to do exactly...

@nagy.balint
I don't agree with you: If a textbox exists for adding class and/or style name, this will not add complexity for the content editor. If he/she doesn't understand how to use it, he/she will not use it... Maybe after some time he/she will do some progress and will start to play with it. Another example is the CKEditor create table button which also contains several textbox to add class name or style (and even ID) in the advanced tab of the "table property" dialog.
Thus, creating an advanced tab for the "Atom property" dialog would be a way to hide the complexity for the starter editor.

nagy.balint’s picture

Well an advanced tab could be a good idea as well.

@jcisio what do you think?

jcisio’s picture

Yes an advanced tab is a nice idea.

nagy.balint’s picture

Status: Active » Needs review
StatusFileSize
new3.17 KB

Based on @gifad 's approach, here is a patch which will add a new tab besides the main tab, where the user can fill in css classes. The classes are stored in the options since there is no other way to get the information to the widget embed function.

Also the functionality will only work with the dndck4 plugin with the widgets.

  • nagy.balint committed b8988e6 on 7.x-1.x
    Issue #2512728 by nagy.balint, DuneBL, gifad: Add a css class or style...
nagy.balint’s picture

Status: Needs review » Fixed

Thanks, Committed.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.

scotwith1t’s picture

What would the proper way be to HIDE this tab if we want to? I would like to customize the dialog box and hiding this tab is one of the things the client has requested. I know it's fairly simple, but seems to be completely different from before with the sas syntax. Any tips on customizing the dialog box behavior?

gifad’s picture

scotself : try this hack :

(function($) {
  if (typeof CKEDITOR !== "undefined") {
    CKEDITOR.on('dialogDefinition', function(ev) {
        if (ev.data.name == 'atomProperties') {
          var dialogDefinition = ev.data.definition;
          delete dialogDefinition.contents[1];
        }
    });
  }
}(jQuery));
scotwith1t’s picture

Thanks gifad. I actually figured it out. Similar, for sure but uses a little more of the CKEditor's functions. First, in:

/**
 * Implements hook_field_widget_form_alter().
 */
function scald_customizations_field_widget_form_alter(&$element, &$form_state, $context) {
  if (isset($element['#attributes']['data-dnd-context'])) {
    $path = drupal_get_path('module', 'scald_customizations');
    $element['#attached']['js'][] = $path . '/scald_customizations_.js';
    $element['#attributes']['class'][] = 'dnd-enabled';
  }
}

So my dnd-enabled widgets have a class on them, which is helpful for:

(function($) {

  Drupal.behaviors.scaldCustomizations = {
    attach: function(context, settings) {

      $('.dnd-enabled', context).once('dnd-field', function() {
        CKEDITOR.on('dialogDefinition', function(e) {

          // Take the dialog name and its definition from the event data.
          var dialog = e.data.definition;
          if (e.data.name == 'atomProperties') {
            dialog.minHeight = 100;
            dialog.minWidth = 100;
            dialog.title = 'Change layout';

            // Remove the 'Advanced' tab.
            dialog.removeContents('advanced');

            // Get a reference to the 'Link Info' tab.
            var infoTab = dialog.getContents('info');
            // Remove unnecessary widgets from the 'Info' tab.
            infoTab.remove('cmbAlign');
            infoTab.remove('chkCaption');

          }
          dialog.onShow = function() {
            var atomProperties = this;
            var widget = e.editor.widgets.focused;
            var sid = Drupal.dnd.Atoms[widget.data.sid].sid;

            // Make our box nice and small.
            atomProperties.resize(100, 100);

            // Get the link field, set the link to the atom's page and hide it.
            var linkField = atomProperties.getContentElement('info', 'txtLink');
            linkField.setValue('/atom/' + sid);
            linkField.getElement().hide();
          }

        });

        CKEDITOR.on('instanceReady', function (e) { e.editor.removeMenuItem('Advanced'); });

      });
    }
  }
})(jQuery);

Hope that helps someone. :)