diff --git a/features.admin.inc b/features.admin.inc index 4e12576..84c5a57 100644 --- a/features.admin.inc +++ b/features.admin.inc @@ -1332,39 +1332,144 @@ function features_cleanup_form($form, $form_state, $cache_clear = FALSE) { * Themed display of what is different. */ function features_feature_diff($feature, $component = NULL) { - drupal_add_css(drupal_get_path('module', 'features') . '/features.css'); module_load_include('inc', 'features', 'features.export'); + drupal_set_title($feature->info['name']); - $overrides = features_detect_overrides($feature); + $return = array( + 'features_comparison_table' => array( + '#theme' => 'table', + '#header' => array( + array('data' => t('Default'), 'colspan' => 2), + array('data' => t('Overrides'), 'colspan' => 2), + ), + '#rows' => array(), + '#empty' => t('No changes have been made to this feature.'), + '#weight' => 1, + '#attributes' => array( + 'class' => array('diff', 'features-diff'), + ), + '#prefix' => '
', + '#suffix' => '
', + '#attached' => array( + 'css' => array( + drupal_get_path('module', 'features') . '/features.css' + ), + ), + ), + ); - $output = ''; + $overrides = features_detect_overrides($feature); if (!empty($overrides)) { + $return['features_diff_formatter_settings_form'] = drupal_get_form('features_diff_formatter_settings_form'); + $return['features_diff_formatter_settings_form']['#weight'] = 0; + // Filter overrides down to specified component. if (isset($component) && isset($overrides[$component])) { $overrides = array($component => $overrides[$component]); } + $diff_settings = features_diff_formatter_settings(); + module_load_include('inc', 'diff', 'diff.engine'); $formatter = new DrupalDiffFormatter(); - $rows = array(); + $formatter->leading_context_lines + = $formatter->trailing_context_lines + = $diff_settings['context_lines']; + + if (!empty($diff_settings['indent'])) { + $return['features_comparison_table']['#attributes']['class'][] = 'diff-indent'; + } + foreach ($overrides as $component => $items) { - $rows[] = array(array('data' => $component, 'colspan' => 4, 'header' => TRUE)); + $return['features_comparison_table']['#rows'][] = array( + array( + 'data' => $component, + 'colspan' => 4, + 'header' => TRUE, + ), + ); $diff = new Diff(explode("\n", $items['default']), explode("\n", $items['normal'])); - $rows = array_merge($rows, $formatter->format($diff)); + + $return['features_comparison_table']['#rows'] = array_merge( + $return['features_comparison_table']['#rows'], + $formatter->format($diff) + ); } - $header = array( - array('data' => t('Default'), 'colspan' => 2), - array('data' => t('Overrides'), 'colspan' => 2), - ); - $output .= theme('table', array('header' => $header, 'rows' => $rows, 'attributes' => array('class' => array('diff', 'features-diff')))); } - else { - $output = "
" . t('No changes have been made to this feature.') . "
"; + + return $return; +} + +/** + * Default values of the diff settings. + */ +function features_diff_formatter_settings() { + $return = array(); + + $keys = array( + 'context_lines' => 3, + 'indent' => 1, + ); + foreach ($keys as $key => $value) { + $name = "features_diff_{$key}"; + $return[$key] = (array_key_exists($name, $_SESSION)) ? $_SESSION[$name] : variable_get($name, $value); } - $output = array('page' => array('#markup' => "
{$output}
")); - return $output; + + return $return; +} + +/** + * Form builder function for 'lines of context' above diff output. + */ +function features_diff_formatter_settings_form($form, &$form_state) { + $diff_settings = features_diff_formatter_settings(); + + $form['#attributes']['class'][] = 'features'; + $form['#attached']['css'][] = drupal_get_path('module', 'features') . '/features.css'; + + $form['context_lines'] = array( + '#type' => 'textfield', + '#title' => ('Lines of context'), + '#title_display' => 'before', + '#size' => 4, + '#default_value' => $diff_settings['context_lines'], + '#element_validate' => array('element_validate_integer_positive'), + '#attributes' => array( + 'class' => array('align-right'), + ), + ); + + $form['indent'] = array( + '#type' => 'checkbox', + '#title' => ('Indent lines'), + '#default_value' => $diff_settings['indent'], + ); + + $form['actions'] = array( + '#type' => 'actions', + 'submit' => array( + '#type' => 'submit', + '#value' => t('Reload page'), + ), + ); + + return $form; +} + +/** + * Submit function for features_diff_formatter_settings_form. + */ +function features_diff_formatter_settings_form_submit($form, &$form_state) { + $context_lines = (int) trim($form_state['values']['context_lines']); + if (!$context_lines) { + $diff_settings = features_diff_formatter_settings(); + $context_lines = $diff_settings['context_lines']; + } + + $_SESSION['features_diff_context_lines'] = $context_lines; + $_SESSION['features_diff_indent'] = $form_state['values']['indent']; } /** diff --git a/features.css b/features.css index 16c7f72..2f0b054 100644 --- a/features.css +++ b/features.css @@ -69,6 +69,22 @@ div.features-empty { color:#999; } +.features-diff-formatter-settings-form .form-type-textfield, +.features-diff-formatter-settings-form .form-type-textfield label, +.features-diff-formatter-settings-form .form-type-textfield .form-text, +.features-diff-formatter-settings-form .form-type-checkbox { + float: left; +} + +.features-diff-formatter-settings-form .form-type-checkbox, +.features-diff-formatter-settings-form .form-submit { + margin: 0 0 0 2em; +} + +.features .align-right { + text-align: right; +} + form div.buttons { text-align:center; } @@ -289,6 +305,10 @@ span.features-component-list .features-dependency { background:#f8f8f8; } +table.diff-indent td div { + white-space: pre; +} + /** * Features diff. */ @@ -563,4 +583,4 @@ input.form-submit.features-refresh-button { fieldset.features-export-component .fieldset-title .component-count { font-size: 12px; font-weight: bold; -} \ No newline at end of file +} diff --git a/features.install b/features.install index 762a054..b5563d8 100644 --- a/features.install +++ b/features.install @@ -25,6 +25,8 @@ function features_uninstall() { variable_del('features_default_export_path'); variable_del('features_semaphore'); variable_del('features_ignored_orphans'); + variable_del('features_diff_context_lines'); + variable_del('features_diff_indent'); if (db_table_exists('menu_custom')) { db_delete('menu_custom') ->condition('menu_name', 'features')