Bug #4578: Individual patchset view that includes the full diff.
authorChuck Hagenbuch <chuck@horde.org>
Sun, 28 Nov 2010 02:04:05 +0000 (21:04 -0500)
committerChuck Hagenbuch <chuck@horde.org>
Sun, 28 Nov 2010 02:08:02 +0000 (21:08 -0500)
chora/app/helpers/Diff.php
chora/app/views/diff/diff.html.php
chora/commit.php
chora/diff.php
chora/lib/Chora.php
chora/templates/patchsets/ps_single.inc
chora/themes/default/screen.css
framework/Vcs/lib/Horde/Vcs/Patchset/Cvs.php
framework/Vcs/lib/Horde/Vcs/Patchset/Git.php

index 87b1e11..ae2d6ca 100644 (file)
@@ -15,13 +15,15 @@ class Chora_Diff_Helper extends Horde_View_Helper_Base
      */
     protected $_context = '';
 
-    public function diff($diff)
+    public function diff(Horde_Vcs_File $file, $r1, $r2, $id = null)
     {
-        if (!$diff) {
-            return '<p>' . _("No Visible Changes") . '</p>';
+        try {
+            $diff = $GLOBALS['VC']->diff($file, $r1, $r2, array('human' => true));
+        } catch (Horde_Vcs_Exception $e) {
+            return '<div class="diff"><p>' . sprintf(_("There was an error generating the diff: %s"), $e->getMessage()) . '</p></div>';
         }
 
-        return $this->render('app/views/diff/diff.html.php', array('diff' => $diff));
+        return $this->render('app/views/diff/diff.html.php', array('diff' => $diff, 'file' => $file, 'r1' => $r1, 'r2' => $r2, 'id' => $id));
     }
 
     public function diffAdd($change)
index 4d73155..7f0fe0a 100644 (file)
@@ -1,4 +1,5 @@
-<div class="diff">
+<div class="diff"<?php if ($id) echo ' id="' . $id . '"' ?>>
+<div class="diff-header"><h4><?php echo $file->queryModulePath() ?></h4></div>
 <?php foreach ($diff as $section): ?>
 <div class="diff-container diff-section">
  <div class="diff-left"><h3><?php printf(_("Line %s"), $section['oldline']) ?></h3></div>
index ad64786..1d8e542 100644 (file)
@@ -34,67 +34,16 @@ try {
 if (empty($patchsets)) {
     Chora::fatal(_("Commit Not Found"), '404 Not Found');
 }
+reset($patchsets);
+$patchset = current($patchsets);
 
-$extraLink = Chora::getFileViews($where, 'patchsets');
+// Cache the commit output for a week - it can be longer, since it should never
+// change.
+header('Cache-Control: max-age=604800');
 
 Horde::addScriptFile('tables.js', 'horde');
 require CHORA_TEMPLATES . '/common-header.inc';
 require CHORA_TEMPLATES . '/menu.inc';
 require CHORA_TEMPLATES . '/headerbar.inc';
-
-$diff_img = Horde::img('diff.png', _("Diff"));
-
-$files = $tags = array();
-
-reset($patchsets);
-$patchset = current($patchsets);
-foreach ($patchset['members'] as $member) {
-    $file = array();
-
-    $file['file'] = Chora::url('co', $member['file'])->link()
-        . htmlspecialchars($member['file']) . '</a>';
-
-    if ($member['status'] == Horde_Vcs_Patchset::ADDED) {
-        $file['from'] = '<ins>' . _("New File") . '</ins>';
-        $file['diff'] = '';
-    } else {
-        $file['from'] = Chora::url('co', $member['file'], array('r' => $member['from']))
-            ->link(array('title' => $member['from']))
-            . htmlspecialchars($VC->abbrev($member['from'])) . '</a>';
-        $file['diff'] = Chora::url('diff', $member['file'], array('r1' => $member['from'], 'r2' => $member['to']))
-            ->link(array('title' => _("Diff")))
-            . ' ' . $diff_img . '</a>';
-    }
-
-    if ($member['status'] == Horde_Vcs_Patchset::DELETED) {
-        $file['to'] = '<del>' . _("Deleted") . '</del>';
-        $file['diff'] = '';
-    } else {
-        $file['to'] = Chora::url('co', $member['file'], array('r' => $member['to']))
-            ->link(array('title' => $member['to']))
-            . htmlspecialchars($VC->abbrev($member['to'])) . '</a>';
-    }
-
-    if (isset($member['added'])) {
-        $file['added'] = $member['added'];
-        $file['deleted'] = $member['deleted'];
-    }
-
-    $files[] = $file;
-}
-
-$commitDate = Chora::formatDate($patchset['date']);
-$readableDate = Chora::readableTime($patchset['date'], true);
-$author = Chora::showAuthorName($patchset['author'], true);
-$logMessage = Chora::formatLogMessage($patchset['log']);
-
-if (!empty($patchset['branch'])) {
-    $tags = $patchset['branch'];
-}
-
-if (!empty($patchset['tag'])) {
-    $tags = array_merge($tags, $patchset['tag']);
-}
-
 require CHORA_TEMPLATES . '/patchsets/ps_single.inc';
 require $registry->get('templates', 'horde') . '/common-footer.inc';
index 9304b56..3d22110 100644 (file)
@@ -34,11 +34,6 @@ if (Horde_Util::getFormData('ty') == 'u') {
     $type = 'unified';
 }
 
-/* Unless otherwise specified, show whitespace differences and 3 lines
- * of context. */
-$ws = Horde_Util::getFormData('ws', 1);
-$num = (int)Horde_Util::getFormData('num', 3);
-
 /* Cache the output of the diff for a week - it can be longer, since
  * it should never change. */
 header('Cache-Control: max-age=604800');
@@ -47,7 +42,7 @@ header('Cache-Control: max-age=604800');
  * the end of the file - patch requires it. */
 if ($type != 'colored') {
     header('Content-Type: text/plain');
-    echo implode("\n", $VC->diff($fl, $r1, $r2, array('num' => $num, 'type' => $type, 'ws' => $ws))) . "\n";
+    echo implode("\n", $VC->diff($fl, $r1, $r2, array('num' => $num, 'type' => $type))) . "\n";
     exit;
 }
 
@@ -83,7 +78,7 @@ if (substr($mime_type, 0, 6) == 'image/') {
 } else {
     $view = $injector->createInstance('Horde_View');
     $view->addHelper('Chora_Diff_Helper');
-    echo $view->diff($VC->diff($fl, $r1, $r2, array('human' => true, 'num' => $num, 'ws' => $ws)));
+    echo $view->diff($fl, $r1, $r2);
     echo $view->diffCaption();
 }
 
index 018ed55..045bdd7 100644 (file)
@@ -128,7 +128,7 @@ class Chora
 
             case 'patchsets.php':
                 if (!empty($args['ps'])) {
-                    $script = urlencode(isset($args['rt']) ? $args['rt'] : $GLOBALS['acts']['rt']) . '/-/commits/' . $args['ps'];
+                    $script = urlencode(isset($args['rt']) ? $args['rt'] : $GLOBALS['acts']['rt']) . '/-/commit/' . $args['ps'];
                     unset($arglist['ps']);
                 }
                 break;
index 35c5ecd..841eb63 100644 (file)
@@ -1,30 +1,49 @@
-<div class="singleps">
- <span class="headerLabel"><?php echo _("Date") ?>:</span>
- <span class="ago"><a title="<?php echo $readableDate ?>"><?php echo $commitDate ?></a></span>
-</div>
-
-<div class="singleps">
- <span class="headerLabel"><?php echo _("Author") ?>:</span> <?php echo $author ?>
-</div>
-
-<?php if (!empty($tags)): ?>
-<div class="singleps">
- <span class="headerLabel"><?php echo _("Tags") ?>:</span> <?php echo implode(', ', array_map('htmlspecialchars', $tags)) ?>
-</div>
-<?php endif; ?>
-
-<div class="singleps">
- <span class="headerLabel"><?php echo _("Description") ?>:</span>
-</div>
-
-<div class="fixed singlepslog"><?php echo $logMessage ?></div>
-
-<div class="singleps">
- <span class="headerLabel"><?php echo _("Changes") ?>:</span>
-</div>
-
-<ul class="singlepsfiles">
-<?php foreach ($files as $file): ?>
- <li><?php echo $file['file'] . (isset($file['added']) ? (' (<span class="diffadd">+' . $file['added'] . '</span>, <span class="diffdel">-' . $file['deleted'] . '</span>) ') : '') . ': ' . $file['from'] . ' -> ' . $file['to'] . ' ' . $file['diff'] ?></li>
-<?php endforeach; ?>
-</ul>
+<?php
+
+$view = $injector->createInstance('Horde_View');
+$view->addHelper('Chora_Diff_Helper');
+
+echo $view->renderPartial('app/views/logMessage', array('collection' => array($patchset['log'])));
+
+echo '<ul class="commit-filelist">';
+$i = 0;
+foreach ($patchset['members'] as $member) {
+    $i++;
+
+    switch ($member['status']) {
+    case Horde_Vcs_Patchset::ADDED:
+        $class = 'commit-file-added';
+        $alt = '+';
+        break;
+
+    case Horde_Vcs_Patchset::DELETED:
+        $class = 'commit-file-deleted';
+        $alt = '-';
+        break;
+
+    default:
+        $class = 'commit-file-modified';
+        $alt = '*';
+    }
+
+    echo '<li><span class="' . $class . '">' . $alt . '</span><a href="#diff-' . $i . '">'
+        . htmlspecialchars($member['file']) . '</a>' . (isset($member['added']) ? (' (<span class="diffadd">+' . $member['added'] . '</span>, <span class="diffdel">-' . $member['deleted'] . '</span>) ') : '') . '</li>';
+}
+echo '</ul>';
+
+$segmentStart = microtime(true);
+$i = 0;
+foreach ($patchset['members'] as $member) {
+    $i++;
+    echo $view->diff($VC->getFileObject($member['file']), $member['from'], $member['to'], "diff-$i");
+
+    // Flush every .1 seconds to keep the page rendering.
+    $now = microtime(true);
+    if ($now - $segmentStart > .1) {
+        ob_flush();
+        flush();
+        $segmentStart = $now;
+    }
+}
+
+echo $view->diffCaption();
index ffd4342..5cdcf2e 100644 (file)
@@ -150,25 +150,6 @@ h3.checkout, h3.file-view-header {
     width: 35%;
 }
 
-.singleps span.headerLabel {
-    font-size: 110%;
-    font-weight: bold;
-    padding-right: 5px;
-}
-.singleps span.ago a:hover {
-    text-decoration: none;
-}
-.singlepslog {
-    padding: 10px 0 20px 20px;
-}
-ul.singlepsfiles {
-    list-style: none;
-    padding: 10px 0 0 20px;
-}
-ul.singlepsfiles li {
-    padding-bottom: 4px;
-}
-
 .commit-list h3 {
     font-size: 130%;
     font-weight: bold;
@@ -183,6 +164,7 @@ ul.singlepsfiles li {
 }
 .commit-message {
     font-size: 110%;
+    font-family: Menlo,Consolas,"Lucida Console","DejaVu Sans Mono",monospace;
     margin-bottom: .5em;
 }
 .commit-info {
@@ -198,7 +180,42 @@ ul.singlepsfiles li {
     margin-bottom: .5em;
 }
 .commit-author {
-    font-size: 90%;
+}
+
+ul.commit-filelist {
+    margin: 1em 0;
+    border-top: thin solid #ccc;
+    list-style: none;
+}
+ul.commit-filelist li {
+    font-family: Menlo,Consolas,"Lucida Console","DejaVu Sans Mono",monospace;
+    padding: .2em;
+    border-bottom: thin solid #ccc;
+}
+ul.commit-filelist li:after {
+    content: ".";
+    display: block;
+    height: 0;
+    clear: both;
+    visibility: hidden;
+}
+
+span.commit-file-added, span.commit-file-deleted, span.commit-file-modified {
+    display: block;
+    float: left;
+    height: 1em;
+    width: 1em;
+    margin-right: .5em;
+    text-indent: -9999px;
+}
+span.commit-file-added {
+    background: #cfc;
+}
+span.commit-file-deleted {
+    background: #fcc;
+}
+span.commit-file-modified {
+    background: #def;
 }
 
 /* Diff stat information. */
@@ -209,6 +226,7 @@ ul.singlepsfiles li {
     color: red;
 }
 
+
 /* Checkout, File view */
 div.checkout, div.file-view-contents {
     padding: 3px;
@@ -254,6 +272,20 @@ table.annotate .logentry {
 div.diff {
     font-size: 100%;
     color: #111;
+    border: 1px solid #ccc;
+    margin: 1.5em 0;
+}
+div.diff-header {
+    border-bottom: 1px solid #ccc;
+    background: #eee;
+    background: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#eee), color-stop(0.5, #eee));
+    background: -moz-linear-gradient(top, #fff, #eee 50%);
+    padding: .5em;
+}
+div.diff-header h4 {
+    font-weight: normal;
+    font-family: Menlo,Consolas,"Lucida Console","DejaVu Sans Mono",monospace;
+    font-size: 110%;
 }
 div.diff-section {
     margin-top: 1em;
@@ -289,8 +321,8 @@ div.diff-right {
 }
 .diff-added-empty {
     background: #efe;
-    background: -webkit-gradient(linear, left top, right top, from(#efe), to(#cfc), color-stop(0.5, #cfc));
-    background: -moz-linear-gradient(left top, #efe, #cfc 50%);
+    background: -webkit-gradient(linear, left top, right top, from(#fff), to(#cfc), color-stop(0.5, #cfc));
+    background: -moz-linear-gradient(left top, #fff, #cfc 50%);
 }
 .diff-modified {
     background: #def;
@@ -300,8 +332,8 @@ div.diff-right {
 }
 .diff-removed-empty {
     background: #fee;
-    background: -webkit-gradient(linear, right top, left top, from(#fee), to(#fcc), color-stop(0.5, #fcc));
-    background: -moz-linear-gradient(right top, #fee, #fcc 50%);
+    background: -webkit-gradient(linear, right top, left top, from(#fff), to(#fcc), color-stop(0.5, #fcc));
+    background: -moz-linear-gradient(right top, #fff, #fcc 50%);
 }
 
 .diff-caption {
index 4802e3f..7f7687e 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /**
- * Horde_Vcs_Cvs Patchset class.
+ * Horde_Vcs_Patchset_Cvs class.
  *
  * Copyright 2000-2010 The Horde Project (http://www.horde.org/)
  *
@@ -139,5 +139,4 @@ class Horde_Vcs_Patchset_Cvs extends Horde_Vcs_Patchset
             }
         }
     }
-
 }
\ No newline at end of file
index e7a8d96..f25ebd8 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /**
- * Horde_Vcs_Git Patchset class.
+ * Horde_Vcs_Patchset_Git class.
  *
  * Copyright 2008-2010 The Horde Project (http://www.horde.org/)
  *
@@ -50,32 +50,25 @@ class Horde_Vcs_Patchset_Git extends Horde_Vcs_Patchset
             }
 
             $this->_patchsets[$rev] = array(
-                'date' => $log->queryDate(),
-                'author' => $log->queryAuthor(),
-                'branches' => $log->queryBranch(),
-                'tags' => $log->queryTags(),
-                'log' => $log->queryLog(),
+                'log' => $log,
                 'members' => array(),
             );
 
             foreach ($log->queryFiles() as $file) {
+                $from = $log->queryParent();
                 $to = $rev;
-                $status = self::MODIFIED;
 
                 switch ($file['status']) {
                 case 'A':
-                    $from = null;
                     $status = self::ADDED;
                     break;
 
                 case 'D':
-                    $from = $to;
-                    $to = null;
                     $status = self::DELETED;
                     break;
 
                 default:
-                    $from = $log->queryParent();
+                    $status = self::MODIFIED;
                 }
 
                 $statinfo = isset($file['added'])
@@ -91,5 +84,4 @@ class Horde_Vcs_Patchset_Git extends Horde_Vcs_Patchset
             }
         }
     }
-
-}
\ No newline at end of file
+}