diff options
Diffstat (limited to 'modules')
-rw-r--r-- | modules/block/block-admin-display-form.tpl.php | 39 | ||||
-rw-r--r-- | modules/block/block-rtl.css | 15 | ||||
-rw-r--r-- | modules/block/block.admin.inc | 166 | ||||
-rw-r--r-- | modules/block/block.css | 17 | ||||
-rw-r--r-- | modules/block/block.js | 95 | ||||
-rw-r--r-- | modules/block/block.module | 7 | ||||
-rw-r--r-- | modules/system/system.css | 48 |
7 files changed, 215 insertions, 172 deletions
diff --git a/modules/block/block-admin-display-form.tpl.php b/modules/block/block-admin-display-form.tpl.php index f7bf2e030..2a20ff4e0 100644 --- a/modules/block/block-admin-display-form.tpl.php +++ b/modules/block/block-admin-display-form.tpl.php @@ -6,13 +6,14 @@ * Default theme implementation to configure blocks. * * Available variables: - * - $block_listing: An array of block controls within regions. + * - $block_regions: An array of regions. Keyed by name with the title as value. + * - $block_listing: An array of blocks keyed by region and then delta. * - $form_submit: Form submit button. * - $throttle: TRUE or FALSE depending on throttle module being enabled. * - * Each $data in $block_listing contains: - * - $data->is_region_first: TRUE or FALSE depending on the listed blocks - * positioning. Used here to insert a region header. + * Each $block_listing[$region] contains an array of blocks for that region. + * + * Each $data in $block_listing[$region] contains: * - $data->region_title: Region title for the listed block. * - $data->block_title: Block title. * - $data->region_select: Drop-down menu for assigning a region. @@ -25,9 +26,15 @@ * @see theme_block_admin_display() */ ?> -<?php drupal_add_js('misc/tableheader.js'); ?> -<?php print $messages; ?> - +<?php + // Add table javascript. + drupal_add_js('misc/tableheader.js'); + drupal_add_js(drupal_get_path('module', 'block') .'/block.js'); + foreach ($block_regions as $region => $title) { + drupal_add_tabledrag('blocks', 'match', 'sibling', 'block-region-select', 'block-region-'. $region, NULL, FALSE); + drupal_add_tabledrag('blocks', 'order', 'sibling', 'block-weight', 'block-weight-'. $region); + } +?> <table id="blocks"> <thead> <tr> @@ -42,15 +49,16 @@ </thead> <tbody> <?php $row = 0; ?> - <?php foreach ($block_listing as $data): ?> - <?php if ($data->is_region_first): ?> - <tr class="<?php print $row % 2 == 0 ? 'odd' : 'even'; ?>"> - <td colspan="<?php print $throttle ? '7' : '6'; ?>" class="region"><?php print $data->region_title; ?></td> + <?php foreach ($block_regions as $region => $title): ?> + <tr class="region region-<?php print $region?>"> + <td colspan="<?php print $throttle ? '6' : '5'; ?>" class="region"><?php print $title; ?></td> </tr> - <?php $row++; ?> - <?php endif; ?> - <tr class="<?php print $row % 2 == 0 ? 'odd' : 'even'; ?><?php print $data->row_class ? ' '. $data->row_class : ''; ?>"> - <td class="block"><?php print $data->block_title; ?><?php print $data->block_modified ? '<span class="warning">*</span>' : ''; ?></td> + <tr class="region-message region-<?php print $region?>-message <?php print empty($block_listing[$region]) ? 'region-empty' : 'region-populated'; ?>"> + <td colspan="<?php print $throttle ? '6' : '5'; ?>"><em><?php print t('No blocks in this region'); ?></em></td> + </tr> + <?php foreach ($block_listing[$region] as $delta => $data): ?> + <tr class="draggable <?php print $row % 2 == 0 ? 'odd' : 'even'; ?><?php print $data->row_class ? ' '. $data->row_class : ''; ?>"> + <td class="block"><?php print $data->block_title; ?></td> <td><?php print $data->region_select; ?></td> <td><?php print $data->weight_select; ?></td> <?php if ($throttle): ?> @@ -60,6 +68,7 @@ <td><?php print $data->delete_link; ?></td> </tr> <?php $row++; ?> + <?php endforeach; ?> <?php endforeach; ?> </tbody> </table> diff --git a/modules/block/block-rtl.css b/modules/block/block-rtl.css deleted file mode 100644 index b43e9cd29..000000000 --- a/modules/block/block-rtl.css +++ /dev/null @@ -1,15 +0,0 @@ -/* $Id$ */ - -#blocks td.block { - padding-left: inherit; - padding-right: 1.5em; -} -#blocks select { - margin-left: 24px; -} -#blocks select.progress-disabled { - margin-left: 0px; -} -#blocks .progress .bar { - float: right; -} diff --git a/modules/block/block.admin.inc b/modules/block/block.admin.inc index be886fd44..a90264075 100644 --- a/modules/block/block.admin.inc +++ b/modules/block/block.admin.inc @@ -36,16 +36,14 @@ function block_admin_display_form(&$form_state, $blocks, $theme = NULL) { init_theme(); $throttle = module_exists('throttle'); - $block_regions = array(BLOCK_REGION_NONE => '<'. t('none') .'>') + system_region_list($theme_key); + $block_regions = system_region_list($theme_key) + array(BLOCK_REGION_NONE => '<'. t('none') .'>'); // Build form tree $form = array( '#action' => arg(3) ? url('admin/build/block/list/'. $theme_key) : url('admin/build/block'), '#tree' => TRUE, - '#cache' => TRUE, - '#prefix' => '<div id="block-admin-display-form-wrapper">', - '#suffix' => '</div>', ); + foreach ($blocks as $i => $block) { $key = $block['module'] .'_'. $block['delta']; $form[$key]['module'] = array( @@ -69,7 +67,7 @@ function block_admin_display_form(&$form_state, $blocks, $theme = NULL) { ); $form[$key]['region'] = array( '#type' => 'select', - '#default_value' => $block['status'] ? (isset($block['region']) ? $block['region'] : system_default_region($theme_key)) : BLOCK_REGION_NONE, + '#default_value' => $block['region'], '#options' => $block_regions, ); @@ -82,20 +80,9 @@ function block_admin_display_form(&$form_state, $blocks, $theme = NULL) { } } - // Attach the AHAH events to the submit button. Set the AHAH selector to every - // select element in the form. The AHAH event could be attached to every select - // element individually, but using the selector is more efficient, especially - // on a page where hundreds of AHAH enabled elements may be present. $form['submit'] = array( '#type' => 'submit', '#value' => t('Save blocks'), - '#ahah' => array( - 'path' => 'admin/build/block/list/js/'. $theme_key, - 'selector' => '#block-admin-display-form-wrapper select', - 'wrapper' => 'block-admin-display-form-wrapper', - 'event' => 'change', - 'effect' => 'fade', - ), ); return $form; @@ -115,104 +102,28 @@ function block_admin_display_form_submit($form, &$form_state) { } /** - * Javascript callback for AHAH replacement. Re-generate the form with the - * updated values and return necessary html. - */ -function block_admin_display_js($theme = NULL) { - // Load the cached form. - $form_cache = cache_get('form_'. $_POST['form_build_id'], 'cache_form'); - - // Set the new weights and regions for each block. - $blocks = array(); - foreach (element_children($form_cache->data) as $key) { - $field = $form_cache->data[$key]; - if (isset($field['info'])) { - $block = array( - 'module' => $field['module']['#value'], - 'delta' => $field['delta']['#value'], - 'info' => html_entity_decode($field['info']['#value'], ENT_QUOTES), - 'region' => $_POST[$key]['region'], - 'weight' => $_POST[$key]['weight'], - 'status' => $_POST[$key]['region'] == BLOCK_REGION_NONE ? 0 : 1, - ); - - $throttle = module_exists('throttle'); - if ($throttle) { - $block['throttle'] = !empty($_POST[$key]['throttle']); - } - - if ($block['weight'] != $form_cache->data[$key]['weight']['#default_value'] || $block['region'] != $form_cache->data[$key]['region']['#default_value']) { - $changed_block = $block['module'] .'_'. $block['delta']; - } - - $blocks[] = $block; - } - } - - // Resort the blocks with the new weights. - usort($blocks, '_block_compare'); - - // Create a form in the new order. - $form_state = array('submitted' => FALSE); - $form = block_admin_display_form($form_state, $blocks, $theme); - - // Maintain classes set on individual blocks. - foreach (element_children($form_cache->data) as $key) { - if (isset($form_cache->data[$key]['#attributes'])) { - $form[$key]['#attributes'] = $form_cache->data[$key]['#attributes']; - } - } - - // Preserve the order of the new form while merging the previous data. - $form_order = array_flip(array_keys($form)); // Save the form order. - $form = array_merge($form_cache->data, $form); // Merge the data. - $form = array_merge($form_order, $form); // Put back into the correct order. - - // Add a permanent class to the changed block. - $form[$changed_block]['#attributes']['class'] = 'block-modified'; - - cache_set('form_'. $_POST['form_build_id'], $form, 'cache_form', $form_cache->expire); - - // Add a temporary class to mark the new AHAH content. - $form[$changed_block]['#attributes']['class'] = empty($form[$changed_block]['#attributes']['class']) ? 'ahah-new-content' : $form[$changed_block]['#attributes']['class'] .' ahah-new-content'; - $form['js_modified'] = array( - '#type' => 'value', - '#value' => TRUE, - ); - - $form['#post'] = $_POST; - $form['#theme'] = 'block_admin_display_form'; - - // Add messages to our output. - drupal_set_message(t('Your settings will not be saved until you click the <em>Save blocks</em> button.'), 'warning'); - - // Render the form. - drupal_alter('form', $form, array(), 'block_admin_display_form'); - $form = form_builder('block_admin_display_form', $form, $form_state); - - // Remove the wrapper from the form to prevent duplicate div IDs. - unset($form['#prefix'], $form['#suffix']); - - $output = drupal_render($form); - - // Return the output in JSON format. - drupal_json(array('status' => TRUE, 'data' => $output)); -} - -/** * Helper function for sorting blocks on admin/build/block. * * Active blocks are sorted by region, then by weight. * Disabled blocks are sorted by name. */ function _block_compare($a, $b) { - $status = $b['status'] - $a['status']; + global $theme_key; + static $regions; + + // We need the region list to correctly order by region. + if (!isset($regions)) { + $regions = array_flip(array_keys(system_region_list($theme_key))); + $regions[BLOCK_REGION_NONE] = count($regions); + } + // Separate enabled from disabled. + $status = $b['status'] - $a['status']; if ($status) { return $status; } - // Sort by region. - $place = strcmp($a['region'], $b['region']); + // Sort by region (in the order defined by theme .info file). + $place = $regions[$a['region']] - $regions[$b['region']]; if ($place) { return $place; } @@ -442,14 +353,20 @@ function block_box_delete_submit($form, &$form_state) { function template_preprocess_block_admin_display_form(&$variables) { global $theme_key; - $variables['throttle'] = module_exists('throttle'); $block_regions = system_region_list($theme_key); + $variables['throttle'] = module_exists('throttle'); + $variables['block_regions'] = $block_regions + array(BLOCK_REGION_NONE => t('Disabled')); - // Highlight regions on page to provide visual reference. foreach ($block_regions as $key => $value) { + // Highlight regions on page to provide visual reference. drupal_set_content($key, '<div class="block-region">'. $value .'</div>'); + // Initialize an empty array for the region. + $variables['block_listing'][$key] = array(); } + // Initialize disabled blocks array. + $variables['block_listing'][BLOCK_REGION_NONE] = array(); + // Setup to track previous region in loop. $last_region = ''; foreach (element_children($variables['form']) as $i) { @@ -460,34 +377,23 @@ function template_preprocess_block_admin_display_form(&$variables) { // Fetch region for current block. $region = $block['region']['#default_value']; - // Track first block listing to insert region header inside block_admin_display.tpl.php. - $is_region_first = FALSE; - if ($last_region != $region) { - $is_region_first = TRUE; - // Set region title. Block regions already translated. - if ($region != BLOCK_REGION_NONE) { - $region_title = drupal_ucfirst($block_regions[$region]); - } - else { - $region_title = t('Disabled'); - } - } - - $variables['block_listing'][$i]->is_region_first = $is_region_first; - $variables['block_listing'][$i]->row_class = isset($block['#attributes']['class']) ? $block['#attributes']['class'] : ''; - $variables['block_listing'][$i]->block_modified = isset($block['#attributes']['class']) && strpos($block['#attributes']['class'], 'block-modified') !== FALSE ? TRUE : FALSE; - $variables['block_listing'][$i]->region_title = $region_title; - $variables['block_listing'][$i]->block_title = drupal_render($block['info']); - $variables['block_listing'][$i]->region_select = drupal_render($block['region']) . drupal_render($block['theme']); - $variables['block_listing'][$i]->weight_select = drupal_render($block['weight']); - $variables['block_listing'][$i]->throttle_check = $variables['throttle'] ? drupal_render($block['throttle']) : ''; - $variables['block_listing'][$i]->configure_link = drupal_render($block['configure']); - $variables['block_listing'][$i]->delete_link = !empty($block['delete']) ? drupal_render($block['delete']) : ''; + // Set special classes needed for table drag and drop. + $variables['form'][$i]['region']['#attributes']['class'] = 'block-region-select block-region-'. $region; + $variables['form'][$i]['weight']['#attributes']['class'] = 'block-weight block-weight-'. $region; + + $variables['block_listing'][$region][$i]->row_class = isset($block['#attributes']['class']) ? $block['#attributes']['class'] : ''; + $variables['block_listing'][$region][$i]->block_modified = isset($block['#attributes']['class']) && strpos($block['#attributes']['class'], 'block-modified') !== FALSE ? TRUE : FALSE; + $variables['block_listing'][$region][$i]->block_title = drupal_render($block['info']); + $variables['block_listing'][$region][$i]->region_select = drupal_render($block['region']) . drupal_render($block['theme']); + $variables['block_listing'][$region][$i]->weight_select = drupal_render($block['weight']); + $variables['block_listing'][$region][$i]->throttle_check = $variables['throttle'] ? drupal_render($block['throttle']) : ''; + $variables['block_listing'][$region][$i]->configure_link = drupal_render($block['configure']); + $variables['block_listing'][$region][$i]->delete_link = !empty($block['delete']) ? drupal_render($block['delete']) : ''; + $variables['block_listing'][$region][$i]->printed = FALSE; $last_region = $region; } } - $variables['messages'] = isset($variables['form']['js_modified']) ? theme('status_messages') : ''; $variables['form_submit'] = drupal_render($variables['form']); } diff --git a/modules/block/block.css b/modules/block/block.css index 87eac484f..3d579ee6c 100644 --- a/modules/block/block.css +++ b/modules/block/block.css @@ -3,8 +3,12 @@ #blocks td.region { font-weight: bold; } -#blocks td.block { - padding-left: 1.5em; /* LTR */ +#blocks tr.region-message { + font-weight: normal; + color: #999; +} +#blocks tr.region-populated { + display: none; } .block-region { background-color: #ff6; @@ -12,12 +16,3 @@ margin-bottom: 4px; padding: 3px; } -#blocks select { - margin-right: 24px; /* LTR */ -} -#blocks select.progress-disabled { - margin-right: 0px; /* LTR */ -} -#blocks tr.ahah-new-content { - background-color: #ffd; -} diff --git a/modules/block/block.js b/modules/block/block.js new file mode 100644 index 000000000..6a2a31d02 --- /dev/null +++ b/modules/block/block.js @@ -0,0 +1,95 @@ +// $Id $ + +/** + * Move a block in the blocks table from one region to another via select list. + * + * This behavior is dependent on the tableDrag behavior, since it uses the + * objects initialized in that behavior to update the row. + */ +Drupal.behaviors.blockDrag = function(context) { + var table = $('table#blocks'); + var tableDrag = Drupal.tableDrag.blocks; // Get the blocks tableDrag object. + + // Add a handler for when a row is swapped, update empty regions. + tableDrag.row.prototype.onSwap = function(swappedRow) { + checkEmptyRegions(table, this); + }; + + // A custom message for the blocks page specifically. + Drupal.theme.tableDragChangedWarning = function () { + return '<div class="warning">' + Drupal.theme('tableDragChangedMarker') + ' ' + Drupal.t("The changes to these blocks will not be saved until the <em>Save blocks</em> button is clicked.") + '</div>'; + }; + + // Add a handler so when a row is dropped, update fields dropped into new regions. + tableDrag.onDrop = function() { + dragObject = this; + if ($(dragObject.rowObject.element).prev('tr').is('.region-message')) { + var regionRow = $(dragObject.rowObject.element).prev('tr').get(0); + var regionName = regionRow.className.replace(/([^ ]+[ ]+)*region-([^ ]+)-message([ ]+[^ ]+)*/, '$2'); + var regionField = $('select.block-region-select', dragObject.rowObject.element); + var weightField = $('select.block-weight', dragObject.rowObject.element); + var oldRegionName = weightField[0].className.replace(/([^ ]+[ ]+)*block-weight-([^ ]+)([ ]+[^ ]+)*/, '$2'); + + if (!regionField.is('.block-region-'+ regionName)) { + regionField.removeClass('block-region-' + oldRegionName).addClass('block-region-' + regionName); + weightField.removeClass('block-weight-' + oldRegionName).addClass('block-weight-' + regionName); + regionField.val(regionName); + } + } + }; + + // Add the behavior to each region select list. + $('select.block-region-select:not(.blockregionselect-processed)', context).each(function() { + $(this).change(function(event) { + // Make our new row and select field. + var row = $(this).parents('tr:first'); + var select = $(this); + tableDrag.rowObject = new tableDrag.row(row); + + // Find the correct region and insert the row as the first in the region. + $('tr.region-message', table).each(function() { + if ($(this).is('.region-' + select[0].value + '-message')) { + // Add the new row and remove the old one. + $(this).after(row); + // Manually update weights and restripe. + tableDrag.updateFields(row.get(0)); + tableDrag.rowObject.changed = true; + if (tableDrag.oldRowElement) { + $(tableDrag.oldRowElement).removeClass('drag-previous'); + } + tableDrag.oldRowElement = row.get(0); + tableDrag.restripeTable(); + tableDrag.rowObject.markChanged(); + tableDrag.oldRowElement = row; + $(row).addClass('drag-previous'); + } + }); + + // Modify empty regions with added or removed fields. + checkEmptyRegions(table, row); + // Remove focus from selectbox. + select.get(0).blur(); + }); + $(this).addClass('blockregionselect-processed'); + }); + + var checkEmptyRegions = function(table, rowObject) { + $('tr.region-message', table).each(function() { + // If the dragged row is in this region, but above the message row, swap it down one space. + if ($(this).prev('tr').get(0) == rowObject.element) { + // Prevent a recursion problem when using the keyboard to move rows up. + if ((rowObject.method != 'keyboard' || rowObject.direction == 'down')) { + rowObject.swap('after', this); + } + } + // This region has become empty + if ($(this).next('tr').is(':not(.draggable)') || $(this).next('tr').size() == 0) { + $(this).removeClass('region-populated').addClass('region-empty'); + } + // This region has become populated. + else if ($(this).is('.region-empty')) { + $(this).removeClass('region-empty').addClass('region-populated'); + } + }); + }; +}; diff --git a/modules/block/block.module b/modules/block/block.module index 53d6974c6..aa44be98c 100644 --- a/modules/block/block.module +++ b/modules/block/block.module @@ -248,6 +248,9 @@ function _block_rehash() { } // Add defaults and save it into the database. drupal_write_record('blocks', $block); + // Set region to none if not enabled. + $block['region'] = $block['status'] ? $block['region'] : BLOCK_REGION_NONE; + // Add to the list of blocks we return. $blocks[] = $block; } else { @@ -257,7 +260,9 @@ function _block_rehash() { // do not need to update the database here. // Add 'info' to this block. $old_blocks[$module][$delta]['info'] = $block['info']; - // Add this block to the list of blocks we return + // Set region to none if not enabled. + $old_blocks[$module][$delta]['region'] = $old_blocks[$module][$delta]['status'] ? $old_blocks[$module][$delta]['region'] : BLOCK_REGION_NONE; + // Add this block to the list of blocks we return. $blocks[] = $old_blocks[$module][$delta]; // Remove this block from the list of blocks to be deleted. unset($old_blocks[$module][$delta]); diff --git a/modules/system/system.css b/modules/system/system.css index 795ed99cc..172fc29a8 100644 --- a/modules/system/system.css +++ b/modules/system/system.css @@ -3,6 +3,9 @@ /* ** HTML elements */ +body.drag { + cursor: move; +} th.active img { display: inline; } @@ -11,6 +14,12 @@ tr.even, tr.odd { border-bottom: 1px solid #ccc; padding: 0.1em 0.6em; } +tr.drag { + background-color: #fffff0; +} +tr.drag-previous { + background-color: #ffd; +} td.active { background-color: #ddd; } @@ -32,6 +41,21 @@ thead th { .breadcrumb { padding-bottom: .5em } +div.indentation { + width: 20px; + margin: -0.4em 0.2em -0.4em -0.4em; + padding: 0.4em 0 0.4em 0.6em; + float: left; +} +div.tree-child { + background: url(../../misc/tree.png) no-repeat 11px center; +} +div.tree-child-last { + background: url(../../misc/tree-bottom.png) no-repeat 11px center; +} +div.tree-child-horizontal { + background: url(../../misc/tree.png) no-repeat -11px center; +} .error { color: #e55; } @@ -334,6 +358,30 @@ html.js .resizable-textarea textarea { } /* +** Table drag and drop. +*/ +a.tabledrag-handle { + cursor: move; + float: left; + height: 1.7em; + margin: -0.42em 0 -0.42em -0.5em; + padding: 0.42em 1.5em 0.42em 0.5em; + text-decoration: none; +} +a.tabledrag-handle:hover { + text-decoration: none; +} +a.tabledrag-handle .handle { + margin-top: 4px; + height: 13px; + width: 13px; + background: url(../../misc/draggable.png) no-repeat 0 0; +} +a.tabledrag-handle-hover .handle { + background-position: 0 -20px; +} + +/* ** Teaser splitter */ .joined + .grippie { |