diff --git a/src/main/scala/app/IssuesController.scala b/src/main/scala/app/IssuesController.scala
index b6b7bb9..d2bb683 100644
--- a/src/main/scala/app/IssuesController.scala
+++ b/src/main/scala/app/IssuesController.scala
@@ -195,7 +195,7 @@
org.json4s.jackson.Serialization.write(
Map("title" -> x.title,
"content" -> view.Markdown.toHtml(x.content getOrElse "No description given.",
- repository, false, true)
+ repository, false, true, true, isEditable(x.userName, x.repositoryName, x.openedUserName))
))
}
} else Unauthorized
@@ -212,7 +212,7 @@
contentType = formats("json")
org.json4s.jackson.Serialization.write(
Map("content" -> view.Markdown.toHtml(x.content,
- repository, false, true)
+ repository, false, true, true, isEditable(x.userName, x.repositoryName, x.commentedUserName))
))
}
} else Unauthorized
diff --git a/src/main/scala/app/RepositoryViewerController.scala b/src/main/scala/app/RepositoryViewerController.scala
index 4291730..18a9f3f 100644
--- a/src/main/scala/app/RepositoryViewerController.scala
+++ b/src/main/scala/app/RepositoryViewerController.scala
@@ -77,7 +77,9 @@
contentType = "text/html"
view.helpers.markdown(params("content"), repository,
params("enableWikiLink").toBoolean,
- params("enableRefsLink").toBoolean)
+ params("enableRefsLink").toBoolean,
+ params("enableTaskList").toBoolean,
+ hasWritePermission(repository.owner, repository.name, context.loginAccount))
})
/**
diff --git a/src/main/scala/view/Markdown.scala b/src/main/scala/view/Markdown.scala
index 0512024..08c3dd4 100644
--- a/src/main/scala/view/Markdown.scala
+++ b/src/main/scala/view/Markdown.scala
@@ -9,6 +9,7 @@
import org.pegdown.LinkRenderer.Rendering
import java.text.Normalizer
import java.util.Locale
+import java.util.regex.Pattern
import scala.collection.JavaConverters._
import service.{RequestCache, WikiService}
@@ -18,17 +19,23 @@
* Converts Markdown of Wiki pages to HTML.
*/
def toHtml(markdown: String, repository: service.RepositoryService.RepositoryInfo,
- enableWikiLink: Boolean, enableRefsLink: Boolean)(implicit context: app.Context): String = {
+ enableWikiLink: Boolean, enableRefsLink: Boolean,
+ enableTaskList: Boolean = false, hasWritePermission: Boolean = false)(implicit context: app.Context): String = {
// escape issue id
- val source = if(enableRefsLink){
+ val s = if(enableRefsLink){
markdown.replaceAll("(?<=(\\W|^))#(\\d+)(?=(\\W|$))", "issue:$2")
} else markdown
+ // escape task list
+ val source = if(enableTaskList){
+ GitBucketHtmlSerializer.escapeTaskList(s)
+ } else s
+
val rootNode = new PegDownProcessor(
Extensions.AUTOLINKS | Extensions.WIKILINKS | Extensions.FENCED_CODE_BLOCKS | Extensions.TABLES | Extensions.HARDWRAPS
).parseMarkdown(source.toCharArray)
- new GitBucketHtmlSerializer(markdown, repository, enableWikiLink, enableRefsLink).toHtml(rootNode)
+ new GitBucketHtmlSerializer(markdown, repository, enableWikiLink, enableRefsLink, enableTaskList, hasWritePermission).toHtml(rootNode)
}
}
@@ -82,7 +89,9 @@
markdown: String,
repository: service.RepositoryService.RepositoryInfo,
enableWikiLink: Boolean,
- enableRefsLink: Boolean
+ enableRefsLink: Boolean,
+ enableTaskList: Boolean,
+ hasWritePermission: Boolean
)(implicit val context: app.Context) extends ToHtmlSerializer(
new GitBucketLinkRender(context, repository, enableWikiLink),
Map[String, VerbatimSerializer](VerbatimSerializer.DEFAULT -> new GitBucketVerbatimSerializer).asJava
@@ -143,7 +152,10 @@
override def visit(node: TextNode): Unit = {
// convert commit id and username to link.
- val text = if(enableRefsLink) convertRefsLinks(node.getText, repository, "issue:") else node.getText
+ val t = if(enableRefsLink) convertRefsLinks(node.getText, repository, "issue:") else node.getText
+
+ // convert task list to checkbox.
+ val text = if(enableTaskList) GitBucketHtmlSerializer.convertCheckBox(t, hasWritePermission) else t
if (abbreviations.isEmpty) {
printer.print(text)
@@ -151,6 +163,28 @@
printWithAbbreviations(text)
}
}
+
+ override def visit(node: BulletListNode): Unit = {
+ if (printChildrenToString(node).contains("""class="task-list-item-checkbox" """)) {
+ printer.println().print("""
""").indent(+2)
+ visitChildren(node)
+ printer.indent(-2).println().print("
")
+ } else {
+ printIndentedTag(node, "ul")
+ }
+ }
+
+ override def visit(node: ListItemNode): Unit = {
+ if (printChildrenToString(node).contains("""class="task-list-item-checkbox" """)) {
+ printer.println()
+ printer.print("""""")
+ visitChildren(node)
+ printer.print("")
+ } else {
+ printer.println()
+ printTag(node, "li")
+ }
+ }
}
object GitBucketHtmlSerializer {
@@ -163,4 +197,14 @@
val noSpecialChars = StringUtil.urlEncode(normalized)
noSpecialChars.toLowerCase(Locale.ENGLISH)
}
+
+ def escapeTaskList(text: String): String = {
+ Pattern.compile("""^( *)- \[([x| ])\] """, Pattern.MULTILINE).matcher(text).replaceAll("$1* task:$2: ")
+ }
+
+ def convertCheckBox(text: String, hasWritePermission: Boolean): String = {
+ val disabled = if (hasWritePermission) "" else "disabled"
+ text.replaceAll("task:x:", """")
+ .replaceAll("task: :", """")
+ }
}
diff --git a/src/main/scala/view/helpers.scala b/src/main/scala/view/helpers.scala
index 78f658f..7c11f1b 100644
--- a/src/main/scala/view/helpers.scala
+++ b/src/main/scala/view/helpers.scala
@@ -48,8 +48,8 @@
* Converts Markdown of Wiki pages to HTML.
*/
def markdown(value: String, repository: service.RepositoryService.RepositoryInfo,
- enableWikiLink: Boolean, enableRefsLink: Boolean)(implicit context: app.Context): Html =
- Html(Markdown.toHtml(value, repository, enableWikiLink, enableRefsLink))
+ enableWikiLink: Boolean, enableRefsLink: Boolean, enableTaskList: Boolean = false, hasWritePermission: Boolean = false)(implicit context: app.Context): Html =
+ Html(Markdown.toHtml(value, repository, enableWikiLink, enableRefsLink, enableTaskList, hasWritePermission))
def renderMarkup(filePath: List[String], fileContent: String, branch: String,
repository: service.RepositoryService.RepositoryInfo,
diff --git a/src/main/twirl/helper/preview.scala.html b/src/main/twirl/helper/preview.scala.html
index b6f37c7..3c0e13e 100644
--- a/src/main/twirl/helper/preview.scala.html
+++ b/src/main/twirl/helper/preview.scala.html
@@ -1,4 +1,4 @@
-@(repository: service.RepositoryService.RepositoryInfo, content: String, enableWikiLink: Boolean, enableRefsLink: Boolean,
+@(repository: service.RepositoryService.RepositoryInfo, content: String, enableWikiLink: Boolean, enableRefsLink: Boolean, enableTaskList: Boolean, hasWritePermission: Boolean,
style: String = "", placeholder: String = "Leave a comment", elastic: Boolean = false)(implicit context: app.Context)
@import context._
@import view.helpers._
@@ -38,7 +38,8 @@
$.post('@url(repository)/_preview', {
content : $('#content').val(),
enableWikiLink : @enableWikiLink,
- enableRefsLink : @enableRefsLink
+ enableRefsLink : @enableRefsLink,
+ enableTaskList : @enableTaskList
}, function(data){
$('#preview-area').html(data);
prettyPrint();
diff --git a/src/main/twirl/issues/commentform.scala.html b/src/main/twirl/issues/commentform.scala.html
index 4ca951e..04169c7 100644
--- a/src/main/twirl/issues/commentform.scala.html
+++ b/src/main/twirl/issues/commentform.scala.html
@@ -10,7 +10,7 @@
@avatar(loginAccount.get.userName, 48)
@@ -28,4 +28,4 @@
$('').attr('name', 'action').val($(this).val().toLowerCase()).appendTo('form');
});
});
-
\ No newline at end of file
+
diff --git a/src/main/twirl/issues/commentlist.scala.html b/src/main/twirl/issues/commentlist.scala.html
index 979062f..ff3ff7e 100644
--- a/src/main/twirl/issues/commentlist.scala.html
+++ b/src/main/twirl/issues/commentlist.scala.html
@@ -16,7 +16,7 @@
- @markdown(issue.content getOrElse "No description provided.", repository, false, true)
+ @markdown(issue.content getOrElse "No description provided.", repository, false, true, true, hasWritePermission)
@@ -46,7 +46,7 @@
@if(comment.action == "commit" && comment.content.split(" ").last.matches("[a-f0-9]{40}")){
@defining(comment.content.substring(comment.content.length - 40)){ id =>
- @markdown(comment.content.substring(0, comment.content.length - 41), repository, false, true)
+ @markdown(comment.content.substring(0, comment.content.length - 41), repository, false, true, true, hasWritePermission)
}
} else {
@if(comment.action == "refer"){
@@ -54,7 +54,7 @@
Issue #@issueId: @rest.mkString(":")
}
} else {
- @markdown(comment.content, repository, false, true)
+ @markdown(comment.content, repository, false, true, true, hasWritePermission)
}
}
@@ -134,5 +134,67 @@
}
return false;
});
+
+ var extractMarkdown = function(data){
+ $('body').append('');
+ $('#tmp').html(data);
+ var markdown = $('#tmp textarea').val();
+ $('#tmp').remove();
+ return markdown;
+ };
+
+ var replaceTaskList = function(issueContentHtml, checkboxes) {
+ var ss = [],
+ markdown = extractMarkdown(issueContentHtml),
+ xs = markdown.split(/- \[[x| ]\]/g);
+ for (var i=0; i
\ No newline at end of file
+
diff --git a/src/main/twirl/issues/create.scala.html b/src/main/twirl/issues/create.scala.html
index cf91159..7080667 100644
--- a/src/main/twirl/issues/create.scala.html
+++ b/src/main/twirl/issues/create.scala.html
@@ -57,7 +57,7 @@
- @helper.html.preview(repository, "", false, true, "width: 565px; height: 200px; max-height: 250px;", elastic = true)
+ @helper.html.preview(repository, "", false, true, true, hasWritePermission, "width: 565px; height: 200px; max-height: 250px;", elastic = true)
diff --git a/src/main/twirl/pulls/compare.scala.html b/src/main/twirl/pulls/compare.scala.html
index b99e5b2..7d900ab 100644
--- a/src/main/twirl/pulls/compare.scala.html
+++ b/src/main/twirl/pulls/compare.scala.html
@@ -58,7 +58,7 @@
- @helper.html.preview(repository, "", false, true, "width: 580px; height: 200px;")
+ @helper.html.preview(repository, "", false, true, true, hasWritePermission, "width: 580px; height: 200px;")
diff --git a/src/main/twirl/wiki/edit.scala.html b/src/main/twirl/wiki/edit.scala.html
index b7ca333..36a61dc 100644
--- a/src/main/twirl/wiki/edit.scala.html
+++ b/src/main/twirl/wiki/edit.scala.html
@@ -22,7 +22,7 @@