[Notice] Announcing the End of Demo Server [Read me]
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
2013-12-17
@(diff: playRepository.FileDiff, comments: java.util.List[_ <: CodeComment], projectB: Project, projectA: Project)
@import playRepository.DiffLineType
@import playRepository.DiffLine
@import playRepository.FileDiff
@import org.eclipse.jgit.diff.DiffEntry
@import org.eclipse.jgit.diff.RawText
@import utils.TemplateHelper.DiffRenderer._
@import utils.TemplateHelper._
@import scala.collection.immutable.Map
@import scala.collection.immutable.List
@import scala.collection.JavaConversions._
@import org.apache.commons.lang.StringEscapeUtils.escapeHtml;
@**
* 변경 내용(Diff) 표시
*
* @param diff
* @param comments
**@
@renderDiffLines(diff: playRepository.FileDiff, comments: Map[String, List[_ <: CodeComment]]) = {
@if(diff.isFileModeChanged) {
<tr><td class="filemode">@diff.oldMode</td><td class="filemode">@diff.newMode</td><td>@Messages("code.fileModeChanged")</td></tr>
}
@if(diff.getHunks.size > 0){
@for(hunk <- diff.getHunks) {
<tr class="range"><td>...</td><td>...</td><td>@@@@ -@(hunk.beginA + 1),@(hunk.endA - hunk.beginA) +@(hunk.beginB + 1),@(hunk.endB - hunk.beginB) @@@@</td></tr>
@Html(renderLines(hunk.lines.toList, comments, eolMissingChecker(diff)))
}
} else {
@if(!diff.isFileModeChanged) {
<tr><td colspan=3>@Messages("code.noChanges")</td></tr>
}
}
}
@**
* 파일 내용 표시
*
* 성능 문제를 해결하기 위해 StringBuilder를 사용했다.
*
* 주의: StringBuilder는 thread-safe 하지 않다.
*
* @param klass
* @param path
* @param rawText
* @param kind
* @param prefix
* @param comments
**@
@renderRawFile(klass: String, path: String, rawText: RawText, side: CodeComment.Side, prefix: String, comments: Map[String, List[_ <: CodeComment]]) = {
@defining(new StringBuilder) { builder =>
@for(i <- 0 until rawText.size) @{
builder.append("<tr class='")
builder.append(klass)
builder.append("' data-line='")
builder.append(i + 1)
builder.append("' data-type='")
builder.append(klass)
builder.append("'><td class='linenum'><i class='icon-comment'></i></td><td class='linenum' data-line-num='")
builder.append(i + 1)
builder.append("'><span class='hidden'>")
builder.append(i + 1)
builder.append("</span></td><td class='code'><span>")
builder.append(prefix)
builder.append("</span>")
builder.append(escapeHtml(rawText.getString(i)))
if ((i + 1 == rawText.size) && rawText.isMissingNewlineAtEnd) {
builder.append(noNewlineAtEof)
}
builder.append("</td></tr>")
builder.append(partial_diff_comment_on_line(commentsOrEmpty(comments, commentKey(path, side, i + 1))).toString.trim)
}
@Html(builder.toString)
}
}
@**
* 추가된 라인 표시
*
* @param rawText
* @param path
* @param comments
* @param isBinaryOverwritten 기존 데이터가 바이너리인 경우 true
**@
@renderAddedLines(rawText: RawText, path: String, comments:Map[String, List[_ <: CodeComment]], isBinaryOverwritten: Boolean = false) = {
<tr class="range"><td>...</td><td>...</td><td>@@@@ -0,0 +1,@rawText.size @@@@</td></tr>
@if(isBinaryOverwritten ){
@renderCodeIsBinary("remove", "-")
}
@renderRawFile("add", path, rawText, CodeComment.Side.B, "+", comments)
}
@**
* 삭제된 라인 표시
*
* @param rawText
* @param path
* @param comments
* @param isOverwrittenByBinary 새 데이터가 바이너리인 경우 true
**@
@renderRemovedLines(rawText: RawText, path: String, comments:Map[String, List[_ <: CodeComment]], isOverwrittenByBinary: Boolean = false) = {
<tr class="range"><td>...</td><td>...</td><td>@@@@ -1,@rawText.size +0,0 @@@@</td></tr>
@renderRawFile("remove", path, rawText, CodeComment.Side.A, "-", comments)
@if(isOverwrittenByBinary){
@renderCodeIsBinary("add", "+")
}
}
@**
* 커밋 아이디를 ShortId 로 만듭니다
* SVN 인 경우 7자 이하인 경우가 많기 때문
*
* @param commitId
**@
@getShortenedCommitId(commitId:String) = @{
if(commitId.length < 7){
commitId
} else {
commitId.substring(0,7)
}
}
@getFileHeadId(diff: FileDiff) = @{
defining(Option(diff.pathB).getOrElse(diff.pathA)) { path =>
path.replace("/", "-").replace(".", "-")
}
}
@**
* 파일 헤더를 포함한 변경점 렌더링
*
* @param diff
* @param fileHeader
* @param renderedLines
**@
@renderFile(diff: FileDiff, fileHeader: String, renderedLines: Html) = {
<table class="diff-body show-comments" data-path-a="@diff.pathA" data-path-b="@diff.pathB" data-commit-a="@diff.commitA" data-commit-b="@diff.commitB"><tbody>
<tr id="@getFileHeadId(diff)" class="file">
<td class="linenum-from">
@if(diff.commitA != null && diff.pathA != null){
<a href="@routes.CodeApp.codeBrowserWithBranch(projectA.owner, projectA.name, diff.commitA, diff.pathA)" title="@diff.commitA" target="_blank">@getShortenedCommitId(diff.commitA)</a>
}
</td>
<td class="linenum-to">
@if(diff.commitB != null && diff.pathB != null){
<a href="@routes.CodeApp.codeBrowserWithBranch(projectB.owner, projectB.name, diff.commitB, diff.pathB)" title="@diff.commitB" target="_blank">@getShortenedCommitId(diff.commitB)</a></td>
}
<td class="line-body">
<span class="filename">@fileHeader</span>
@if(diff.commitA && diff.commitB && diff.pathA && diff.pathB){
<button type="button" class="ybtn pull-right" data-toggle="mergely"
data-pathA="@diff.pathA" data-pathB="@diff.pathB" data-commitA="@diff.commitA" data-commitB="@diff.commitB"
data-rawA="@routes.CodeApp.showRawFile(projectA.owner, projectA.name, diff.commitA, diff.pathA)"
data-rawB="@routes.CodeApp.showRawFile(projectB.owner, projectB.name, diff.commitB, diff.pathB)"
>@Messages("code.fullDiff")</button>
}
</td>
</tr>
@renderedLines
</tbody></table>
}
@**
* 바이너리 파일이면 경로명 뒤에 (Binary) 붙이기
*
* @param path
* @param isBinary
**@
@getPathPostfixedBinary(path:String, isBinary:Boolean) = @{
path + (if (isBinary) { " (Binary)" } else { "" } )
}
@**
* 파일 헤더 영역 메시지
*
* @param headerType
* @param diff
**@
@getFileHeaderMessage(headerType:DiffEntry.ChangeType, diff:FileDiff) = @{
headerType match {
case DiffEntry.ChangeType.MODIFY => { getPathPostfixedBinary(diff.pathB, diff.isBinaryB) }
case DiffEntry.ChangeType.ADD => { Messages("code.addedPath", getPathPostfixedBinary(diff.pathB, diff.isBinaryB)) }
case DiffEntry.ChangeType.DELETE => { Messages("code.deletedPath", getPathPostfixedBinary(diff.pathA, diff.isBinaryA)) }
case DiffEntry.ChangeType.RENAME => { Messages("code.renamedPath", getPathPostfixedBinary(diff.pathA, diff.isBinaryA), getPathPostfixedBinary(diff.pathB, diff.isBinaryB)) }
case DiffEntry.ChangeType.COPY => { Messages("code.copiedPath", getPathPostfixedBinary(diff.pathA, diff.isBinaryA), getPathPostfixedBinary(diff.pathB, diff.isBinaryB)) }
case _ => { "" }
}
}
@**
* 바이너리 파일입니다 표시
* 이 영역에는 댓글을 달 수 없음
*
* @param klass CSS 클래스명. add/remove
* @param prefix
**@
@renderCodeIsBinary(klass:String = "", prefix:String = "") = {
<tr class="@klass"><td></td><td></td><td class="isBinary">@prefix@Messages("code.isBinary")</td></tr>
}
@getComments(comments: java.util.List[_ <: CodeComment]) = @{
if(comments != null){
comments.toList.groupBy((comment: CodeComment) => commentKey(comment.path, comment.side, comment.line))
} else {
null
}
}
@defining(getComments(comments)) { comments =>
@diff.changeType match {
case DiffEntry.ChangeType.MODIFY => {
@(diff.isBinaryA, diff.isBinaryB) match {
case (true, true) => { @renderFile(diff, getFileHeaderMessage(DiffEntry.ChangeType.MODIFY, diff), renderCodeIsBinary()) }
case (true, false) => { @renderFile(diff, getFileHeaderMessage(DiffEntry.ChangeType.MODIFY, diff), renderAddedLines(diff.b, diff.pathB, comments, true)) }
case (false, true) => { @renderFile(diff, getFileHeaderMessage(DiffEntry.ChangeType.MODIFY, diff), renderRemovedLines(diff.a, diff.pathA, comments, true)) }
case (false, false) => { @renderFile(diff, diff.pathB, renderDiffLines(diff, comments)) }
}
}
case DiffEntry.ChangeType.ADD => {
@if(diff.isBinaryB){
@renderFile(diff, getFileHeaderMessage(DiffEntry.ChangeType.ADD, diff), renderCodeIsBinary())
} else {
@renderFile(diff, getFileHeaderMessage(DiffEntry.ChangeType.ADD, diff), renderAddedLines(diff.b, diff.pathB, comments))
}
}
case DiffEntry.ChangeType.DELETE => {
@if(diff.isBinaryA){
@renderFile(diff, getFileHeaderMessage(DiffEntry.ChangeType.DELETE, diff), renderCodeIsBinary())
} else {
@renderFile(diff, Messages("code.deletedPath", diff.pathA), renderRemovedLines(diff.a, diff.pathA, comments))
}
}
case DiffEntry.ChangeType.RENAME => {
@(diff.isBinaryA, diff.isBinaryB) match {
case (true, true) => { @renderFile(diff, getFileHeaderMessage(DiffEntry.ChangeType.RENAME, diff), renderCodeIsBinary()) }
case (true, false) => { @renderFile(diff, getFileHeaderMessage(DiffEntry.ChangeType.RENAME, diff), renderAddedLines(diff.b, diff.pathB, comments, true)) }
case (false, true) => { @renderFile(diff, getFileHeaderMessage(DiffEntry.ChangeType.RENAME, diff), renderRemovedLines(diff.a, diff.pathA, comments, true)) }
case (false, false) => { @renderFile(diff, Messages("code.renamedPath", diff.pathA, diff.pathB), renderDiffLines(diff, comments)) }
}
}
case DiffEntry.ChangeType.COPY => {
@if(diff.isBinaryB){
@renderFile(diff, getFileHeaderMessage(DiffEntry.ChangeType.COPY, diff), renderCodeIsBinary())
} else {
@renderFile(diff, Messages("code.copiedPath", diff.pathA, diff.pathB), renderAddedLines(diff.b, diff.pathB, comments))
}
}
}
}