Index: wysiwyg.admin.css
===================================================================
RCS file: wysiwyg.admin.css
diff -N wysiwyg.admin.css
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ wysiwyg.admin.css 1 Feb 2011 03:52:24 -0000
@@ -0,0 +1,76 @@
+/* $Id$ */
+
+#toolbar-rows {
+ margin: 1em 0;
+}
+#toolbar-rows .toolbar-row {
+ border: 1px solid gray;
+ padding: 0.2em 0.2em 0.2em 20px;
+ min-height: 2em;
+ position: relative;
+ margin-bottom: 0.5em;
+}
+#toolbar-rows .single-group .toolbar-group {
+ border: 0;
+ margin: 0;
+ padding: 0;
+ width: 100%;
+}
+#toolbar-rows .single-group .group-handler {
+ display: none;
+}
+#toolbar-rows .toolbar-group {
+ border: 1px dotted silver;
+ display: inline-block;
+ min-width: 10em;
+ min-height: 27px;
+ padding: 0 0.5em;
+ margin: 0 0.5em 0.1em 0;
+ position: relative;
+}
+.toolbar-row-template, .toolbar-group-template {
+ display: none;
+}
+#toolbar-rows .row-handler {
+ position: absolute;
+ top: 0.2em;
+ left: 0.2em;
+}
+#toolbar-available-buttons {
+ border: 1px dashed silver;
+ padding: 0.5em;
+ margin-bottom: 1em;
+ position: relative;
+}
+#wysiwyg-toolbar-designer .add {
+ display: inline-block;
+ background: transparent url(images/add.png) no-repeat;
+ width: 16px;
+ height: 16px;
+ text-decoration: none;
+ outline: none;
+}
+#wysiwyg-toolbar-designer .add-group {
+ position: absolute;
+ right: 0.2em;
+ top: 0.2em;
+}
+#wysiwyg-toolbar-designer .handler {
+ background: url(images/draggable.png) no-repeat 0 4px;
+ width: 16px;
+ height: 16px;
+ display: inline-block;
+ text-decoration: none;
+}
+#wysiwyg-toolbar-designer .wysiwyg-button {
+ border: 1px solid silver;
+ display: inline-block;
+ margin: 0.2em 0.2em 0.2em 0;
+ padding: 0 0.5em;
+ height: 20px;
+ cursor: pointer;
+}
+#wysiwyg-toolbar-designer .ahah-progress, #wysiwyg-toolbar-designer div.warning {
+ /* Hidden by default. */
+ display: none;
+}
Index: wysiwyg.admin.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/wysiwyg/wysiwyg.admin.inc,v
retrieving revision 1.30
diff -u -p -r1.30 wysiwyg.admin.inc
--- wysiwyg.admin.inc 23 Jan 2011 01:11:12 -0000 1.30
+++ wysiwyg.admin.inc 3 Feb 2011 23:49:33 -0000
@@ -7,9 +7,9 @@
*/
/**
- * Form builder for Wysiwyg profile form.
+ * Prepare default properties for profile.
*/
-function wysiwyg_profile_form($form, &$form_state, $profile) {
+function wysiwyg_profile_default($profile) {
// Merge in defaults.
$profile = (array) $profile;
$profile += array(
@@ -27,7 +27,7 @@ function wysiwyg_profile_form($form, &$f
'language' => 'en',
'access' => 1,
'access_pages' => "node/*\nuser/*\ncomment/*",
- 'buttons' => array(),
+ 'toolbar' => array(),
'toolbar_loc' => 'top',
'toolbar_align' => 'left',
'path_loc' => 'bottom',
@@ -45,6 +45,15 @@ function wysiwyg_profile_form($form, &$f
'css_classes' => NULL,
);
$profile = (object) $profile;
+ return $profile;
+}
+
+/**
+ * Form builder for Wysiwyg profile form.
+ */
+function wysiwyg_profile_form($form, &$form_state, $profile) {
+ $profile = wysiwyg_profile_default($profile);
+ $module_path = drupal_get_path('module', 'wysiwyg');
$formats = filter_formats();
$editor = wysiwyg_get_editor($profile->editor);
@@ -111,50 +120,118 @@ function wysiwyg_profile_form($form, &$f
asort($predefined);
$form['basic']['language']['#options'] = $predefined;
- $form['buttons'] = array(
+ $form['extensions'] = array(
'#type' => 'fieldset',
- '#title' => t('Buttons and plugins'),
+ '#title' => t('Extensions'),
'#collapsible' => TRUE,
'#collapsed' => TRUE,
'#tree' => TRUE,
'#theme' => 'wysiwyg_admin_button_table',
);
+ // Retrieve all available extensions and buttons.
$plugins = wysiwyg_get_plugins($profile->editor);
- // Generate the button list.
+ $buttons = array();
foreach ($plugins as $name => $meta) {
if (isset($meta['buttons']) && is_array($meta['buttons'])) {
foreach ($meta['buttons'] as $button => $title) {
- $icon = '';
- if (!empty($meta['path'])) {
- // @todo Button icon locations are different in editors, editor versions,
- // and contrib/custom plugins (like Image Assist, f.e.).
- $img_src = $meta['path'] . "/images/$name.gif";
- // Handle plugins that have more than one button.
- if (!file_exists($img_src)) {
- $img_src = $meta['path'] . "/images/$button.gif";
- }
- $icon = file_exists($img_src) ? '
' : '';
- }
- $title = (isset($meta['url']) ? l($title, $meta['url'], array('target' => '_blank')) : $title);
- $title = (!empty($icon) ? $icon . ' ' . $title : $title);
- $form['buttons'][$name][$button] = array(
- '#type' => 'checkbox',
- '#title' => $title,
- '#default_value' => !empty($profile->settings['buttons'][$name][$button]) ? $profile->settings['buttons'][$name][$button] : FALSE,
+ $buttons[] = array(
+ 'plugin' => $name,
+ 'button' => $button,
+ 'title' => $title,
);
}
}
- else if (isset($meta['extensions']) && is_array($meta['extensions'])) {
+ if (isset($meta['extensions']) && is_array($meta['extensions'])) {
foreach ($meta['extensions'] as $extension => $title) {
- $form['buttons'][$name][$extension] = array(
+ $form['extensions'][$name][$extension] = array(
'#type' => 'checkbox',
'#title' => isset($meta['url']) ? l($title, $meta['url'], array('target' => '_blank')) : $title,
- '#default_value' => !empty($profile->settings['buttons'][$name][$extension]) ? $profile->settings['buttons'][$name][$extension] : FALSE,
+ '#default_value' => !empty($profile->settings['extensions'][$name][$extension]) ? $profile->settings['extensions'][$name][$extension] : 0,
);
}
}
}
+ // Hide the extensions fieldset if there are no extensions.
+ if (!element_children($form['extensions'])) {
+ $form['extensions']['#access'] = FALSE;
+ }
+
+ $toolbar_support = array(
+ 'toolbar' => $profile->settings['toolbar'],
+ 'toolbar rows' => !empty($editor['toolbar rows']),
+ 'toolbar groups' => !empty($editor['toolbar groups']),
+ 'toolbar separator' => !empty($editor['toolbar separator']),
+ );
+ // Separator.
+ if ($toolbar_support['toolbar separator']) {
+ array_unshift($buttons, array(
+ 'plugin' => 'default',
+ 'button' => 'separator',
+ 'title' => t('Separator'),
+ ));
+ }
+
+ $form['toolbar_designer'] = array(
+ '#type' => 'container',
+ '#id' => 'wysiwyg-toolbar-designer',
+ '#access' => !empty($buttons),
+ );
+ $form['toolbar_designer']['available'] = array(
+ '#type' => 'item',
+ '#title' => t('Available buttons'),
+ '#id' => 'toolbar-available-buttons',
+ );
+ foreach ($buttons as $button) {
+ $form['toolbar_designer']['available'][$button['plugin']][$button['button']] = array(
+ '#theme' => 'html_tag',
+ '#tag' => 'span',
+ '#value' => check_plain($button['title']),
+ '#attributes' => array('class' => array('wysiwyg-button', 'wysiwyg-button-' . $button['plugin'] . '-' . $button['button'])),
+ );
+ }
+ $form['toolbar_designer']['toolbar'] = array(
+ '#type' => 'item',
+ '#title' => t('Toolbar'),
+ );
+ $form['toolbar_designer']['toolbar']['toolbar'] = array(
+ '#markup' => '
',
+ );
+ $form['toolbar_designer']['toolbar']['actions'] = array(
+ '#type' => 'container',
+ '#id' => 'toolbar-actions',
+ );
+ $form['toolbar_designer']['toolbar']['actions']['add-row'] = array(
+ '#type' => 'link',
+ '#title' => t('Add new row'),
+ '#href' => '#',
+ '#attributes' => array(
+ 'class' => array('add', 'add-toolbar-row'),
+ ),
+ );
+ $form['toolbar_designer']['toolbar']['templates'] = array(
+ '#markup' => '
+
+',
+ );
+
+ $form['toolbar_designer']['#attached']['js'][] = array(
+ 'data' => array('wysiwyg_toolbar' => $toolbar_support),
+ 'type' => 'setting',
+ );
+ $form['toolbar_designer']['#attached']['library'][] = array('system', 'ui.droppable');
+ $form['toolbar_designer']['#attached']['library'][] = array('system', 'ui.sortable');
+ $form['toolbar_designer']['#attached']['js'][] = $module_path . '/wysiwyg.admin.js';
+ $form['toolbar_designer']['#attached']['css'][] = $module_path . '/wysiwyg.admin.css';
+ $form['toolbar_designer']['_toolbar'] = array(
+ '#type' => 'hidden',
+ '#attributes' => array('id' => 'edit-toolbar'),
+ );
$form['appearance'] = array(
'#type' => 'fieldset',
@@ -309,15 +386,44 @@ function wysiwyg_profile_form($form, &$f
* @see wysiwyg_profile_form()
*/
function wysiwyg_profile_form_submit($form, &$form_state) {
- $values = $form_state['values'];
- if (isset($values['buttons'])) {
+ $values = &$form_state['values'];
+ if (isset($values['extensions'])) {
// Store only enabled buttons for each plugin.
- foreach ($values['buttons'] as $plugin => $buttons) {
- $values['buttons'][$plugin] = array_filter($values['buttons'][$plugin]);
+ foreach ($values['extensions'] as $plugin => $buttons) {
+ $values['extensions'][$plugin] = array_filter($values['extensions'][$plugin]);
}
// Store only enabled plugins.
- $values['buttons'] = array_filter($values['buttons']);
+ $values['extensions'] = array_filter($values['extensions']);
+ }
+ else {
+ $values['extensions'] = array();
}
+
+ // Restore toolbar array
+ $raw_toolbar = explode("\n", trim($values['toolbar']));
+ $values['toolbar'] = array();
+ foreach ($raw_toolbar as $raw_row) {
+ $row = array();
+ foreach (explode('|', trim($raw_row, '|')) as $raw_group) {
+ $group = array();
+ foreach (explode(',', trim($raw_group, ',')) as $button) {
+ list($plugin, $name) = explode('.', $button, 2);
+ $group[] = array(
+ 'button' => $name,
+ 'plugin' => $plugin,
+ );
+ }
+ if ($group) {
+ $row[] = $group;
+ }
+ }
+ if ($row) {
+ $values['toolbar'][] = $row;
+ }
+ }
+ // Remove available plugins/button information.
+ unset($values['buttons']);
+
// Remove any white-space from 'block_formats' setting, since editor
// implementations rely on a comma-separated list to explode().
$values['block_formats'] = preg_replace('@\s+@', '', $values['block_formats']);
@@ -328,9 +434,8 @@ function wysiwyg_profile_form_submit($fo
$editor = $values['editor'];
unset($values['format'], $values['input_format'], $values['editor']);
- // Remove FAPI values.
- // @see system_settings_form_submit()
- unset($values['submit'], $values['form_id'], $values['op'], $values['form_token'], $values['form_build_id']);
+ // Remove internal Form API values.
+ form_state_values_clean($form_state);
// Insert new profile data.
db_merge('wysiwyg')
Index: wysiwyg.admin.js
===================================================================
RCS file: wysiwyg.admin.js
diff -N wysiwyg.admin.js
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ wysiwyg.admin.js 3 Feb 2011 23:52:32 -0000
@@ -0,0 +1,205 @@
+// $Id$
+(function ($, undefined) {
+
+Drupal.behaviors.wysiwygToolbarDesigner = {
+ attach: function (context, settings) {
+ var settings = settings.wysiwyg_toolbar;
+ var workspace = $('#wysiwyg-toolbar-designer');
+ var designArea = $('#toolbar-rows');
+ var changeNotification = $('#wysiwyg-toolbar-designer div.warning');
+ var availableButtons = $('#toolbar-available-buttons');
+ var separator = $('.wysiwyg-button-default-Separator',availableButtons);
+
+ var createRow = function(noGroup) {
+ var row = $('.toolbar-row-template',workspace).clone().removeClass('toolbar-row-template');
+ row.addClass('toolbar-row').sortable({
+ handle: '.group-handler',
+ revert: true,
+ items: '.toolbar-group',
+ addClasses: false,
+ connectWith: '#toolbar-rows .toolbar-row',
+ stop: function(event,ui) {
+ changeNotification.fadeIn();
+ }
+ });
+ if (settings['toolbar groups']) {
+ row.find('.add-group').click(function() {
+ var group = createGroup();
+ row.append(group);
+ row.sortable('refresh');
+ return false;
+ });
+ }
+ else {
+ row.find('.add-group').hide();
+ row.addClass('single-group');
+ }
+ // add required group
+ if (!noGroup) {
+ var group = createGroup();
+ row.append(group);
+ }
+ return row;
+ };
+
+ var createGroup = function() {
+ var group = $('.toolbar-group-template').clone().removeClass('toolbar-group-template');
+ group.addClass('toolbar-group');
+ group.sortable({
+ revert: true,
+ items: '.wysiwyg-button',
+ connectWith: '#toolbar-rows .toolbar-group',
+ addClasses: false,
+ stop: function(event,ui) {
+ changeNotification.fadeIn();
+ }
+ });
+
+ group.droppable({
+ accept: '.template-button',
+ drop: function(event,ui) {
+ var button = ui.draggable.clone();
+ button.removeClass('template-button').addClass('toolbar-button');
+
+ // Disable this button in template area.
+ ui.draggable.hide();
+ separator.show();
+
+ $(this).append(button).sortable('refresh');
+ changeNotification.fadeIn();
+ }
+ });
+ return group;
+ }
+
+ var reset = function() {
+ $('.toolbar-row',designArea).remove();
+ // Enable all buttons and then disable it later.
+ $('.wysiwyg-button',availableButtons).show();
+
+ for (var i in settings.toolbar) {
+ var groups = settings.toolbar[i];
+ var row = createRow(true);
+ for (var j in groups) {
+ var group = createGroup();
+ var buttons = groups[j];
+
+ for (var k in buttons) {
+ var buttonClass = '.wysiwyg-button-' + buttons[k].plugin + '-' + buttons[k].button;
+ var template_button = $(buttonClass,$('#toolbar-available-buttons'));
+ if (template_button.length) {
+ button = template_button.clone().show();
+ button.removeClass('template-button').addClass('toolbar-button');
+ group.append(button);
+
+ // Disable button in template area.
+ template_button.hide();
+ }
+ }
+ row.append(group);
+ }
+ designArea.append(row);
+ }
+ // Make sure we always have at least one row.
+ if (!settings['toolbar rows']) {
+ if ($('.toolbar-row',designArea).length <= 0) {
+ var row = createRow();
+ designArea.append(row);
+ }
+ }
+ separator.show();
+ changeNotification.fadeOut();
+ }
+
+ $('.add-toolbar-row',workspace).click(function(){
+ // clone from toolbar template
+ var row = createRow();
+
+ // Append row to design area.
+ designArea.append(row).sortable('refresh');
+ changeNotification.fadeIn();
+ return false;
+ });
+
+ $('.wysiwyg-button',availableButtons).addClass('template-button').draggable({
+ handle: '.handler',
+ helper: 'clone',
+ revert: 'invalid',
+ addClasses: false
+ });
+
+ availableButtons.droppable({
+ accept: '.toolbar-button, .toolbar-group, .toolbar-row',
+ drop: function(event, ui) {
+ var item = ui.draggable;
+ var parent = item.parent();
+
+ // Guarantee there is at least 1 row and 1 group.
+ if (item.hasClass('toolbar-row') && parent.find('.toolbar-row').not('.ui-sortable-placeholder').length == 1) {
+ return;
+ } else if (item.hasClass('toolbar-group') && parent.find('.toolbar-group').not('.ui-sortable-placeholder').length == 1) {
+ return;
+ }
+
+ var buttons = $('.toolbar-button', item);
+ if (item.hasClass('toolbar-button')) {
+ buttons.add(item);
+ }
+
+ // Remove each button and enable in template.
+ buttons.each(function(){
+ var button_id = /wysiwyg-button-([^-]+-[^\s]+)/.exec($(this).attr('class'));
+ $('.wysiwyg-button-' + button_id[1]).show();
+ });
+
+ item.parent().sortable('refresh');
+ item.remove();
+
+ changeNotification.fadeIn();
+ }
+ });
+
+ $('#toolbar-rows').sortable({
+ items: '.toolbar-row',
+ handle: '.row-handler',
+ addClass: false,
+ stop: function(event, ui) {
+ changeNotification.fadeIn();
+ }
+ });
+
+ // Design actions buttons.
+ $('#reset-design').click(function() {
+ if (!changeNotification.is(':hidden') && confirm(Drupal.t('Do you want to reset the changes ?')))
+ reset();
+ return false;
+ });
+
+ $('#wysiwyg-profile-form').submit(function() {
+ // Prepare toolbar data to submit.
+ var toolbar = "";
+ designArea.find('.toolbar-row').each(function(key,rowDom){
+ var row = "";
+ $('.toolbar-group',rowDom).each(function(key,groupDom){
+ var group = "";
+ $('.wysiwyg-button',groupDom).each(function(key,button){
+ var cls = /wysiwyg-button-([^-]+)-([^\s]+)/.exec($(button).attr('class'));
+ group += cls[1] + "." + cls[2] + ",";
+ })
+ row += group + "|";
+ });
+ toolbar += row + "\n";
+ });
+ // Assign to hidden field.
+ $('#edit-toolbar').val(toolbar);
+ });
+
+ reset();
+
+ if (!settings['toolbar rows']) {
+ $('.add-toolbar-row').hide();
+ }
+ }
+};
+
+})(jQuery);
Index: wysiwyg.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/wysiwyg/wysiwyg.module,v
retrieving revision 1.54
diff -u -p -r1.54 wysiwyg.module
--- wysiwyg.module 30 Jan 2011 04:06:47 -0000 1.54
+++ wysiwyg.module 3 Feb 2011 23:38:41 -0000
@@ -457,16 +457,17 @@ function wysiwyg_add_plugin_settings($pr
// Process native editor plugins.
if (isset($editor['plugin settings callback'])) {
- // @todo Require PHP 5.1 in 3.x and use array_intersect_key().
$profile_plugins_native = array();
- foreach ($plugins[$editor['name']] as $plugin => $meta) {
- // Skip Drupal plugins (handled below).
- if ($plugin === $proxy) {
- continue;
- }
- // Only keep native plugins that are enabled in this profile.
- if (isset($profile->settings['buttons'][$plugin])) {
- $profile_plugins_native[$plugin] = $meta;
+ foreach ($profile->settings['toolbar'] as $row) {
+ foreach ($row as $group) {
+ foreach ($group as $button) {
+ $plugin = $button['plugin'];
+ // Skip Drupal plugins (handled below).
+ if ($plugin === $proxy) {
+ continue;
+ }
+ $profile_plugins_native[$plugin] = $plugins[$plugin];
+ }
}
}
// Invoke the editor's plugin settings callback, so it can populate the
@@ -480,24 +481,32 @@ function wysiwyg_add_plugin_settings($pr
// Process Drupal plugins.
if ($proxy && isset($editor['proxy plugin settings callback'])) {
+ $drupal_plugins = wysiwyg_get_all_plugins();
$profile_plugins_drupal = array();
- foreach (wysiwyg_get_all_plugins() as $plugin => $meta) {
- if (isset($profile->settings['buttons'][$proxy][$plugin])) {
- // JavaScript and plugin-specific settings for Drupal plugins must be
- // loaded and processed only once. Plugin information is cached
- // statically to pass it to the editor's proxy plugin settings callback.
- if (!isset($processed_plugins[$proxy][$plugin])) {
- $profile_plugins_drupal[$plugin] = $processed_plugins[$proxy][$plugin] = $meta;
- // Load the Drupal plugin's JavaScript.
- drupal_add_js($meta['js path'] . '/' . $meta['js file']);
- // Add plugin-specific settings.
- if (isset($meta['settings'])) {
- drupal_add_js(array('wysiwyg' => array('plugins' => array('drupal' => array($plugin => $meta['settings'])))), 'setting');
+ foreach ($profile->settings['toolbar'] as $row) {
+ foreach ($row as $group) {
+ foreach ($group as $button) {
+ $plugin = $button['plugin'];
+ $button_id = $button['button'];
+ if ($plugin == $proxy && isset($drupal_plugins[$button_id])) {
+ $meta = $drupal_plugins[$button_id];
+ // JavaScript and plugin-specific settings for Drupal plugins must be
+ // loaded and processed only once. Plugin information is cached
+ // statically to pass it to the editor's proxy plugin settings callback.
+ if (!isset($processed_plugins[$proxy][$button_id])) {
+ $profile_plugins_drupal[$button_id] = $processed_plugins[$proxy][$button_id] = $meta;
+ // Load the Drupal plugin's JavaScript.
+ drupal_add_js($meta['js path'] . '/' . $meta['js file']);
+ // Add plugin-specific settings.
+ if (isset($meta['settings'])) {
+ drupal_add_js(array('wysiwyg' => array('plugins' => array('drupal' => array($button_id => $meta['settings'])))), 'setting');
+ }
+ }
+ else {
+ $profile_plugins_drupal[$button_id] = $processed_plugins[$proxy][$button_id];
+ }
}
}
- else {
- $profile_plugins_drupal[$plugin] = $processed_plugins[$proxy][$plugin];
- }
}
}
// Invoke the editor's proxy plugin settings callback, so it can populate
Index: editors/ckeditor.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/wysiwyg/editors/ckeditor.inc,v
retrieving revision 1.13
diff -u -p -r1.13 ckeditor.inc
--- editors/ckeditor.inc 14 Jan 2011 15:42:47 -0000 1.13
+++ editors/ckeditor.inc 1 Feb 2011 04:32:16 -0000
@@ -28,6 +28,9 @@ function wysiwyg_ckeditor_editor() {
),
),
),
+ 'toolbar groups' => TRUE,
+ 'toolbar rows' => TRUE,
+ 'toolbar separator' => TRUE,
'version callback' => 'wysiwyg_ckeditor_version',
'themes callback' => 'wysiwyg_ckeditor_themes',
'settings callback' => 'wysiwyg_ckeditor_settings',
@@ -192,49 +195,62 @@ function wysiwyg_ckeditor_settings($edit
$settings['toolbarLocation'] = $config['toolbar_loc'];
}
- $settings['toolbar'] = array();
- if (!empty($config['buttons'])) {
- $extra_plugins = array();
- $plugins = wysiwyg_get_plugins($editor['name']);
- foreach ($config['buttons'] as $plugin => $buttons) {
- foreach ($buttons as $button => $enabled) {
- // Iterate separately over buttons and extensions properties.
- foreach (array('buttons', 'extensions') as $type) {
- // Skip unavailable plugins.
- if (!isset($plugins[$plugin][$type][$button])) {
- continue;
- }
- // Add buttons.
- if ($type == 'buttons') {
- $settings['toolbar'][] = $button;
- }
- // Add external Drupal plugins to the list of extensions.
- if ($type == 'buttons' && !empty($plugins[$plugin]['proxy'])) {
- $extra_plugins[] = $button;
- }
- // Add external plugins to the list of extensions.
- elseif ($type == 'buttons' && empty($plugins[$plugin]['internal'])) {
- $extra_plugins[] = $plugin;
- }
- // Add internal buttons that also need to be loaded as extension.
- elseif ($type == 'buttons' && !empty($plugins[$plugin]['load'])) {
- $extra_plugins[] = $plugin;
- }
- // Add plain extensions.
- elseif ($type == 'extensions' && !empty($plugins[$plugin]['load'])) {
- $extra_plugins[] = $plugin;
- }
- // Allow plugins to add or override global configuration settings.
- if (!empty($plugins[$plugin]['options'])) {
- $settings = array_merge($settings, $plugins[$plugin]['options']);
- }
- }
+ $toolbar = array();
+ $extra_plugins = array();
+ $plugins = wysiwyg_get_plugins($editor['name']);
+ foreach ($config['extensions'] as $plugin => $buttons) {
+ foreach ($buttons as $button => $enabled) {
+ if (!isset($plugins[$plugin]['extensions'][$button])) {
+ continue;
+ }
+ // Add plain extensions.
+ if (!empty($plugins[$plugin]['load'])) {
+ $extra_plugins[] = $plugin;
+ }
+ // Allow plugins to add or override global configuration settings.
+ if (!empty($plugins[$plugin]['options'])) {
+ $settings = array_merge($settings, $plugins[$plugin]['options']);
}
}
- if (!empty($extra_plugins)) {
- $settings['extraPlugins'] = implode(',', $extra_plugins);
+ }
+
+ foreach ($config['toolbar'] as $row) {
+ foreach ($row as $buttons) {
+ $group = array();
+ foreach ($buttons as $button_config) {
+ $plugin = $button_config['plugin'];
+ $button = $button_config['button'];
+ if ($button == 'separator') {
+ $group[] = '-';
+ continue;
+ }
+ if (!isset($plugins[$plugin]['buttons'][$button])) {
+ continue;
+ }
+ $group[] = $button;
+
+ // Add external Drupal plugins to the list of extensions.
+ if (!empty($plugins[$plugin]['proxy']) || empty($plugins[$plugin]['internal']) || !empty($plugins[$plugin]['load'])) {
+ $extra_plugins[] = $button;
+ }
+ // Allow plugins to add or override global configuration settings.
+ if (!empty($plugins[$plugin]['options'])) {
+ $settings = array_merge($settings, $plugins[$plugin]['options']);
+ }
+ }
+ $toolbar[] = $group;
}
+ $toolbar[] = '/';
}
+
+ // Remove the last '/'.
+ array_pop($toolbar);
+ $settings['toolbar'] = $toolbar;
+
+ if (!empty($extra_plugins)) {
+ $settings['extraPlugins'] = implode(',', array_unique($extra_plugins));
+ }
+
// For now, all buttons are placed into one row.
$settings['toolbar'] = array($settings['toolbar']);
Index: editors/fckeditor.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/wysiwyg/editors/fckeditor.inc,v
retrieving revision 1.22
diff -u -p -r1.22 fckeditor.inc
--- editors/fckeditor.inc 19 Dec 2010 23:26:56 -0000 1.22
+++ editors/fckeditor.inc 1 Feb 2011 04:36:49 -0000
@@ -20,6 +20,9 @@ function wysiwyg_fckeditor_editor() {
'files' => array('fckeditor.js'),
),
),
+ 'toolbar groups' => TRUE,
+ 'toolbar rows' => TRUE,
+ 'toolbar separator' => TRUE,
'version callback' => 'wysiwyg_fckeditor_version',
'themes callback' => 'wysiwyg_fckeditor_themes',
'settings callback' => 'wysiwyg_fckeditor_settings',
@@ -139,32 +142,47 @@ function wysiwyg_fckeditor_settings($edi
// Use our custom toolbar set.
$settings['ToolbarSet'] = 'Wysiwyg';
- // Populate our custom toolbar set for fckeditor.config.js.
- $settings['buttons'] = array();
- if (!empty($config['buttons'])) {
- $plugins = wysiwyg_get_plugins($editor['name']);
- foreach ($config['buttons'] as $plugin => $buttons) {
- foreach ($buttons as $button => $enabled) {
- // Iterate separately over buttons and extensions properties.
- foreach (array('buttons', 'extensions') as $type) {
- // Skip unavailable plugins.
- if (!isset($plugins[$plugin][$type][$button])) {
- continue;
- }
- // Add buttons.
- if ($type == 'buttons') {
- $settings['buttons'][] = $button;
- }
- // Allow plugins to add or override global configuration settings.
- if (!empty($plugins[$plugin]['options'])) {
- $settings = array_merge($settings, $plugins[$plugin]['options']);
- }
+ $toolbar = array();
+ $plugins = wysiwyg_get_plugins($editor['name']);
+ foreach ($config['extensions'] as $plugin => $buttons) {
+ foreach ($buttons as $button => $enabled) {
+ if (!isset($plugins[$plugin]['extensions'][$button])) {
+ continue;
+ }
+ // Allow plugins to add or override global configuration settings.
+ if (!empty($plugins[$plugin]['options'])) {
+ $settings = array_merge($settings, $plugins[$plugin]['options']);
+ }
+ }
+ }
+
+ foreach ($config['toolbar'] as $row) {
+ foreach ($row as $buttons) {
+ $group = array();
+ foreach ($buttons as $button_config) {
+ $plugin = $button_config['plugin'];
+ $button = $button_config['button'];
+ if ($button == 'separator') {
+ $group[] = '-';
+ continue;
+ }
+ if (!isset($plugins[$plugin]['buttons'][$button])) {
+ continue;
+ }
+ $group[] = $button;
+ // Allow plugins to add or override global configuration settings.
+ if (!empty($plugins[$plugin]['options'])) {
+ $settings = array_merge($settings, $plugins[$plugin]['options']);
}
}
+ $toolbar[] = $group;
}
+ $toolbar[] = '/';
}
- // For now, all buttons are placed into one row.
- $settings['buttons'] = array($settings['buttons']);
+ // Remove the last '/'.
+ array_pop($toolbar);
+
+ $settings['ToolbarSets']['Wysiwyg'] = $toolbar;
return $settings;
}
Index: editors/markitup.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/wysiwyg/editors/markitup.inc,v
retrieving revision 1.12
diff -u -p -r1.12 markitup.inc
--- editors/markitup.inc 19 Dec 2010 19:19:56 -0000 1.12
+++ editors/markitup.inc 31 Jan 2011 04:22:59 -0000
@@ -156,11 +156,11 @@ function wysiwyg_markitup_settings($edit
),
);
$settings['markupSet'] = array();
- if (!empty($config['buttons'])) {
- foreach ($config['buttons'] as $plugin) {
- foreach ($plugin as $button => $enabled) {
- if (isset($default_buttons[$button])) {
- $settings['markupSet'][$button] = $default_buttons[$button];
+ if (!empty($config['toolbar'])) {
+ foreach ($config['toolbar'] as $row) {
+ foreach ($row as $group) {
+ foreach ($group as $button) {
+ $settings['markupSet'][$button['button']] = $default_buttons[$button['button']];
}
}
}
Index: editors/nicedit.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/wysiwyg/editors/nicedit.inc,v
retrieving revision 1.8
diff -u -p -r1.8 nicedit.inc
--- editors/nicedit.inc 13 Nov 2010 18:31:20 -0000 1.8
+++ editors/nicedit.inc 1 Feb 2011 04:38:42 -0000
@@ -67,12 +67,16 @@ function wysiwyg_nicedit_settings($edito
// Add configured buttons or all available.
$settings['buttonList'] = array();
- if (!empty($config['buttons'])) {
+ if (!empty($config['toolbar'])) {
$buttons = array();
- foreach ($config['buttons'] as $plugin) {
- $buttons = array_merge($buttons, $plugin);
+ foreach ($config['toolbar'] as $row) {
+ foreach ($row as $group) {
+ foreach ($group as $button) {
+ $buttons[] = $button['button'];
+ }
+ }
}
- $settings['buttonList'] = array_keys($buttons);
+ $settings['buttonList'] = $buttons;
}
// Add editor content stylesheet.
Index: editors/openwysiwyg.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/wysiwyg/editors/openwysiwyg.inc,v
retrieving revision 1.7
diff -u -p -r1.7 openwysiwyg.inc
--- editors/openwysiwyg.inc 13 Nov 2010 18:31:21 -0000 1.7
+++ editors/openwysiwyg.inc 1 Feb 2011 04:39:59 -0000
@@ -21,6 +21,8 @@ function wysiwyg_openwysiwyg_editor() {
'files' => array('wysiwyg.js'),
),
),
+ 'toolbar rows' => TRUE,
+ 'toolbar separator' => TRUE,
'version callback' => 'wysiwyg_openwysiwyg_version',
'themes callback' => 'wysiwyg_openwysiwyg_themes',
'settings callback' => 'wysiwyg_openwysiwyg_settings',
@@ -109,21 +111,25 @@ function wysiwyg_openwysiwyg_settings($e
}
$settings['Toolbar'] = array();
- if (!empty($config['buttons'])) {
+ if (!empty($config['toolbar'])) {
$plugins = wysiwyg_get_plugins($editor['name']);
- foreach ($config['buttons'] as $plugin => $buttons) {
- foreach ($buttons as $button => $enabled) {
- foreach (array('buttons', 'extensions') as $type) {
+ foreach ($config['toolbar'] as $row) {
+ $toolbar_row = array();
+ foreach ($row as $buttons) {
+ foreach ($buttons as $button_config) {
// Skip unavailable plugins.
- if (!isset($plugins[$plugin][$type][$button])) {
- continue;
+ $plugin = $button_config['plugin'];
+ $button = $button_config['button'];
+ if ($button == 'separator') {
+ $toolbar_row[] = 'seperator';
}
- // Add buttons.
- if ($type == 'buttons') {
- $settings['Toolbar'][0][] = $button;
+ elseif (!isset($plugins[$plugin]['buttons'][$button])) {
+ continue;
}
+ $toolbar_row[] = $button;
}
}
+ $settings['Toolbar'][] = $toolbar_row;
}
}
Index: editors/tinymce.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/wysiwyg/editors/tinymce.inc,v
retrieving revision 1.48
diff -u -p -r1.48 tinymce.inc
--- editors/tinymce.inc 3 Feb 2011 11:46:02 -0000 1.48
+++ editors/tinymce.inc 3 Feb 2011 22:19:01 -0000
@@ -27,6 +27,8 @@ function wysiwyg_tinymce_editor() {
'files' => array('tiny_mce_src.js'),
),
),
+ 'toolbar rows' => TRUE,
+ 'toolbar separator' => TRUE,
'version callback' => 'wysiwyg_tinymce_version',
'themes callback' => 'wysiwyg_tinymce_themes',
'settings callback' => 'wysiwyg_tinymce_settings',
@@ -195,69 +197,72 @@ function wysiwyg_tinymce_settings($edito
}
}
- // Find the enabled buttons and the button row they belong on.
- // Also map the plugin metadata for each button.
- // @todo What follows is a pain; needs a rewrite.
- // $settings['buttons'] are stacked into $settings['theme_advanced_buttons1']
- // later.
- $settings['buttons'] = array();
- if (!empty($config['buttons']) && is_array($config['buttons'])) {
- // Only array keys in $settings['extensions'] matter; added to
- // $settings['plugins'] later.
- $settings['extensions'] = array();
- // $settings['extended_valid_elements'] are just stacked, unique'd later,
- // and transformed into a comma-separated string in
- // wysiwyg_add_editor_settings().
- // @todo Needs a complete plugin API redesign using arrays for
- // tag => attributes definitions and array_merge_recursive().
- $settings['extended_valid_elements'] = array();
-
- $plugins = wysiwyg_get_plugins($editor['name']);
- foreach ($config['buttons'] as $plugin => $buttons) {
- foreach ($buttons as $button => $enabled) {
- // Iterate separately over buttons and extensions properties.
- foreach (array('buttons', 'extensions') as $type) {
- // Skip unavailable plugins.
- if (!isset($plugins[$plugin][$type][$button])) {
- continue;
- }
- // Add buttons.
- if ($type == 'buttons') {
- $settings['buttons'][] = $button;
- }
- // Add external Drupal plugins to the list of extensions.
- if ($type == 'buttons' && !empty($plugins[$plugin]['proxy'])) {
- $settings['extensions'][_wysiwyg_tinymce_plugin_name('add', $button)] = 1;
- }
- // Add external plugins to the list of extensions.
- else if ($type == 'buttons' && empty($plugins[$plugin]['internal'])) {
- $settings['extensions'][_wysiwyg_tinymce_plugin_name('add', $plugin)] = 1;
- }
- // Add internal buttons that also need to be loaded as extension.
- else if ($type == 'buttons' && !empty($plugins[$plugin]['load'])) {
- $settings['extensions'][$plugin] = 1;
- }
- // Add plain extensions.
- else if ($type == 'extensions' && !empty($plugins[$plugin]['load'])) {
- $settings['extensions'][$plugin] = 1;
- }
- // Allow plugins to add valid HTML elements.
- if (!empty($plugins[$plugin]['extended_valid_elements'])) {
- $settings['extended_valid_elements'] = array_merge($settings['extended_valid_elements'], $plugins[$plugin]['extended_valid_elements']);
- }
- // Allow plugins to add or override global configuration settings.
- if (!empty($plugins[$plugin]['options'])) {
- $settings = array_merge($settings, $plugins[$plugin]['options']);
- }
- }
+ $toolbar = array();
+ $extensions = array();
+ $settings['extended_valid_elements'] = array();
+
+ $plugins = wysiwyg_get_plugins($editor['name']);
+ foreach ($config['extensions'] as $plugin => $buttons) {
+ foreach ($buttons as $button => $enabled) {
+ if (!isset($plugins[$plugin], $plugins[$plugin]['extensions'], $plugins[$plugin]['extensions'][$button])) {
+ continue;
+ }
+ // Add plain extensions.
+ if (!empty($plugins[$plugin]['load'])) {
+ $extensions[$plugin] = 1;
+ }
+ // Allow plugins to add valid HTML elements.
+ if (!empty($plugins[$plugin]['extended_valid_elements'])) {
+ $settings['extended_valid_elements'] = array_merge($settings['extended_valid_elements'], $plugins[$plugin]['extended_valid_elements']);
+ }
+ // Allow plugins to add or override global configuration settings.
+ if (!empty($plugins[$plugin]['options'])) {
+ $settings = array_merge($settings, $plugins[$plugin]['options']);
}
}
- // Clean-up.
- $settings['extended_valid_elements'] = array_unique($settings['extended_valid_elements']);
- if ($settings['extensions']) {
- $settings['plugins'] = array_keys($settings['extensions']);
+ }
+
+ foreach ($config['toolbar'] as $row) {
+ $group = array();
+ foreach ($row as $buttons) {
+ foreach ($buttons as $button_config) {
+ $plugin = $button_config['plugin'];
+ $button = $button_config['button'];
+ if ($button == 'separator') {
+ $group[] = '|';
+ continue;
+ }
+ if (!isset($plugins[$plugin]['buttons'][$button])) {
+ continue;
+ }
+ $group[] = $button;
+ // Add external Drupal plugins to the list of extensions.
+ if (!empty($plugins[$plugin]['proxy'])) {
+ $extensions[_wysiwyg_tinymce_plugin_name('add', $button)] = 1;
+ }
+ // Add external plugins to the list of extensions.
+ elseif (empty($plugins[$plugin]['internal'])) {
+ $extensions[_wysiwyg_tinymce_plugin_name('add', $plugin)] = 1;
+ }
+ // Add internal buttons that also need to be loaded as extension.
+ elseif (!empty($plugins[$plugin]['load'])) {
+ $extensions[$plugin] = 1;
+ }
+ // Allow plugins to add or override global configuration settings.
+ if (!empty($plugins[$plugin]['options'])) {
+ $settings = array_merge($settings, $plugins[$plugin]['options']);
+ }
+ // Allow plugins to add valid HTML elements.
+ if (!empty($plugins[$plugin]['extended_valid_elements'])) {
+ $settings['extended_valid_elements'] = array_merge($settings['extended_valid_elements'], $plugins[$plugin]['extended_valid_elements']);
+ }
+ }
}
- unset($settings['extensions']);
+ $toolbar[] = $group;
+ }
+ $settings['extended_valid_elements'] = array_unique($settings['extended_valid_elements']);
+ if ($extensions) {
+ $settings['plugins'] = array_keys($extensions);
}
// Add theme-specific settings.
@@ -274,7 +279,7 @@ function wysiwyg_tinymce_settings($edito
if (isset($config['block_formats'])) {
$settings['theme_advanced_blockformats'] = $config['block_formats'];
}
- if (isset($settings['buttons'])) {
+ if ($toolbar) {
// These rows explicitly need to be set to be empty, otherwise TinyMCE
// loads its default buttons of the advanced theme for each row.
$settings += array(
@@ -282,14 +287,14 @@ function wysiwyg_tinymce_settings($edito
'theme_advanced_buttons2' => array(),
'theme_advanced_buttons3' => array(),
);
- // @todo Allow to sort/arrange editor buttons.
- for ($i = 0; $i < count($settings['buttons']); $i++) {
- $settings['theme_advanced_buttons1'][] = $settings['buttons'][$i];
+ for ($i = 0; $i < count($toolbar); $i++) {
+ foreach ($toolbar[$i] as $button) {
+ $settings['theme_advanced_buttons' . ($i + 1)][] = $button;
+ }
}
}
break;
}
- unset($settings['buttons']);
// Convert the config values into the form expected by TinyMCE.
$csv_settings = array('plugins', 'extended_valid_elements', 'theme_advanced_buttons1', 'theme_advanced_buttons2', 'theme_advanced_buttons3');
Index: editors/css/tinymce-2.css
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/wysiwyg/editors/css/tinymce-2.css,v
retrieving revision 1.2
diff -u -p -r1.2 tinymce-2.css
--- editors/css/tinymce-2.css 29 Oct 2008 00:35:11 -0000 1.2
+++ editors/css/tinymce-2.css 1 Feb 2011 04:37:38 -0000
@@ -7,22 +7,3 @@ table.mceEditor {
clear: left;
}
-/**
- * Align all buttons and separators in a single row, so they wrap into multiple
- * rows if required.
- */
-.mceToolbarTop a, .mceToolbarBottom a {
- float: left;
-}
-.mceSeparatorLine {
- float: left;
- margin-top: 3px;
-}
-.mceSelectList {
- float: left;
- margin-bottom: 1px;
-}
-/* Place table plugin buttons into new row */
-#mce_editor_0_table, #mce_editor_1_table {
- clear: left;
-}
Index: editors/css/tinymce-3.css
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/wysiwyg/editors/css/tinymce-3.css,v
retrieving revision 1.3
diff -u -p -r1.3 tinymce-3.css
--- editors/css/tinymce-3.css 29 Oct 2008 00:35:11 -0000 1.3
+++ editors/css/tinymce-3.css 1 Feb 2011 04:37:31 -0000
@@ -7,19 +7,3 @@ table.mceLayout {
clear: left;
}
-/**
- * Align all buttons and separators in a single row, so they wrap into multiple
- * rows if required.
- */
-.mceToolbar td {
- display: inline;
-}
-.mceToolbar a,
-.mceSeparator {
- float: left;
-}
-.mceListBox,
-.mceSplitButton {
- float: left;
- margin-bottom: 1px;
-}
Index: editors/js/fckeditor.config.js
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/wysiwyg/editors/js/fckeditor.config.js,v
retrieving revision 1.7
diff -u -p -r1.7 fckeditor.config.js
--- editors/js/fckeditor.config.js 29 Sep 2009 01:48:23 -0000 1.7
+++ editors/js/fckeditor.config.js 31 Jan 2011 04:22:59 -0000
@@ -17,28 +17,7 @@ var pluginSettings = (Drupal.settings.wy
* Apply format-specific settings.
*/
for (var setting in wysiwygSettings) {
- if (setting == 'buttons') {
- // Apply custom Wysiwyg toolbar for this format.
- // FCKConfig.ToolbarSets['Wysiwyg'] = wysiwygSettings.buttons;
-
- // Temporarily stack buttons into multiple button groups and remove
- // separators until #277954 is solved.
- FCKConfig.ToolbarSets['Wysiwyg'] = [];
- for (var i = 0; i < wysiwygSettings.buttons[0].length; i++) {
- FCKConfig.ToolbarSets['Wysiwyg'].push([wysiwygSettings.buttons[0][i]]);
- }
- FCKTools.AppendStyleSheet(document, '#xToolbar .TB_Start { display:none; }');
- // Set valid height of select element in silver and office2003 skins.
- if (FCKConfig.SkinPath.match(/\/office2003\/$/)) {
- FCKTools.AppendStyleSheet(document, '#xToolbar .SC_FieldCaption { height: 24px; } #xToolbar .TB_End { display: none; }');
- }
- else if (FCKConfig.SkinPath.match(/\/silver\/$/)) {
- FCKTools.AppendStyleSheet(document, '#xToolbar .SC_FieldCaption { height: 27px; }');
- }
- }
- else {
- FCKConfig[setting] = wysiwygSettings[setting];
- }
+ FCKConfig[setting] = wysiwygSettings[setting];
}
/**
Index: editors/js/tinymce-3.js
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/wysiwyg/editors/js/tinymce-3.js,v
retrieving revision 1.22
diff -u -p -r1.22 tinymce-3.js
--- editors/js/tinymce-3.js 17 Oct 2010 20:52:40 -0000 1.22
+++ editors/js/tinymce-3.js 31 Jan 2011 04:22:59 -0000
@@ -51,15 +51,6 @@ Drupal.wysiwyg.editor.attach.tinymce = f
ed.onEvent.add(function(ed, e) {
Drupal.wysiwyg.activeId = ed.id;
});
- // Make toolbar buttons wrappable (required for IE).
- ed.onPostRender.add(function (ed) {
- var $toolbar = $('');
- $('#' + ed.editorContainer + ' table.mceToolbar > tbody > tr > td').each(function () {
- $('').addClass(this.className).append($(this).children()).appendTo($toolbar);
- });
- $('#' + ed.editorContainer + ' table.mceLayout td.mceToolbar').append($toolbar);
- $('#' + ed.editorContainer + ' table.mceToolbar').remove();
- });
// Remove TinyMCE's internal mceItem class, which was incorrectly added to
// submitted content by Wysiwyg <2.1. TinyMCE only temporarily adds the class
Index: images/add.png
===================================================================
RCS file: images/add.png
diff -N images/add.png
Binary files /dev/null and add.png differ
Index: images/draggable.png
===================================================================
RCS file: images/draggable.png
diff -N images/draggable.png
Binary files /dev/null and draggable.png differ
Index: images/remove.png
===================================================================
RCS file: images/remove.png
diff -N images/remove.png
Binary files /dev/null and remove.png differ