*/
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)
-<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>
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';
$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');
* 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;
}
} 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();
}
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;
-<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();
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;
}
.commit-message {
font-size: 110%;
+ font-family: Menlo,Consolas,"Lucida Console","DejaVu Sans Mono",monospace;
margin-bottom: .5em;
}
.commit-info {
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. */
color: red;
}
+
/* Checkout, File view */
div.checkout, div.file-view-contents {
padding: 3px;
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;
}
.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;
}
.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 {
<?php
/**
- * Horde_Vcs_Cvs Patchset class.
+ * Horde_Vcs_Patchset_Cvs class.
*
* Copyright 2000-2010 The Horde Project (http://www.horde.org/)
*
}
}
}
-
}
\ No newline at end of file
<?php
/**
- * Horde_Vcs_Git Patchset class.
+ * Horde_Vcs_Patchset_Git class.
*
* Copyright 2008-2010 The Horde Project (http://www.horde.org/)
*
}
$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'])
}
}
}
-
-}
\ No newline at end of file
+}