Index: DiffEngine.php =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/diff/DiffEngine.php,v retrieving revision 1.1.4.1 diff -U3 -r1.1.4.1 DiffEngine.php --- DiffEngine.php 6 Jun 2007 18:14:25 -0000 1.1.4.1 +++ DiffEngine.php 7 Dec 2007 22:02:10 -0000 @@ -1119,3 +1119,137 @@ } } } + +/** + * Diff formatter which uses Drupal theme functions. + * @private + * @subpackage DifferenceEngine + */ +class DrupalDiffFormatter extends DiffFormatter +{ + + var $rows; + + function DrupalDiffFormatter() { + $this->leading_context_lines = 2; + $this->trailing_context_lines = 2; + } + + function _start_diff() { + $this->rows = array(); + } + + function _end_diff() { + return $this->rows; + } + + function _block_header( $xbeg, $xlen, $ybeg, $ylen ) { + return array( + array( + 'data' => '' . t('Line %nr', array('%nr' => $xbeg)) . '', + 'colspan' => 2 + ), + array( + 'data' => '' . t('Line %nr', array('%nr' => $ybeg)) . '', + 'colspan' => 2 + ) + ); + } + + function _start_block( $header ) { + if ($this->show_header) { + $this->rows[] = $header; + } + } + + function _end_block() { + } + + function _lines( $lines, $prefix=' ', $color='white' ) { + } + + /** + * Note: you should HTML-escape parameter before calling this. + */ + function addedLine($line) { + return array( + array( + 'data' => '+', + ), + array( + 'data' => $line, + 'class' => 'diff-addedline' + ) + ); + } + + /** + * Note: you should HTML-escape parameter before calling this. + */ + function deletedLine($line) { + return array( + array( + 'data' => '-', + ), + array( + 'data' => $line, + 'class' => 'diff-deletedline', + ) + ); + } + + /** + * Note: you should HTML-escape parameter before calling this. + */ + function contextLine($line) { + return array( + ' ', + array( + 'data' => $line, + 'class' => 'diff-context', + ) + ); + } + + function emptyLine() { + return array( + ' ', + ' ' + ); + } + + function _added($lines) { + foreach($lines as $line) { + $this->rows[] = array_merge($this->emptyLine(), $this->addedLine(check_plain($line))); + } + } + + function _deleted($lines) { + foreach($lines as $line) { + $this->rows[] = array_merge($this->deletedLine(check_plain ($line)), $this->emptyLine()); + } + } + + function _context($lines) { + foreach($lines as $line) { + $this->rows[] = array_merge($this->contextLine(check_plain ($line)), $this->contextLine(check_plain($line))); + } + } + + function _changed($orig, $closing) { + $diff = new WordLevelDiff($orig, $closing); + $del = $diff->orig(); + $add = $diff->closing(); + + // Notice that WordLevelDiff returns HTML-escaped output. + // Hence, we will be calling addedLine/deletedLine without HTML-escaping. + + while ($line = array_shift($del)) { + $aline = array_shift( $add ); + $this->rows[] = array_merge($this->deletedLine($line), $this->addedLine($aline)); + } + foreach ($add as $line) { // If any leftovers + $this->rows[] = array_merge($this->emptyLine(), $this->addedLine($line)); + } + } +} Index: diff.css =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/diff/diff.css,v retrieving revision 1.2.2.3 diff -U3 -r1.2.2.3 diff.css --- diff.css 31 Jan 2007 18:05:55 -0000 1.2.2.3 +++ diff.css 7 Dec 2007 22:02:10 -0000 @@ -4,6 +4,10 @@ width: 100%; margin-bottom: 20px; } +table.diff tr.even, table.diff tr.odd { + background-color: inherit; + border: none; +} td.diff-prevlink { text-align: left; } Index: diff.module =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/diff/diff.module,v retrieving revision 1.8.2.8 diff -U3 -r1.8.2.8 diff.module --- diff.module 6 Jun 2007 18:14:25 -0000 1.8.2.8 +++ diff.module 7 Dec 2007 22:02:10 -0000 @@ -320,16 +320,43 @@ $prev_link = ''; } - // display table - $output .= ''; - $output .= ''; - if ($new_log || $old_log) { - $output .= ''; - } - $output .= ''; - $output .= _diff_table_body($old_node, $new_node); - $output .= '
'. $old_header .''. $new_header .'
'. $old_log .''. $new_log .'
'; - $output .= '
'; + $header = array( + array( + 'data' => $old_header, + 'colspan' => 2 + ), + array( + 'data' => $new_header, + 'colspan' => 2 + ) + ); + $rows = array(); + if ($old_log || $new_log) { + $rows[] = array( + array( + 'data' => $old_log, + 'colspan' => 2 + ), + array( + 'data' => $new_log, + 'colspan' => 2 + ) + ); + } + $rows[] = array( + array( + 'data' => $prev_link, + 'class' => 'diff-prevlink', + 'colspan' => 2 + ), + array( + 'data' => $next_link, + 'class' => 'diff-nextlink', + 'colspan' => 2 + ) + ); + $rows = array_merge($rows, _diff_body_rows($old_node, $new_node)); + $output = theme('table', $header, $rows, array('class' => 'diff')); if ($node->vid == $new_vid) { $output .= '
'. t('Current revision:') .'
'; @@ -343,13 +370,21 @@ } /** - * Create the table body of the diff between $old_node and $new_node. - * The result is a html table part enclosed in tags. + * Creates an array of rows which represent a diff between $old_node and $new_node. + * The rows can be used via theme('table') to be displayed. + * + * @param $old_node + * Node for comparison which will be displayed on the left side. + * @param $new_node + * Node for comparison which will be displayed on the right side. */ -function _diff_table_body(&$old_node, &$new_node) { +function _diff_body_rows(&$old_node, &$new_node) { drupal_add_css(drupal_get_path('module', 'diff') .'/diff.css', 'module', 'all', FALSE); include_once('DiffEngine.php'); include_once('node.inc'); + if (module_exists('taxonomy')) { + include_once('taxonomy.inc'); + } if (module_exists('upload')) { include_once('upload.inc'); } @@ -357,27 +392,38 @@ include_once('cck.inc'); } - $output = ''; + $rows = array(); $any_visible_change = false; $node_diffs = module_invoke_all('diff', $old_node, $new_node); foreach($node_diffs as $node_diff) { $diff = new Diff($node_diff['old'], $node_diff['new']); - $formatter = new TableDiffFormatter(); + $formatter = new DrupalDiffFormatter(); if (isset($node_diff['format'])) { $formatter->show_header = $node_diff['format']['show_header']; } - $formatter_output = $formatter->format($diff); - if ($formatter_output) { - $output .= ''. t('Changes to %name', array('%name' => $node_diff['name'])) .''; - $output .= $formatter_output; + $diff_rows = $formatter->format($diff); + if (count($diff_rows)) { + $rows[] = array( + array( + 'data' => t('Changes to %name', array('%name' => $node_diff['name'])), + 'class' => 'diff-section-title', + 'colspan' => 4 + ) + ); + $rows = array_merge($rows, $diff_rows); $any_visible_change = true; } } if (!$any_visible_change) { - $output .= '' .t('No visible changes') .''; + $rows[] = array( + array( + 'data' => t('No visible changes'), + 'class' => 'diff-section-title', + 'colspan' => 4 + ) + ); } - $output .= ''; - return $output; + return $rows; } /** @@ -477,10 +523,12 @@ $op = isset($form_values['op']) ? $form_values['op'] : ''; if ($op == t('Preview changes')) { + // Diff module excpects node as object, thus $form_values is cast to an object. $node = (object)$form_values; - $changes = ''; - $changes .= _diff_table_body(node_load($form_values['nid']), $node); - $changes .= '
'; + // Create diff of old node and edited node + $rows = _diff_body_rows(node_load($form_values['nid']), $node); + $changes = theme('table', array(), $rows, array('class' => 'diff')); + // Prepend diff to edit form $form['#prefix'] = isset($form['#prefix']) ? $changes . $form['#prefix'] : $changes; return $form; }