diff --git a/src/main/scala/gitbucket/core/controller/PullRequestsController.scala b/src/main/scala/gitbucket/core/controller/PullRequestsController.scala index 21481cc..d7059ee 100644 --- a/src/main/scala/gitbucket/core/controller/PullRequestsController.scala +++ b/src/main/scala/gitbucket/core/controller/PullRequestsController.scala @@ -144,25 +144,6 @@ getRepository(pullreq.requestUserName, pullreq.requestRepositoryName), flash.iterator.map(f => f._1 -> f._2.toString).toMap ) - -// html.pullreq( -// issue, -// pullreq, -// comments, -// getIssueLabels(owner, name, issueId), -// getAssignableUserNames(owner, name), -// getMilestonesWithIssueCount(owner, name), -// getPriorities(owner, name), -// getLabels(owner, name), -// commits, -// diffs, -// isEditable(repository), -// isManageable(repository), -// hasDeveloperRole(pullreq.requestUserName, pullreq.requestRepositoryName, context.loginAccount), -// repository, -// getRepository(pullreq.requestUserName, pullreq.requestRepositoryName), -// flash.toMap.map(f => f._1 -> f._2.toString) -// ) } } getOrElse NotFound() }) @@ -396,9 +377,9 @@ }) get("/:owner/:repository/compare")(referrersOnly { forkedRepository => - val headBranch: Option[String] = params.get("head") + val headBranch = params.get("head") (forkedRepository.repository.originUserName, forkedRepository.repository.originRepositoryName) match { - case (Some(originUserName), Some(originRepositoryName)) => { + case (Some(originUserName), Some(originRepositoryName)) => getRepository(originUserName, originRepositoryName).map { originRepository => Using.resources( @@ -415,8 +396,7 @@ ) } } getOrElse NotFound() - } - case _ => { + case _ => Using.resource(Git.open(getRepositoryDir(forkedRepository.owner, forkedRepository.name))) { git => JGitUtil.getDefaultBranch(git, forkedRepository).map { case (_, defaultBranch) => @@ -427,41 +407,48 @@ redirect(s"/${forkedRepository.owner}/${forkedRepository.name}") } } - } } }) + private def getOriginRepositoryName( + originOwner: String, + forkedOwner: String, + forkedRepository: RepositoryInfo + ): Option[String] = { + if (originOwner == forkedOwner) { + // Self repository + Some(forkedRepository.name) + } else if (forkedRepository.repository.originUserName.isEmpty) { + // when ForkedRepository is the original repository + getForkedRepositories(forkedRepository.owner, forkedRepository.name) + .find(_.userName == originOwner) + .map(_.repositoryName) + } else if (Some(originOwner) == forkedRepository.repository.originUserName) { + // Original repository + forkedRepository.repository.originRepositoryName + } else { + // Sibling repository + getUserRepositories(originOwner) + .find { x => + x.repository.originUserName == forkedRepository.repository.originUserName && + x.repository.originRepositoryName == forkedRepository.repository.originRepositoryName + } + .map(_.repository.repositoryName) + } + } + get("/:owner/:repository/compare/*...*")(referrersOnly { forkedRepository => val Seq(origin, forked) = multiParams("splat") val (originOwner, originId) = parseCompareIdentifier(origin, forkedRepository.owner) val (forkedOwner, forkedId) = parseCompareIdentifier(forked, forkedRepository.owner) - (for (originRepositoryName <- if (originOwner == forkedOwner) { - // Self repository - Some(forkedRepository.name) - } else if (forkedRepository.repository.originUserName.isEmpty) { - // when ForkedRepository is the original repository - getForkedRepositories(forkedRepository.owner, forkedRepository.name) - .find(_.userName == originOwner) - .map(_.repositoryName) - } else if (Some(originOwner) == forkedRepository.repository.originUserName) { - // Original repository - forkedRepository.repository.originRepositoryName - } else { - // Sibling repository - getUserRepositories(originOwner) - .find { x => - x.repository.originUserName == forkedRepository.repository.originUserName && - x.repository.originRepositoryName == forkedRepository.repository.originRepositoryName - } - .map(_.repository.repositoryName) - }; + (for (originRepositoryName <- getOriginRepositoryName(originOwner, forkedOwner, forkedRepository); originRepository <- getRepository(originOwner, originRepositoryName)) yield { val (oldId, newId) = getPullRequestCommitFromTo(originRepository, forkedRepository, originId, forkedId) (oldId, newId) match { - case (Some(oldId), Some(newId)) => { + case (Some(oldId), Some(newId)) => val (commits, diffs) = getRequestCompareInfo( originRepository.owner, originRepository.name, @@ -512,7 +499,6 @@ getLabels(originRepository.owner, originRepository.name), getCustomFields(originRepository.owner, originRepository.name).filter(_.enableForPullRequests) ) - } case (oldId, newId) => redirect( s"/${forkedRepository.owner}/${forkedRepository.name}/compare/" + @@ -524,6 +510,54 @@ }) getOrElse NotFound() }) + ajaxGet("/:owner/:repository/diff/:id")(referrersOnly { repository => + (for { + commitId <- params.get("id") + path <- params.get("path") + diff <- getSingleDiff(repository.owner, repository.name, commitId, path) + } yield { + contentType = formats("json") + org.json4s.jackson.Serialization.write( + Map( + "oldContent" -> diff.oldContent, + "newContent" -> diff.newContent + ) + ) + }) getOrElse NotFound() + }) + + ajaxGet("/:owner/:repository/diff/*...*")(referrersOnly { forkedRepository => + val Seq(origin, forked) = multiParams("splat") + val (originOwner, originId) = parseCompareIdentifier(origin, forkedRepository.owner) + val (forkedOwner, forkedId) = parseCompareIdentifier(forked, forkedRepository.owner) + + (for { + path <- params.get("path") + originRepositoryName <- getOriginRepositoryName(originOwner, forkedOwner, forkedRepository) + originRepository <- getRepository(originOwner, originRepositoryName) + (oldId, newId) = getPullRequestCommitFromTo(originRepository, forkedRepository, originId, forkedId) + oldId <- oldId + newId <- newId + diff <- getSingleDiff( + originRepository.owner, + originRepository.name, + oldId.getName, + forkedRepository.owner, + forkedRepository.name, + newId.getName, + path + ) + } yield { + contentType = formats("json") + org.json4s.jackson.Serialization.write( + Map( + "oldContent" -> diff.oldContent, + "newContent" -> diff.newContent + ) + ) + }) getOrElse NotFound() + }) + ajaxGet("/:owner/:repository/compare/*...*/mergecheck")(readableUsersOnly { forkedRepository => val Seq(origin, forked) = multiParams("splat") val (originOwner, tmpOriginBranch) = parseCompareIdentifier(origin, forkedRepository.owner) diff --git a/src/main/scala/gitbucket/core/controller/RepositoryViewerController.scala b/src/main/scala/gitbucket/core/controller/RepositoryViewerController.scala index 4026a53..ba09e06 100644 --- a/src/main/scala/gitbucket/core/controller/RepositoryViewerController.scala +++ b/src/main/scala/gitbucket/core/controller/RepositoryViewerController.scala @@ -331,15 +331,12 @@ post("/:owner/:repository/upload", uploadForm)(writableUsersOnly { (form, repository) => def _commit( branchName: String, - //files: Seq[CommitFile], newFiles: Seq[CommitFile], loginAccount: Account ): Either[String, ObjectId] = { commitFiles( repository = repository, branch = branchName, - //path = form.path, - //files = files.toIndexedSeq, message = form.message.getOrElse("Add files via upload"), loginAccount = loginAccount, settings = context.settings @@ -614,7 +611,7 @@ } else { _commit(form.branch, loginAccount) match { case Right(_) => - if (form.path.length == 0) { + if (form.path.isEmpty) { redirect(s"/${repository.owner}/${repository.name}/tree/${encodeRefName(form.branch)}") } else { redirect( diff --git a/src/main/scala/gitbucket/core/service/PullRequestService.scala b/src/main/scala/gitbucket/core/service/PullRequestService.scala index 925a4f7..b98ce2b 100644 --- a/src/main/scala/gitbucket/core/service/PullRequestService.scala +++ b/src/main/scala/gitbucket/core/service/PullRequestService.scala @@ -472,6 +472,40 @@ } } + def getSingleDiff( + userName: String, + repositoryName: String, + commitId: String, + path: String + ): Option[DiffInfo] = { + Using.resource( + Git.open(getRepositoryDir(userName, repositoryName)) + ) { git => + val newId = git.getRepository.resolve(commitId) + JGitUtil.getDiff(git, None, newId.getName, path) + } + } + + def getSingleDiff( + userName: String, + repositoryName: String, + branch: String, + requestUserName: String, + requestRepositoryName: String, + requestCommitId: String, + path: String + ): Option[DiffInfo] = { + Using.resources( + Git.open(getRepositoryDir(userName, repositoryName)), + Git.open(getRepositoryDir(requestUserName, requestRepositoryName)) + ) { (oldGit, newGit) => + val oldId = oldGit.getRepository.resolve(branch) + val newId = newGit.getRepository.resolve(requestCommitId) + + JGitUtil.getDiff(newGit, Some(oldId.getName), newId.getName, path) + } + } + def getRequestCompareInfo( userName: String, repositoryName: String, diff --git a/src/main/scala/gitbucket/core/util/JGitUtil.scala b/src/main/scala/gitbucket/core/util/JGitUtil.scala index 77e3449..ab63856 100644 --- a/src/main/scala/gitbucket/core/util/JGitUtil.scala +++ b/src/main/scala/gitbucket/core/util/JGitUtil.scala @@ -37,7 +37,7 @@ private val logger = LoggerFactory.getLogger(JGitUtil.getClass) - implicit val objectDatabaseReleasable: Releasable[ObjectDatabase] = + private implicit val objectDatabaseReleasable: Releasable[ObjectDatabase] = _.close() /** @@ -690,7 +690,7 @@ val toCommit = revWalk.parseCommit(git.getRepository.resolve(to)) (from match { - case None => { + case None => toCommit.getParentCount match { case 0 => df.scan( @@ -700,11 +700,9 @@ .asScala case _ => df.scan(toCommit.getParent(0), toCommit.getTree).asScala } - } - case Some(from) => { + case Some(from) => val fromCommit = revWalk.parseCommit(git.getRepository.resolve(from)) df.scan(fromCommit.getTree, toCommit.getTree).asScala - } }).toSeq } } @@ -719,6 +717,29 @@ } } + def getDiff(git: Git, from: Option[String], to: String, path: String): Option[DiffInfo] = { + getDiffEntries(git, from, to).find(_.getNewPath == path).map { diff => + val oldIsImage = FileUtil.isImage(diff.getOldPath) + val newIsImage = FileUtil.isImage(diff.getNewPath) + val includeContent = oldIsImage || newIsImage + DiffInfo( + changeType = diff.getChangeType, + oldPath = diff.getOldPath, + newPath = diff.getNewPath, + oldContent = if (includeContent) None else getTextContent(git, diff.getOldId.toObjectId), + newContent = if (includeContent) None else getTextContent(git, diff.getNewId.toObjectId), + oldIsImage = oldIsImage, + newIsImage = newIsImage, + oldObjectId = Option(diff.getOldId).map(_.name), + newObjectId = Option(diff.getNewId).map(_.name), + oldMode = diff.getOldMode.toString, + newMode = diff.getNewMode.toString, + tooLarge = false, + patch = None + ) + } + } + def getDiffs( git: Git, from: Option[String], @@ -728,7 +749,7 @@ ): List[DiffInfo] = { val diffs = getDiffEntries(git, from, to) diffs.map { diff => - if (diffs.size > 100) { + if (diffs.size > 100) { // Don't show diff if there are more than 100 files DiffInfo( changeType = diff.getChangeType, oldPath = diff.getOldPath, @@ -747,49 +768,35 @@ } else { val oldIsImage = FileUtil.isImage(diff.getOldPath) val newIsImage = FileUtil.isImage(diff.getNewPath) - if (!fetchContent || oldIsImage || newIsImage) { - DiffInfo( - changeType = diff.getChangeType, - oldPath = diff.getOldPath, - newPath = diff.getNewPath, - oldContent = None, - newContent = None, - oldIsImage = oldIsImage, - newIsImage = newIsImage, - oldObjectId = Option(diff.getOldId).map(_.name), - newObjectId = Option(diff.getNewId).map(_.name), - oldMode = diff.getOldMode.toString, - newMode = diff.getNewMode.toString, - tooLarge = false, - patch = (if (makePatch) Some(makePatchFromDiffEntry(git, diff)) else None) // TODO use DiffFormatter - ) - } else { - DiffInfo( - changeType = diff.getChangeType, - oldPath = diff.getOldPath, - newPath = diff.getNewPath, - oldContent = JGitUtil - .getContentFromId(git, diff.getOldId.toObjectId, false) - .filter(FileUtil.isText) - .map(convertFromByteArray), - newContent = JGitUtil - .getContentFromId(git, diff.getNewId.toObjectId, false) - .filter(FileUtil.isText) - .map(convertFromByteArray), - oldIsImage = oldIsImage, - newIsImage = newIsImage, - oldObjectId = Option(diff.getOldId).map(_.name), - newObjectId = Option(diff.getNewId).map(_.name), - oldMode = diff.getOldMode.toString, - newMode = diff.getNewMode.toString, - tooLarge = false, - patch = (if (makePatch) Some(makePatchFromDiffEntry(git, diff)) else None) // TODO use DiffFormatter - ) - } + val patch = if (oldIsImage || newIsImage) None else Some(makePatchFromDiffEntry(git, diff)) // TODO use DiffFormatter + val tooLarge = patch.exists(_.count(_ == '\n') > 1000) // Don't show diff if the file has more than 1000 lines diff + val includeContent = tooLarge || !fetchContent || oldIsImage || newIsImage + DiffInfo( + changeType = diff.getChangeType, + oldPath = diff.getOldPath, + newPath = diff.getNewPath, + oldContent = if (includeContent) None else getTextContent(git, diff.getOldId.toObjectId), + newContent = if (includeContent) None else getTextContent(git, diff.getNewId.toObjectId), + oldIsImage = oldIsImage, + newIsImage = newIsImage, + oldObjectId = Option(diff.getOldId).map(_.name), + newObjectId = Option(diff.getNewId).map(_.name), + oldMode = diff.getOldMode.toString, + newMode = diff.getNewMode.toString, + tooLarge = tooLarge, + patch = if (makePatch) patch else None + ) } }.toList } + private def getTextContent(git: Git, objectId: ObjectId): Option[String] = { + JGitUtil + .getContentFromId(git, objectId, false) + .filter(FileUtil.isText) + .map(convertFromByteArray) + } + private def makePatchFromDiffEntry(git: Git, diff: DiffEntry): String = { val out = new ByteArrayOutputStream() Using.resource(new DiffFormatter(out)) { formatter => diff --git a/src/main/twirl/gitbucket/core/helper/diff.scala.html b/src/main/twirl/gitbucket/core/helper/diff.scala.html index 92999c9..4579a90 100644 --- a/src/main/twirl/gitbucket/core/helper/diff.scala.html +++ b/src/main/twirl/gitbucket/core/helper/diff.scala.html @@ -100,38 +100,48 @@ - @if(diff.oldObjectId == diff.newObjectId){ - @if(diff.oldPath != diff.newPath){ -
File renamed without changes
- } else { -
File mode changed
- } + @if(diff.tooLarge) { +
+ @if(oldCommitId.isEmpty && newCommitId.isDefined) { + Too large (Show diff) + } + @if(oldCommitId.isDefined && newCommitId.isDefined) { + Too large (Show diff) + } +
+
+ + } else { - @if(diff.newContent != None || diff.oldContent != None){ -
- - - } else { - @if(diff.newIsImage || diff.oldIsImage){ -
- @if(oldCommitId.isDefined && diff.oldIsImage){ -
- } else { - @if(diff.changeType != ChangeType.ADD){ -
Not supported
- } - } - @if(newCommitId.isDefined && diff.newIsImage){ -
- } else { - @if(diff.changeType != ChangeType.DELETE){ -
Not supported
- } - } -
+ @if(diff.oldObjectId == diff.newObjectId) { + @if(diff.oldPath != diff.newPath) { +
File renamed without changes
} else { - @if(diff.tooLarge){ -
Too large
+
File mode changed
+ } + } else { + @if(diff.newContent != None || diff.oldContent != None){ +
+ + + } else { + @if(diff.newIsImage || diff.oldIsImage){ +
+ @if(oldCommitId.isDefined && diff.oldIsImage){ +
+ } else { + @if(diff.changeType != ChangeType.ADD){ +
Not supported
+ } + } + @if(newCommitId.isDefined && diff.newIsImage){ +
+ } else { + @if(diff.changeType != ChangeType.DELETE){ +
Not supported
+ } + } +
} else {
Not supported
} @@ -200,53 +210,10 @@ renderOneDiff($(this).closest("table").find(".diffText"), window.viewType, $(this).closest("table").find(".file-hash")[0].id); }); - function getInlineContainer(where) { - if (window.viewType == 0) { - if (where === 'new') { - return $(''); - } else { - return $(''); - } - } - return $(''); - } - if (typeof $('#show-notes')[0] !== 'undefined' && !$('#show-notes')[0].checked) { $('#comment-list').children('.inline-comment').hide(); } - function showCommentForm(commitId, fileName, oldLineNumber, newLineNumber, $tr){ - // assemble Ajax url - let url = '@helpers.url(repository)/commit/' + commitId + '/comment/_form?fileName=' + fileName@issueId.map { id => + '&issueId=@id' }; - if (!isNaN(oldLineNumber) && oldLineNumber) { - url += ('&oldLineNumber=' + oldLineNumber) - } - if (!isNaN(newLineNumber) && newLineNumber) { - url += ('&newLineNumber=' + newLineNumber) - } - // send Ajax request - $.get(url, { dataType : 'html' }, function(responseContent) { - // create container - let tmp; - if (!isNaN(oldLineNumber) && oldLineNumber) { - if (!isNaN(newLineNumber) && newLineNumber) { - tmp = getInlineContainer(); - } else { - tmp = getInlineContainer('old'); - } - } else { - tmp = getInlineContainer('new'); - } - // add comment textarea - tmp.addClass('inline-comment-form').children('.comment-box-container').html(responseContent); - $tr.nextAll(':not(.not-diff):first').before(tmp); - // hide reply comment field - $(tmp).closest('.not-diff').prev().find('.reply-comment').closest('.not-diff').hide(); - // focus textarea - tmp.find('textarea').focus(); - }); - } - // Add comment button $('.diff-outside').on('click','table.diff .add-comment',function() { const $this = $(this); @@ -302,11 +269,156 @@ getSelection().empty(); updateHighlighting(); }); +}); - function renderOneCommitCommentIntoDiff($v, diff){ - //var filename = $v.attr('filename'); - const oldline = $v.attr('oldline'); - const newline = $v.attr('newline'); +function getInlineContainer(where) { + if (window.viewType == 0) { + if (where === 'new') { + return $(''); + } else { + return $(''); + } + } + return $(''); +} + +function showCommentForm(commitId, fileName, oldLineNumber, newLineNumber, $tr){ + // assemble Ajax url + let url = '@helpers.url(repository)/commit/' + commitId + '/comment/_form?fileName=' + fileName@issueId.map { id => + '&issueId=@id' }; + if (!isNaN(oldLineNumber) && oldLineNumber) { + url += ('&oldLineNumber=' + oldLineNumber) + } + if (!isNaN(newLineNumber) && newLineNumber) { + url += ('&newLineNumber=' + newLineNumber) + } + // send Ajax request + $.get(url, { dataType : 'html' }, function(responseContent) { + // create container + let tmp; + if (!isNaN(oldLineNumber) && oldLineNumber) { + if (!isNaN(newLineNumber) && newLineNumber) { + tmp = getInlineContainer(); + } else { + tmp = getInlineContainer('old'); + } + } else { + tmp = getInlineContainer('new'); + } + // add comment textarea + tmp.addClass('inline-comment-form').children('.comment-box-container').html(responseContent); + $tr.nextAll(':not(.not-diff):first').before(tmp); + // hide reply comment field + $(tmp).closest('.not-diff').prev().find('.reply-comment').closest('.not-diff').hide(); + // focus textarea + tmp.find('textarea').focus(); + }); +} + +function renderOneCommitCommentIntoDiff($v, diff){ + //var filename = $v.attr('filename'); + const oldline = $v.attr('oldline'); + const newline = $v.attr('newline'); + let tmp; + if (typeof oldline !== 'undefined') { + if (typeof newline !== 'undefined') { + tmp = getInlineContainer(); + } else { + tmp = getInlineContainer('old'); + } + tmp.children('td:first').html($v.clone().show()); + diff.find('table.diff').find('.oldline[line-number=' + oldline + ']').parent().nextAll(':not(.not-diff):first').before(tmp); + } else { + tmp = getInlineContainer('new'); + tmp.children('td:last').html($v.clone().show()); + diff.find('table.diff').find('.newline[line-number=' + newline + ']').parent().nextAll(':not(.not-diff):first').before(tmp); + } + if (!diff.find('.toggle-notes').prop('checked')) { + tmp.hide(); + } +} + +function renderStatBar(add, del){ + if(add + del > 5){ + if(add){ + if(add < del){ + add = Math.floor(1 + (add * 4 / (add + del))); + } else { + add = Math.ceil(1 + (add * 4 / (add + del))); + } + } + del = 5 - add; + } + const ret = $('
'); + for(let i = 0; i < 5; i++){ + if(add){ + ret.append(''); + add--; + } else if(del){ + ret.append(''); + del--; + } else { + ret.append('■'); + } + } + return ret; +} + +function renderOneDiff(diffText, viewType, fileHash){ + const table = diffText.closest("table[data-diff-id]"); + const i = table.data("diff-id"); + const ignoreWhiteSpace = table.find('.ignore-whitespace').prop('checked'); + diffUsingJS('oldText-' + i, 'newText-' + i, diffText.attr('id'), viewType, ignoreWhiteSpace, fileHash); + const add = diffText.find("table").attr("add") * 1; + const del = diffText.find("table").attr("del") * 1; + table.find(".diffstat").text(add + del + " ").append(renderStatBar(add, del)).attr("title", add + " additions & " + del + " deletions").tooltip(); + $('span.diffstat[data-diff-id="' + i + '"]') + .html('+' + add + '-' + del + '') + .append(renderStatBar(add, del).attr('title', (add + del) + " lines changed").tooltip()); + + @if(hasWritePermission) { + diffText.find('.body').filter(function(i, e) { + return $(e).has('span').length > 0; + }).each(function(){ + $('+').prependTo(this); + }); + } + @if(showLineNotes){ + const fileName = table.attr('filename'); + $('.inline-comment').each(function(i, v) { + if($(this).attr('filename') == fileName){ + renderOneCommitCommentIntoDiff($(this), table); + } + }); + } + return table; +} + +function renderReplyComment($table){ + const elements = {}; + let filename, newline, oldline; + $table.find('.comment-box-container .inline-comment').each(function(i, e){ + filename = $(e).attr('filename'); + newline = $(e).attr('newline'); + oldline = $(e).attr('oldline'); + const key = filename + '-' + newline + '-' + oldline; + elements[key] = { + element: $(e), + filename: filename, + newline: newline, + oldline: oldline + }; + }); + for(const key in elements){ + filename = elements[key]['filename']; + oldline = elements[key]['oldline']; //? elements[key]['oldline'] : ''; + newline = elements[key]['newline']; //? elements[key]['newline'] : ''; + + const $v = $('
') + .append($('')); + let tmp; if (typeof oldline !== 'undefined') { if (typeof newline !== 'undefined') { @@ -314,134 +426,51 @@ } else { tmp = getInlineContainer('old'); } - tmp.children('td:first').html($v.clone().show()); - diff.find('table.diff').find('.oldline[line-number=' + oldline + ']').parent().nextAll(':not(.not-diff):first').before(tmp); + tmp.children('td:first').html($v); } else { tmp = getInlineContainer('new'); - tmp.children('td:last').html($v.clone().show()); - diff.find('table.diff').find('.newline[line-number=' + newline + ']').parent().nextAll(':not(.not-diff):first').before(tmp); + tmp.children('td:last').html($v); } - if (!diff.find('.toggle-notes').prop('checked')) { - tmp.hide(); - } + elements[key]['element'].closest('.not-diff').after(tmp); } +} - function renderStatBar(add, del){ - if(add + del > 5){ - if(add){ - if(add < del){ - add = Math.floor(1 + (add * 4 / (add + del))); - } else { - add = Math.ceil(1 + (add * 4 / (add + del))); - } +function renderDiffs() { + const diffs = $('.diffText'); + let i = 0; + function render(){ + if (diffs[i]) { + const $table = renderOneDiff($(diffs[i]), window.viewType, $('.file-hash')[i].id); + @if(hasWritePermission) { + renderReplyComment($table); } - del = 5 - add; - } - const ret = $('
'); - for(let i = 0; i < 5; i++){ - if(add){ - ret.append(''); - add--; - } else if(del){ - ret.append(''); - del--; - } else { - ret.append('■'); - } - } - return ret; - } - - function renderOneDiff(diffText, viewType, fileHash){ - const table = diffText.closest("table[data-diff-id]"); - const i = table.data("diff-id"); - const ignoreWhiteSpace = table.find('.ignore-whitespace').prop('checked'); - diffUsingJS('oldText-' + i, 'newText-' + i, diffText.attr('id'), viewType, ignoreWhiteSpace, fileHash); - const add = diffText.find("table").attr("add") * 1; - const del = diffText.find("table").attr("del") * 1; - table.find(".diffstat").text(add + del + " ").append(renderStatBar(add, del)).attr("title", add + " additions & " + del + " deletions").tooltip(); - $('span.diffstat[data-diff-id="' + i + '"]') - .html('+' + add + '-' + del + '') - .append(renderStatBar(add, del).attr('title', (add + del) + " lines changed").tooltip()); - - @if(hasWritePermission) { - diffText.find('.body').filter(function(i, e) { - return $(e).has('span').length > 0; - }).each(function(){ - $('+').prependTo(this); - }); - } - @if(showLineNotes){ - const fileName = table.attr('filename'); - $('.inline-comment').each(function(i, v) { - if($(this).attr('filename') == fileName){ - renderOneCommitCommentIntoDiff($(this), table); - } - }); - } - return table; - } - - function renderReplyComment($table){ - const elements = {}; - let filename, newline, oldline; - $table.find('.comment-box-container .inline-comment').each(function(i, e){ - filename = $(e).attr('filename'); - newline = $(e).attr('newline'); - oldline = $(e).attr('oldline'); - const key = filename + '-' + newline + '-' + oldline; - elements[key] = { - element: $(e), - filename: filename, - newline: newline, - oldline: oldline - }; - }); - for(const key in elements){ - filename = elements[key]['filename']; - oldline = elements[key]['oldline']; //? elements[key]['oldline'] : ''; - newline = elements[key]['newline']; //? elements[key]['newline'] : ''; - - const $v = $('
') - .append($('')); - - let tmp; - if (typeof oldline !== 'undefined') { - if (typeof newline !== 'undefined') { - tmp = getInlineContainer(); - } else { - tmp = getInlineContainer('old'); - } - tmp.children('td:first').html($v); - } else { - tmp = getInlineContainer('new'); - tmp.children('td:last').html($v); - } - elements[key]['element'].closest('.not-diff').after(tmp); + i++; + setTimeout(render); + } else { + updateHighlighting(); } } + render(); +} - function renderDiffs() { +function showDiff(index, fromId, toId, path){ + let url = '@helpers.url(repository)/diff/'; + if (fromId == '') { + url = url + encodeURIComponent(toId); + } else { + url = url + encodeURIComponent(fromId) + '...' + encodeURIComponent(toId); + } + $.get(url, { path : path }, function(data) { + $('#oldText-' + index).attr('data-val', data.oldContent); + $('#newText-' + index).attr('data-val', data.newContent); const diffs = $('.diffText'); - let i = 0; - function render(){ - if (diffs[i]) { - const $table = renderOneDiff($(diffs[i]), window.viewType, $('.file-hash')[i].id); - @if(hasWritePermission) { - renderReplyComment($table); - } - i++; - setTimeout(render); - } else { - updateHighlighting(); - } + const $table = renderOneDiff($(diffs[index]), window.viewType, $('.file-hash')[index].id); + @if(hasWritePermission) { + renderReplyComment($table); } - render(); - } -}); + $('#show-diff-' + index).hide(); + }); +} function changeDisplaySetting(key, value){ let url = ''; diff --git a/src/main/twirl/gitbucket/core/pulls/conversation.scala.html b/src/main/twirl/gitbucket/core/pulls/conversation.scala.html index 223cb78..be00cb1 100644 --- a/src/main/twirl/gitbucket/core/pulls/conversation.scala.html +++ b/src/main/twirl/gitbucket/core/pulls/conversation.scala.html @@ -4,7 +4,7 @@ comments: Seq[gitbucket.core.model.Comment], changedFileSize: Int, issueLabels: List[gitbucket.core.model.Label], - issueAsignees: List[gitbucket.core.model.IssueAssignee], + issueAssignees: List[gitbucket.core.model.IssueAssignee], collaborators: List[String], milestones: List[(gitbucket.core.model.Milestone, Int, Int)], priorities: List[gitbucket.core.model.Priority], @@ -56,7 +56,7 @@ Some(issue), comments.toList, issueLabels, - issueAsignees, + issueAssignees, collaborators, milestones, priorities,