Added inline visualization of text files from the repository.
This commit is contained in:
parent
297d7290df
commit
9ac6e38e81
@ -127,7 +127,7 @@ class IDF_Diff
|
|||||||
} else {
|
} else {
|
||||||
$class = 'diff-a';
|
$class = 'diff-a';
|
||||||
}
|
}
|
||||||
$line_content = $this->padLine(Pluf_esc($line[2]));
|
$line_content = self::padLine(Pluf_esc($line[2]));
|
||||||
$out .= sprintf('<tr class="diff-line"><td class="diff-lc">%s</td><td class="diff-lc">%s</td><td class="%s mono">%s</td></tr>'."\n", $line[0], $line[1], $class, $line_content);
|
$out .= sprintf('<tr class="diff-line"><td class="diff-lc">%s</td><td class="diff-lc">%s</td><td class="%s mono">%s</td></tr>'."\n", $line[0], $line[1], $class, $line_content);
|
||||||
}
|
}
|
||||||
if (count($file['chunks']) > $cc)
|
if (count($file['chunks']) > $cc)
|
||||||
@ -136,11 +136,11 @@ class IDF_Diff
|
|||||||
}
|
}
|
||||||
$out .= '</table>';
|
$out .= '</table>';
|
||||||
}
|
}
|
||||||
return $out;
|
return Pluf_Template::markSafe($out);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function padLine($line)
|
public static function padLine($line)
|
||||||
{
|
{
|
||||||
$n = strlen($line);
|
$n = strlen($line);
|
||||||
for ($i=0;$i<$n;$i++) {
|
for ($i=0;$i<$n;$i++) {
|
||||||
|
@ -128,12 +128,17 @@ class IDF_Views_Source
|
|||||||
$rep = new Pluf_HTTP_Response($scm->getBlob($request_file_info, $commit),
|
$rep = new Pluf_HTTP_Response($scm->getBlob($request_file_info, $commit),
|
||||||
$info[0]);
|
$info[0]);
|
||||||
$rep->headers['Content-Disposition'] = 'attachment; filename="'.$info[1].'"';
|
$rep->headers['Content-Disposition'] = 'attachment; filename="'.$info[1].'"';
|
||||||
|
return $rep;
|
||||||
} else {
|
} else {
|
||||||
// We want to display the content of the file as text
|
// We want to display the content of the file as text
|
||||||
$rep = new Pluf_HTTP_Response($scm->getBlob($request_file_info, $commit),
|
$extra = array('branches' => $branches,
|
||||||
'text/plain');
|
'commit' => $commit,
|
||||||
|
'request_file' => $request_file,
|
||||||
|
'request_file_info' => $request_file_info,
|
||||||
|
'mime' => $info,
|
||||||
|
);
|
||||||
|
return $this->viewFile($request, $match, $extra);
|
||||||
}
|
}
|
||||||
return $rep;
|
|
||||||
}
|
}
|
||||||
$bc = self::makeBreadCrumb($request->project, $commit, $request_file_info->file);
|
$bc = self::makeBreadCrumb($request->project, $commit, $request_file_info->file);
|
||||||
$page_title = $bc.' - '.$title;
|
$page_title = $bc.' - '.$title;
|
||||||
@ -215,6 +220,83 @@ class IDF_Views_Source
|
|||||||
$request);
|
$request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Should only be called through self::tree
|
||||||
|
*/
|
||||||
|
public function viewFile($request, $match, $extra)
|
||||||
|
{
|
||||||
|
$title = sprintf(__('%1$s %2$s Source Tree'), (string) $request->project,
|
||||||
|
$this->getScmType($request));
|
||||||
|
$scm = IDF_Scm::get($request);
|
||||||
|
$branches = $extra['branches'];
|
||||||
|
$commit = $extra['commit'];
|
||||||
|
$request_file = $extra['request_file'];
|
||||||
|
$request_file_info = $extra['request_file_info'];
|
||||||
|
$bc = self::makeBreadCrumb($request->project, $commit, $request_file_info->file);
|
||||||
|
$page_title = $bc.' - '.$title;
|
||||||
|
$cobject = $scm->getCommit($commit);
|
||||||
|
$tree_in = in_array($commit, $branches);
|
||||||
|
// try to find the previous level if it exists.
|
||||||
|
$prev = split('/', $request_file);
|
||||||
|
$l = array_pop($prev);
|
||||||
|
$previous = substr($request_file, 0, -strlen($l.' '));
|
||||||
|
$scmConf = $request->conf->getVal('scm', 'git');
|
||||||
|
$props = null;
|
||||||
|
if ($scmConf === 'svn') {
|
||||||
|
$props = $scm->getProperties($commit, $request_file);
|
||||||
|
}
|
||||||
|
$content = self::highLight($extra['mime'], $scm->getBlob($request_file_info, $commit));
|
||||||
|
return Pluf_Shortcuts_RenderToResponse('source/'.$scmConf.'/file.html',
|
||||||
|
array(
|
||||||
|
'page_title' => $page_title,
|
||||||
|
'title' => $title,
|
||||||
|
'breadcrumb' => $bc,
|
||||||
|
'file' => $content,
|
||||||
|
'commit' => $commit,
|
||||||
|
'cobject' => $cobject,
|
||||||
|
'fullpath' => $request_file,
|
||||||
|
'base' => $request_file_info->file,
|
||||||
|
'prev' => $previous,
|
||||||
|
'tree_in' => $tree_in,
|
||||||
|
'branches' => $branches,
|
||||||
|
'props' => $props,
|
||||||
|
),
|
||||||
|
$request);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a given file at a given commit.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public $getFile_precond = array('IDF_Precondition::accessSource');
|
||||||
|
public function getFile($request, $match)
|
||||||
|
{
|
||||||
|
$scm = IDF_Scm::get($request);
|
||||||
|
$branches = $scm->getBranches();
|
||||||
|
$commit = $match[2];
|
||||||
|
$request_file = $match[3];
|
||||||
|
if ('commit' != $scm->testHash($commit, $request_file)) {
|
||||||
|
// Redirect to the first branch
|
||||||
|
$url = Pluf_HTTP_URL_urlForView('IDF_Views_Source::treeBase',
|
||||||
|
array($request->project->shortname,
|
||||||
|
$branches[0]));
|
||||||
|
return new Pluf_HTTP_Response_Redirect($url);
|
||||||
|
}
|
||||||
|
$request_file_info = $scm->getFileInfo($request_file, $commit);
|
||||||
|
if (!$request_file_info or $request_file_info->type == 'tree') {
|
||||||
|
// Redirect to the first branch
|
||||||
|
$url = Pluf_HTTP_URL_urlForView('IDF_Views_Source::treeBase',
|
||||||
|
array($request->project->shortname,
|
||||||
|
$branches[0]));
|
||||||
|
return new Pluf_HTTP_Response_Redirect($url);
|
||||||
|
}
|
||||||
|
$info = self::getMimeType($request_file_info->file);
|
||||||
|
$rep = new Pluf_HTTP_Response($scm->getBlob($request_file_info, $commit),
|
||||||
|
$info[0]);
|
||||||
|
$rep->headers['Content-Disposition'] = 'attachment; filename="'.$info[1].'"';
|
||||||
|
return $rep;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a zip archive of the current commit.
|
* Get a zip archive of the current commit.
|
||||||
*
|
*
|
||||||
@ -289,6 +371,18 @@ class IDF_Views_Source
|
|||||||
return (in_array($fileinfo[2], explode(' ', $ext)));
|
return (in_array($fileinfo[2], explode(' ', $ext)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function highLight($fileinfo, $content)
|
||||||
|
{
|
||||||
|
$table = array();
|
||||||
|
$i = 1;
|
||||||
|
foreach (preg_split("/\015\012|\015|\012/", $content) as $line) {
|
||||||
|
$table[] = '<tr class="c-line"><td class="code-lc" id="L'.$i.'"><a href="#L'.$i.'">'.$i.'</a></td>'
|
||||||
|
.'<td class="code mono">'.IDF_Diff::padLine(Pluf_esc($line)).'</td></tr>';
|
||||||
|
$i++;
|
||||||
|
}
|
||||||
|
return Pluf_Template::markSafe(implode("\n", $table));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the scm type for page title
|
* Get the scm type for page title
|
||||||
*
|
*
|
||||||
|
@ -165,6 +165,12 @@ $ctl[] = array('regex' => '#^/p/([\-\w]+)/source/download/(\w+)/$#',
|
|||||||
'model' => 'IDF_Views_Source',
|
'model' => 'IDF_Views_Source',
|
||||||
'method' => 'download');
|
'method' => 'download');
|
||||||
|
|
||||||
|
$ctl[] = array('regex' => '#^/p/([\-\w]+)/source/file/(\w+)/(.*)$#',
|
||||||
|
'base' => $base,
|
||||||
|
'priority' => 4,
|
||||||
|
'model' => 'IDF_Views_Source',
|
||||||
|
'method' => 'getFile');
|
||||||
|
|
||||||
$ctl[] = array('regex' => '#^/p/([\-\w]+)/source/treerev/$#',
|
$ctl[] = array('regex' => '#^/p/([\-\w]+)/source/treerev/$#',
|
||||||
'base' => $base,
|
'base' => $base,
|
||||||
'priority' => 4,
|
'priority' => 4,
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
{if count($diff.files)}
|
{if count($diff.files)}
|
||||||
<h2>{trans 'Change Details'}</h2>
|
<h2>{trans 'Change Details'}</h2>
|
||||||
|
|
||||||
{$diff.as_html()|safe}
|
{$diff.as_html()}
|
||||||
{/if}
|
{/if}
|
||||||
{/block}
|
{/block}
|
||||||
{block context}
|
{block context}
|
||||||
|
21
src/IDF/templates/source/git/file.html
Normal file
21
src/IDF/templates/source/git/file.html
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
{extends "source/base.html"}
|
||||||
|
{block docclass}yui-t1{assign $inSourceTree=true}{/block}
|
||||||
|
{block body}
|
||||||
|
<h2 class="top"><a href="{url 'IDF_Views_Source::treeBase', array($project.shortname, $commit)}">{trans 'Root'}</a><span class="sep">/</span>{if $breadcrumb}{$breadcrumb|safe}{/if}</h2>
|
||||||
|
|
||||||
|
<table class="code" summary=" ">
|
||||||
|
{$file}
|
||||||
|
</table>
|
||||||
|
{aurl 'url', 'IDF_Views_Source::getFile', array($project.shortname, $commit, $fullpath)}
|
||||||
|
<p class="right soft"><a href="{$url}"><img style="vertical-align: text-bottom;" src="{media '/idf/img/package-grey.png'}" alt="{trans 'Archive'}" align="bottom" /></a> <a href="{$url}">{trans 'Download this file'}</a></p>
|
||||||
|
|
||||||
|
|
||||||
|
{/block}
|
||||||
|
{block context}
|
||||||
|
<p><strong>{trans 'Branches:'}</strong><br />
|
||||||
|
{foreach $branches as $branch}
|
||||||
|
{aurl 'url', 'IDF_Views_Source::treeBase', array($project.shortname, $branch)}
|
||||||
|
<span class="label{if $commit == $branch} active{/if}"><a href="{$url}" class="label">{$branch}</a></span><br />
|
||||||
|
{/foreach}
|
||||||
|
</p>
|
||||||
|
{/block}
|
@ -1,7 +1,7 @@
|
|||||||
{extends "source/base.html"}
|
{extends "source/base.html"}
|
||||||
{block docclass}yui-t1{assign $inSourceTree=true}{/block}
|
{block docclass}yui-t1{assign $inSourceTree=true}{/block}
|
||||||
{block body}
|
{block body}
|
||||||
<h2><a href="{url 'IDF_Views_Source::treeBase', array($project.shortname, $commit)}">{trans 'Root'}</a><span class="sep">/</span>{if $breadcrumb}{$breadcrumb|safe}{/if}</h2>
|
<h2 class="top"><a href="{url 'IDF_Views_Source::treeBase', array($project.shortname, $commit)}">{trans 'Root'}</a><span class="sep">/</span>{if $breadcrumb}{$breadcrumb|safe}{/if}</h2>
|
||||||
|
|
||||||
<table summary="" class="tree-list">
|
<table summary="" class="tree-list">
|
||||||
<thead>
|
<thead>
|
||||||
|
23
src/IDF/templates/source/svn/file.html
Normal file
23
src/IDF/templates/source/svn/file.html
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
{extends "source/base.html"}
|
||||||
|
{block docclass}yui-t1{assign $inSourceTree=true}{/block}
|
||||||
|
{block body}
|
||||||
|
<h2 class="top"><a href="{url 'IDF_Views_Source::treeBase', array($project.shortname, $commit)}">{trans 'Root'}</a><span class="sep">/</span>{if $breadcrumb}{$breadcrumb|safe}{/if}</h2>
|
||||||
|
|
||||||
|
<table class="code" summary=" ">
|
||||||
|
{$file}
|
||||||
|
</table>
|
||||||
|
{aurl 'url', 'IDF_Views_Source::getFile', array($project.shortname, $commit, $fullpath)}
|
||||||
|
<p class="right soft"><a href="{$url}"><img style="vertical-align: text-bottom;" src="{media '/idf/img/package-grey.png'}" alt="{trans 'Archive'}" align="bottom" /></a> <a href="{$url}">{trans 'Download this file'}</a></p>
|
||||||
|
|
||||||
|
|
||||||
|
{/block}
|
||||||
|
{block context}
|
||||||
|
<form class="star" action="{url 'IDF_Views_Source_Svn::treeRev', array($project.shortname)}" method="get">
|
||||||
|
<p><strong>{trans 'Revision:'}</strong> {$commit}</p>
|
||||||
|
<p>
|
||||||
|
<input accesskey="4" type="text" value="{$commit}" name="rev" size="5" />
|
||||||
|
<input type="hidden" name="sourcefile" value="{$base}"/>
|
||||||
|
<input type="submit" name="s" value="{trans 'Go to revision'}" /></p>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
{/block}
|
@ -1,7 +1,7 @@
|
|||||||
{extends "source/base.html"}
|
{extends "source/base.html"}
|
||||||
{block docclass}yui-t1{assign $inSourceTree=true}{/block}
|
{block docclass}yui-t1{assign $inSourceTree=true}{/block}
|
||||||
{block body}
|
{block body}
|
||||||
<h2><a href="{url 'IDF_Views_Source::treeBase', array($project.shortname, $commit)}">{trans 'Root'}</a><span class="sep">/</span>{if $breadcrumb}{$breadcrumb|safe}{/if}</h2>
|
<h2 class="top"><a href="{url 'IDF_Views_Source::treeBase', array($project.shortname, $commit)}">{trans 'Root'}</a><span class="sep">/</span>{if $breadcrumb}{$breadcrumb|safe}{/if}</h2>
|
||||||
|
|
||||||
<table summary="" class="tree-list">
|
<table summary="" class="tree-list">
|
||||||
<thead>
|
<thead>
|
||||||
|
@ -19,6 +19,10 @@
|
|||||||
#
|
#
|
||||||
# ***** END LICENSE BLOCK ***** */
|
# ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
|
h2.top {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.yui-g {
|
.yui-g {
|
||||||
padding: 0 1em;
|
padding: 0 1em;
|
||||||
}
|
}
|
||||||
@ -480,6 +484,57 @@ table.diff tr.diff-next td {
|
|||||||
padding: 1px 5px;
|
padding: 1px 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* view file content
|
||||||
|
*/
|
||||||
|
table.code {
|
||||||
|
border-bottom: 1px solid #d3d7cf;
|
||||||
|
border-top: 1px solid #d3d7cf;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.code tr {
|
||||||
|
border-left: 1px solid #d3d7cf;
|
||||||
|
border-right: 1px solid #d3d7cf;
|
||||||
|
border-bottom: none;
|
||||||
|
border-top: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.code td {
|
||||||
|
font-size: 90%;
|
||||||
|
vertical-align: top;
|
||||||
|
padding: 1px;
|
||||||
|
border-color: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.code td.code {
|
||||||
|
border: none;
|
||||||
|
/* Whitespace hacking from: http://ln.hixie.ch/ */
|
||||||
|
white-space: pre; /* CSS2 */
|
||||||
|
white-space: -moz-pre-wrap; /* Mozilla */
|
||||||
|
white-space: -hp-pre-wrap; /* HP printers */
|
||||||
|
white-space: -o-pre-wrap; /* Opera 7 */
|
||||||
|
white-space: -pre-wrap; /* Opera 4-6 */
|
||||||
|
white-space: pre-wrap; /* CSS 2.1 */
|
||||||
|
white-space: pre-line; /* CSS 3 (and 2.1 as well, actually) */
|
||||||
|
word-wrap: break-word; /* IE */
|
||||||
|
padding-left: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.code td.code-lc {
|
||||||
|
text-align: right;
|
||||||
|
padding: 1px 5px;
|
||||||
|
border-color: inherit;
|
||||||
|
border-top: 1px solid #d3d7cf;
|
||||||
|
border-bottom: 1px solid #d3d7cf;
|
||||||
|
width: 3em;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.code td.code-lc a {
|
||||||
|
color: #555753;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Download
|
* Download
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user