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')