mirror of
https://github.com/go-gitea/gitea.git
synced 2025-11-10 15:32:55 +09:00
Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
34182c87ec | ||
|
|
c401788383 | ||
|
|
8335b556d1 | ||
|
|
09fff9e1c1 | ||
|
|
622552b709 | ||
|
|
1709297701 | ||
|
|
5fe8fee933 |
@@ -1,5 +1,14 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## [1.1.4](https://github.com/go-gitea/gitea/releases/tag/v1.1.4) - 2017-09-04
|
||||||
|
|
||||||
|
* BUGFIXES
|
||||||
|
* Fix rendering of external links (#2292) (#2315)
|
||||||
|
* Fix deleted milestone bug (#1942) (#2300)
|
||||||
|
* fix 500 error when view an issue which's milestone deleted (#2297) (#2299)
|
||||||
|
* Fix SHA1 hash linking (#2143) (#2293)
|
||||||
|
* back port from #1709 (#2291)
|
||||||
|
|
||||||
## [1.1.3](https://github.com/go-gitea/gitea/releases/tag/v1.1.3) - 2017-08-03
|
## [1.1.3](https://github.com/go-gitea/gitea/releases/tag/v1.1.3) - 2017-08-03
|
||||||
|
|
||||||
* BUGFIXES
|
* BUGFIXES
|
||||||
|
|||||||
@@ -146,7 +146,7 @@ func (issue *Issue) loadAttributes(e Engine) (err error) {
|
|||||||
|
|
||||||
if issue.Milestone == nil && issue.MilestoneID > 0 {
|
if issue.Milestone == nil && issue.MilestoneID > 0 {
|
||||||
issue.Milestone, err = getMilestoneByRepoID(e, issue.RepoID, issue.MilestoneID)
|
issue.Milestone, err = getMilestoneByRepoID(e, issue.RepoID, issue.MilestoneID)
|
||||||
if err != nil {
|
if err != nil && !IsErrMilestoneNotExist(err) {
|
||||||
return fmt.Errorf("getMilestoneByRepoID [repo_id: %d, milestone_id: %d]: %v", issue.RepoID, issue.MilestoneID, err)
|
return fmt.Errorf("getMilestoneByRepoID [repo_id: %d, milestone_id: %d]: %v", issue.RepoID, issue.MilestoneID, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -231,26 +231,20 @@ func (c *Comment) LoadMilestone() error {
|
|||||||
has, err := x.ID(c.OldMilestoneID).Get(&oldMilestone)
|
has, err := x.ID(c.OldMilestoneID).Get(&oldMilestone)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
} else if !has {
|
} else if has {
|
||||||
return ErrMilestoneNotExist{
|
|
||||||
ID: c.OldMilestoneID,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
c.OldMilestone = &oldMilestone
|
c.OldMilestone = &oldMilestone
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if c.MilestoneID > 0 {
|
if c.MilestoneID > 0 {
|
||||||
var milestone Milestone
|
var milestone Milestone
|
||||||
has, err := x.ID(c.MilestoneID).Get(&milestone)
|
has, err := x.ID(c.MilestoneID).Get(&milestone)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
} else if !has {
|
} else if has {
|
||||||
return ErrMilestoneNotExist{
|
|
||||||
ID: c.MilestoneID,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
c.Milestone = &milestone
|
c.Milestone = &milestone
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -53,6 +53,10 @@ func IsReadmeFile(name string) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
// NOTE: All below regex matching do not perform any extra validation.
|
||||||
|
// Thus a link is produced even if the user does not exist, the issue does not exist, the commit does not exist, etc.
|
||||||
|
// While fast, this is also incorrect and lead to false positives.
|
||||||
|
|
||||||
// MentionPattern matches string that mentions someone, e.g. @Unknwon
|
// MentionPattern matches string that mentions someone, e.g. @Unknwon
|
||||||
MentionPattern = regexp.MustCompile(`(\s|^|\W)@[0-9a-zA-Z-_\.]+`)
|
MentionPattern = regexp.MustCompile(`(\s|^|\W)@[0-9a-zA-Z-_\.]+`)
|
||||||
|
|
||||||
@@ -65,9 +69,9 @@ var (
|
|||||||
CrossReferenceIssueNumericPattern = regexp.MustCompile(`( |^)[0-9a-zA-Z]+/[0-9a-zA-Z]+#[0-9]+\b`)
|
CrossReferenceIssueNumericPattern = regexp.MustCompile(`( |^)[0-9a-zA-Z]+/[0-9a-zA-Z]+#[0-9]+\b`)
|
||||||
|
|
||||||
// Sha1CurrentPattern matches string that represents a commit SHA, e.g. d8a994ef243349f321568f9e36d5c3f444b99cae
|
// Sha1CurrentPattern matches string that represents a commit SHA, e.g. d8a994ef243349f321568f9e36d5c3f444b99cae
|
||||||
// FIXME: this pattern matches pure numbers as well, right now we do a hack to check in renderSha1CurrentPattern
|
// Although SHA1 hashes are 40 chars long, the regex matches the hash from 7 to 40 chars in length
|
||||||
// by converting string to a number.
|
// so that abbreviated hash links can be used as well. This matches git and github useability.
|
||||||
Sha1CurrentPattern = regexp.MustCompile(`(?:^|\s|\()[0-9a-f]{40}\b`)
|
Sha1CurrentPattern = regexp.MustCompile(`(?:^|\s|\()([0-9a-f]{7,40})\b`)
|
||||||
|
|
||||||
// ShortLinkPattern matches short but difficult to parse [[name|link|arg=test]] syntax
|
// ShortLinkPattern matches short but difficult to parse [[name|link|arg=test]] syntax
|
||||||
ShortLinkPattern = regexp.MustCompile(`(\[\[.*\]\]\w*)`)
|
ShortLinkPattern = regexp.MustCompile(`(\[\[.*\]\]\w*)`)
|
||||||
@@ -75,12 +79,29 @@ var (
|
|||||||
// AnySHA1Pattern allows to split url containing SHA into parts
|
// AnySHA1Pattern allows to split url containing SHA into parts
|
||||||
AnySHA1Pattern = regexp.MustCompile(`(http\S*)://(\S+)/(\S+)/(\S+)/(\S+)/([0-9a-f]{40})(?:/?([^#\s]+)?(?:#(\S+))?)?`)
|
AnySHA1Pattern = regexp.MustCompile(`(http\S*)://(\S+)/(\S+)/(\S+)/(\S+)/([0-9a-f]{40})(?:/?([^#\s]+)?(?:#(\S+))?)?`)
|
||||||
|
|
||||||
// IssueFullPattern allows to split issue (and pull) URLs into parts
|
|
||||||
IssueFullPattern = regexp.MustCompile(`(?:^|\s|\()(http\S*)://((?:[^\s/]+/)+)((?:\w{1,10}-)?[1-9][0-9]*)([\?|#]\S+.(\S+)?)?\b`)
|
|
||||||
|
|
||||||
validLinksPattern = regexp.MustCompile(`^[a-z][\w-]+://`)
|
validLinksPattern = regexp.MustCompile(`^[a-z][\w-]+://`)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// regexp for full links to issues/pulls
|
||||||
|
var issueFullPattern *regexp.Regexp
|
||||||
|
|
||||||
|
// InitMarkdown initialize regexps for markdown parsing
|
||||||
|
func InitMarkdown() {
|
||||||
|
getIssueFullPattern()
|
||||||
|
}
|
||||||
|
|
||||||
|
func getIssueFullPattern() *regexp.Regexp {
|
||||||
|
if issueFullPattern == nil {
|
||||||
|
appURL := setting.AppURL
|
||||||
|
if len(appURL) > 0 && appURL[len(appURL)-1] != '/' {
|
||||||
|
appURL += "/"
|
||||||
|
}
|
||||||
|
issueFullPattern = regexp.MustCompile(appURL +
|
||||||
|
`\w+/\w+/(?:issues|pulls)/((?:\w{1,10}-)?[1-9][0-9]*)([\?|#]\S+.(\S+)?)?\b`)
|
||||||
|
}
|
||||||
|
return issueFullPattern
|
||||||
|
}
|
||||||
|
|
||||||
// isLink reports whether link fits valid format.
|
// isLink reports whether link fits valid format.
|
||||||
func isLink(link []byte) bool {
|
func isLink(link []byte) bool {
|
||||||
return validLinksPattern.Match(link)
|
return validLinksPattern.Match(link)
|
||||||
@@ -155,12 +176,12 @@ func (r *Renderer) ListItem(out *bytes.Buffer, text []byte, flags int) {
|
|||||||
}
|
}
|
||||||
switch {
|
switch {
|
||||||
case bytes.HasPrefix(text, []byte(prefix+"[ ] ")):
|
case bytes.HasPrefix(text, []byte(prefix+"[ ] ")):
|
||||||
text = append([]byte(`<div class="ui fitted disabled checkbox"><input type="checkbox" disabled="disabled" /><label /></div>`), text[3+len(prefix):]...)
|
text = append([]byte(`<span class="ui fitted disabled checkbox"><input type="checkbox" disabled="disabled" /><label /></span>`), text[3+len(prefix):]...)
|
||||||
if prefix != "" {
|
if prefix != "" {
|
||||||
text = bytes.Replace(text, []byte(prefix), []byte{}, 1)
|
text = bytes.Replace(text, []byte(prefix), []byte{}, 1)
|
||||||
}
|
}
|
||||||
case bytes.HasPrefix(text, []byte(prefix+"[x] ")):
|
case bytes.HasPrefix(text, []byte(prefix+"[x] ")):
|
||||||
text = append([]byte(`<div class="ui checked fitted disabled checkbox"><input type="checkbox" checked="" disabled="disabled" /><label /></div>`), text[3+len(prefix):]...)
|
text = append([]byte(`<span class="ui checked fitted disabled checkbox"><input type="checkbox" checked="" disabled="disabled" /><label /></span>`), text[3+len(prefix):]...)
|
||||||
if prefix != "" {
|
if prefix != "" {
|
||||||
text = bytes.Replace(text, []byte(prefix), []byte{}, 1)
|
text = bytes.Replace(text, []byte(prefix), []byte{}, 1)
|
||||||
}
|
}
|
||||||
@@ -348,32 +369,17 @@ func renderFullSha1Pattern(rawBytes []byte, urlPrefix string) []byte {
|
|||||||
return rawBytes
|
return rawBytes
|
||||||
}
|
}
|
||||||
|
|
||||||
// renderFullIssuePattern renders issues-like URLs
|
// RenderFullIssuePattern renders issues-like URLs
|
||||||
func renderFullIssuePattern(rawBytes []byte, urlPrefix string) []byte {
|
func RenderFullIssuePattern(rawBytes []byte) []byte {
|
||||||
ms := IssueFullPattern.FindAllSubmatch(rawBytes, -1)
|
ms := getIssueFullPattern().FindAllSubmatch(rawBytes, -1)
|
||||||
for _, m := range ms {
|
for _, m := range ms {
|
||||||
all := m[0]
|
all := m[0]
|
||||||
protocol := string(m[1])
|
id := string(m[1])
|
||||||
paths := bytes.Split(m[2], []byte("/"))
|
|
||||||
paths = paths[:len(paths)-1]
|
|
||||||
if bytes.HasPrefix(paths[0], []byte("gist.")) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
path := protocol + "://" + string(m[2])
|
|
||||||
id := string(m[3])
|
|
||||||
path = URLJoin(path, id)
|
|
||||||
var comment []byte
|
|
||||||
if len(m) > 3 {
|
|
||||||
comment = m[4]
|
|
||||||
}
|
|
||||||
urlSuffix := ""
|
|
||||||
text := "#" + id
|
text := "#" + id
|
||||||
if comment != nil {
|
// TODO if m[2] is not nil, then link is to a comment,
|
||||||
urlSuffix += string(comment)
|
// and we should indicate that in the text somehow
|
||||||
text += " <i class='comment icon'></i>"
|
|
||||||
}
|
|
||||||
rawBytes = bytes.Replace(rawBytes, all, []byte(fmt.Sprintf(
|
rawBytes = bytes.Replace(rawBytes, all, []byte(fmt.Sprintf(
|
||||||
`<a href="%s%s">%s</a>`, path, urlSuffix, text)), -1)
|
`<a href="%s">%s</a>`, string(all), text)), -1)
|
||||||
}
|
}
|
||||||
return rawBytes
|
return rawBytes
|
||||||
}
|
}
|
||||||
@@ -553,12 +559,15 @@ func RenderCrossReferenceIssueIndexPattern(rawBytes []byte, urlPrefix string, me
|
|||||||
func renderSha1CurrentPattern(rawBytes []byte, urlPrefix string) []byte {
|
func renderSha1CurrentPattern(rawBytes []byte, urlPrefix string) []byte {
|
||||||
ms := Sha1CurrentPattern.FindAllSubmatch(rawBytes, -1)
|
ms := Sha1CurrentPattern.FindAllSubmatch(rawBytes, -1)
|
||||||
for _, m := range ms {
|
for _, m := range ms {
|
||||||
all := m[0]
|
hash := m[1]
|
||||||
if com.StrTo(all).MustInt() > 0 {
|
// The regex does not lie, it matches the hash pattern.
|
||||||
continue
|
// However, a regex cannot know if a hash actually exists or not.
|
||||||
}
|
// We could assume that a SHA1 hash should probably contain alphas AND numerics
|
||||||
rawBytes = bytes.Replace(rawBytes, all, []byte(fmt.Sprintf(
|
// but that is not always the case.
|
||||||
`<a href="%s">%s</a>`, URLJoin(urlPrefix, "commit", string(all)), base.ShortSha(string(all)))), -1)
|
// Although unlikely, deadbeef and 1234567 are valid short forms of SHA1 hash
|
||||||
|
// as used by git and github for linking and thus we have to do similar.
|
||||||
|
rawBytes = bytes.Replace(rawBytes, hash, []byte(fmt.Sprintf(
|
||||||
|
`<a href="%s">%s</a>`, URLJoin(urlPrefix, "commit", string(hash)), base.ShortSha(string(hash)))), -1)
|
||||||
}
|
}
|
||||||
return rawBytes
|
return rawBytes
|
||||||
}
|
}
|
||||||
@@ -572,12 +581,12 @@ func RenderSpecialLink(rawBytes []byte, urlPrefix string, metas map[string]strin
|
|||||||
[]byte(fmt.Sprintf(`<a href="%s">%s</a>`, URLJoin(setting.AppURL, string(m[1:])), m)), -1)
|
[]byte(fmt.Sprintf(`<a href="%s">%s</a>`, URLJoin(setting.AppURL, string(m[1:])), m)), -1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rawBytes = RenderFullIssuePattern(rawBytes)
|
||||||
rawBytes = RenderShortLinks(rawBytes, urlPrefix, false, isWikiMarkdown)
|
rawBytes = RenderShortLinks(rawBytes, urlPrefix, false, isWikiMarkdown)
|
||||||
rawBytes = RenderIssueIndexPattern(rawBytes, urlPrefix, metas)
|
rawBytes = RenderIssueIndexPattern(rawBytes, urlPrefix, metas)
|
||||||
rawBytes = RenderCrossReferenceIssueIndexPattern(rawBytes, urlPrefix, metas)
|
rawBytes = RenderCrossReferenceIssueIndexPattern(rawBytes, urlPrefix, metas)
|
||||||
rawBytes = renderFullSha1Pattern(rawBytes, urlPrefix)
|
rawBytes = renderFullSha1Pattern(rawBytes, urlPrefix)
|
||||||
rawBytes = renderSha1CurrentPattern(rawBytes, urlPrefix)
|
rawBytes = renderSha1CurrentPattern(rawBytes, urlPrefix)
|
||||||
rawBytes = renderFullIssuePattern(rawBytes, urlPrefix)
|
|
||||||
return rawBytes
|
return rawBytes
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -180,13 +180,15 @@ func TestRender_AutoLink(t *testing.T) {
|
|||||||
numericIssueLink(URLJoin(setting.AppSubURL, "issues"), 3333))
|
numericIssueLink(URLJoin(setting.AppSubURL, "issues"), 3333))
|
||||||
|
|
||||||
// render external issue URLs
|
// render external issue URLs
|
||||||
tmp := "http://1111/2222/ssss-issues/3333?param=blah&blahh=333"
|
for _, externalURL := range []string{
|
||||||
test(tmp, "<a href=\""+tmp+"\">#3333 <i class='comment icon'></i></a>")
|
"http://1111/2222/ssss-issues/3333?param=blah&blahh=333",
|
||||||
test("http://test.com/issues/33333", numericIssueLink("http://test.com/issues", 33333))
|
"http://test.com/issues/33333",
|
||||||
test("https://issues/333", numericIssueLink("https://issues", 333))
|
"https://issues/333"} {
|
||||||
|
test(externalURL, externalURL)
|
||||||
|
}
|
||||||
|
|
||||||
// render valid commit URLs
|
// render valid commit URLs
|
||||||
tmp = URLJoin(AppSubURL, "commit", "d8a994ef243349f321568f9e36d5c3f444b99cae")
|
tmp := URLJoin(AppSubURL, "commit", "d8a994ef243349f321568f9e36d5c3f444b99cae")
|
||||||
test(tmp, "<a href=\""+tmp+"\">d8a994ef24</a>")
|
test(tmp, "<a href=\""+tmp+"\">d8a994ef24</a>")
|
||||||
tmp += "#diff-2"
|
tmp += "#diff-2"
|
||||||
test(tmp, "<a href=\""+tmp+"\">d8a994ef24 (diff-2)</a>")
|
test(tmp, "<a href=\""+tmp+"\">d8a994ef24 (diff-2)</a>")
|
||||||
@@ -290,6 +292,8 @@ func TestRender_Commits(t *testing.T) {
|
|||||||
var src = strings.Replace(subtree, "/commit/", "/src/", -1)
|
var src = strings.Replace(subtree, "/commit/", "/src/", -1)
|
||||||
|
|
||||||
test(sha, `<p><a href="`+commit+`" rel="nofollow">b6dd6210ea</a></p>`)
|
test(sha, `<p><a href="`+commit+`" rel="nofollow">b6dd6210ea</a></p>`)
|
||||||
|
test(sha[:7], `<p><a href="`+commit[:len(commit)-(40-7)]+`" rel="nofollow">b6dd621</a></p>`)
|
||||||
|
test(sha[:39], `<p><a href="`+commit[:len(commit)-(40-39)]+`" rel="nofollow">b6dd6210ea</a></p>`)
|
||||||
test(commit, `<p><a href="`+commit+`" rel="nofollow">b6dd6210ea</a></p>`)
|
test(commit, `<p><a href="`+commit+`" rel="nofollow">b6dd6210ea</a></p>`)
|
||||||
test(tree, `<p><a href="`+src+`" rel="nofollow">b6dd6210ea/src</a></p>`)
|
test(tree, `<p><a href="`+src+`" rel="nofollow">b6dd6210ea/src</a></p>`)
|
||||||
}
|
}
|
||||||
@@ -330,6 +334,22 @@ func TestRender_CrossReferences(t *testing.T) {
|
|||||||
`<p><a href="`+URLJoin(AppURL, "gogits", "gogs", "issues", "12345")+`" rel="nofollow">gogits/gogs#12345</a></p>`)
|
`<p><a href="`+URLJoin(AppURL, "gogits", "gogs", "issues", "12345")+`" rel="nofollow">gogits/gogs#12345</a></p>`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestRender_FullIssueURLs(t *testing.T) {
|
||||||
|
setting.AppURL = AppURL
|
||||||
|
setting.AppSubURL = AppSubURL
|
||||||
|
|
||||||
|
test := func(input, expected string) {
|
||||||
|
result := RenderFullIssuePattern([]byte(input))
|
||||||
|
assert.Equal(t, expected, string(result))
|
||||||
|
}
|
||||||
|
test("Here is a link https://git.osgeo.org/gogs/postgis/postgis/pulls/6",
|
||||||
|
"Here is a link https://git.osgeo.org/gogs/postgis/postgis/pulls/6")
|
||||||
|
test("Look here http://localhost:3000/person/repo/issues/4",
|
||||||
|
`Look here <a href="http://localhost:3000/person/repo/issues/4">#4</a>`)
|
||||||
|
test("http://localhost:3000/person/repo/issues/4#issuecomment-1234",
|
||||||
|
`<a href="http://localhost:3000/person/repo/issues/4#issuecomment-1234">#4</a>`)
|
||||||
|
}
|
||||||
|
|
||||||
func TestRegExp_MentionPattern(t *testing.T) {
|
func TestRegExp_MentionPattern(t *testing.T) {
|
||||||
trueTestCases := []string{
|
trueTestCases := []string{
|
||||||
"@Unknwon",
|
"@Unknwon",
|
||||||
@@ -520,50 +540,6 @@ func TestRegExp_AnySHA1Pattern(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRegExp_IssueFullPattern(t *testing.T) {
|
|
||||||
testCases := map[string][]string{
|
|
||||||
"https://github.com/gogits/gogs/pull/3244": {
|
|
||||||
"https",
|
|
||||||
"github.com/gogits/gogs/pull/",
|
|
||||||
"3244",
|
|
||||||
"",
|
|
||||||
"",
|
|
||||||
},
|
|
||||||
"https://github.com/gogits/gogs/issues/3247#issuecomment-231517079": {
|
|
||||||
"https",
|
|
||||||
"github.com/gogits/gogs/issues/",
|
|
||||||
"3247",
|
|
||||||
"#issuecomment-231517079",
|
|
||||||
"",
|
|
||||||
},
|
|
||||||
"https://try.gogs.io/gogs/gogs/issues/4#issue-685": {
|
|
||||||
"https",
|
|
||||||
"try.gogs.io/gogs/gogs/issues/",
|
|
||||||
"4",
|
|
||||||
"#issue-685",
|
|
||||||
"",
|
|
||||||
},
|
|
||||||
"https://youtrack.jetbrains.com/issue/JT-36485": {
|
|
||||||
"https",
|
|
||||||
"youtrack.jetbrains.com/issue/",
|
|
||||||
"JT-36485",
|
|
||||||
"",
|
|
||||||
"",
|
|
||||||
},
|
|
||||||
"https://youtrack.jetbrains.com/issue/JT-36485#comment=27-1508676": {
|
|
||||||
"https",
|
|
||||||
"youtrack.jetbrains.com/issue/",
|
|
||||||
"JT-36485",
|
|
||||||
"#comment=27-1508676",
|
|
||||||
"",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for k, v := range testCases {
|
|
||||||
assert.Equal(t, IssueFullPattern.FindStringSubmatch(k)[1:], v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestMisc_IsMarkdownFile(t *testing.T) {
|
func TestMisc_IsMarkdownFile(t *testing.T) {
|
||||||
setting.Markdown.FileExtensions = []string{".md", ".markdown", ".mdown", ".mkd"}
|
setting.Markdown.FileExtensions = []string{".md", ".markdown", ".mdown", ".mkd"}
|
||||||
trueTestCases := []string{
|
trueTestCases := []string{
|
||||||
@@ -632,7 +608,7 @@ var sameCases = []string{
|
|||||||
|
|
||||||
Ideas and codes
|
Ideas and codes
|
||||||
|
|
||||||
- Bezier widget (by @r-lyeh) https://github.com/ocornut/imgui/issues/786
|
- Bezier widget (by @r-lyeh) ` + AppURL + `ocornut/imgui/issues/786
|
||||||
- Node graph editors https://github.com/ocornut/imgui/issues/306
|
- Node graph editors https://github.com/ocornut/imgui/issues/306
|
||||||
- [[Memory Editor|memory_editor_example]]
|
- [[Memory Editor|memory_editor_example]]
|
||||||
- [[Plot var helper|plot_var_example]]`,
|
- [[Plot var helper|plot_var_example]]`,
|
||||||
@@ -668,8 +644,8 @@ func testAnswers(baseURLContent, baseURLImages string) []string {
|
|||||||
<p>Ideas and codes</p>
|
<p>Ideas and codes</p>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li>Bezier widget (by <a href="` + AppURL + `r-lyeh" rel="nofollow">@r-lyeh</a>)<a href="https://github.com/ocornut/imgui/issues/786" rel="nofollow">#786</a></li>
|
<li>Bezier widget (by <a href="` + AppURL + `r-lyeh" rel="nofollow">@r-lyeh</a>) <a href="http://localhost:3000/ocornut/imgui/issues/786" rel="nofollow">#786</a></li>
|
||||||
<li>Node graph editors<a href="https://github.com/ocornut/imgui/issues/306" rel="nofollow">#306</a></li>
|
<li>Node graph editors https://github.com/ocornut/imgui/issues/306</li>
|
||||||
<li><a href="` + baseURLContent + `memory_editor_example" rel="nofollow">Memory Editor</a></li>
|
<li><a href="` + baseURLContent + `memory_editor_example" rel="nofollow">Memory Editor</a></li>
|
||||||
<li><a href="` + baseURLContent + `plot_var_example" rel="nofollow">Plot var helper</a></li>
|
<li><a href="` + baseURLContent + `plot_var_example" rel="nofollow">Plot var helper</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|||||||
@@ -558,6 +558,7 @@ issues.remove_label_at = `removed the <div class="ui label" style="color: %s; ba
|
|||||||
issues.add_milestone_at = `added this to the <b>%s</b> milestone %s`
|
issues.add_milestone_at = `added this to the <b>%s</b> milestone %s`
|
||||||
issues.change_milestone_at = `modified the milestone from <b>%s</b> to <b>%s</b> %s`
|
issues.change_milestone_at = `modified the milestone from <b>%s</b> to <b>%s</b> %s`
|
||||||
issues.remove_milestone_at = `removed this from the <b>%s</b> milestone %s`
|
issues.remove_milestone_at = `removed this from the <b>%s</b> milestone %s`
|
||||||
|
issues.deleted_milestone = `(deleted)`
|
||||||
issues.self_assign_at = `self-assigned this %s`
|
issues.self_assign_at = `self-assigned this %s`
|
||||||
issues.add_assignee_at = `was assigned by <b>%s</b> %s`
|
issues.add_assignee_at = `was assigned by <b>%s</b> %s`
|
||||||
issues.remove_assignee_at = `removed their assignment %s`
|
issues.remove_assignee_at = `removed their assignment %s`
|
||||||
|
|||||||
@@ -5,11 +5,13 @@ jQuery.fn.autolink = function() {
|
|||||||
.each(function() {
|
.each(function() {
|
||||||
$(this).each(function() {
|
$(this).each(function() {
|
||||||
if (re.test($(this).text()))
|
if (re.test($(this).text()))
|
||||||
|
if($(this).parents().filter('code').length === 0) {
|
||||||
$(this).replaceWith(
|
$(this).replaceWith(
|
||||||
$("<span />").html(
|
$("<span />").html(
|
||||||
this.nodeValue.replace(re, "<a href='$1'>$1</a>")
|
this.nodeValue.replace(re, "<a href='$1'>$1</a>")
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
};
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -75,7 +75,7 @@ func TestAPI_RenderGFM(t *testing.T) {
|
|||||||
<ul>
|
<ul>
|
||||||
<li><a href="` + AppSubURL + `wiki/Links" rel="nofollow">Links, Language bindings, Engine bindings</a></li>
|
<li><a href="` + AppSubURL + `wiki/Links" rel="nofollow">Links, Language bindings, Engine bindings</a></li>
|
||||||
<li><a href="` + AppSubURL + `wiki/Tips" rel="nofollow">Tips</a></li>
|
<li><a href="` + AppSubURL + `wiki/Tips" rel="nofollow">Tips</a></li>
|
||||||
<li>Bezier widget (by <a href="` + AppURL + `r-lyeh" rel="nofollow">@r-lyeh</a>)<a href="https://github.com/ocornut/imgui/issues/786" rel="nofollow">#786</a></li>
|
<li>Bezier widget (by <a href="` + AppURL + `r-lyeh" rel="nofollow">@r-lyeh</a>) https://github.com/ocornut/imgui/issues/786</li>
|
||||||
</ul>
|
</ul>
|
||||||
`,
|
`,
|
||||||
// wine-staging wiki home extract: special wiki syntax, images
|
// wine-staging wiki home extract: special wiki syntax, images
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ func GlobalInit() {
|
|||||||
|
|
||||||
if setting.InstallLock {
|
if setting.InstallLock {
|
||||||
highlight.NewContext()
|
highlight.NewContext()
|
||||||
|
markdown.InitMarkdown()
|
||||||
markdown.NewSanitizer()
|
markdown.NewSanitizer()
|
||||||
if err := models.NewEngine(); err != nil {
|
if err := models.NewEngine(); err != nil {
|
||||||
log.Fatal(4, "Failed to initialize ORM engine: %v", err)
|
log.Fatal(4, "Failed to initialize ORM engine: %v", err)
|
||||||
|
|||||||
@@ -596,6 +596,16 @@ func ViewIssue(ctx *context.Context) {
|
|||||||
ctx.Handle(500, "LoadMilestone", err)
|
ctx.Handle(500, "LoadMilestone", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
ghostMilestone := &models.Milestone{
|
||||||
|
ID: -1,
|
||||||
|
Name: ctx.Tr("repo.issues.deleted_milestone"),
|
||||||
|
}
|
||||||
|
if comment.OldMilestoneID > 0 && comment.OldMilestone == nil {
|
||||||
|
comment.OldMilestone = ghostMilestone
|
||||||
|
}
|
||||||
|
if comment.MilestoneID > 0 && comment.Milestone == nil {
|
||||||
|
comment.Milestone = ghostMilestone
|
||||||
|
}
|
||||||
} else if comment.Type == models.CommentTypeAssignees {
|
} else if comment.Type == models.CommentTypeAssignees {
|
||||||
if err = comment.LoadAssignees(); err != nil {
|
if err = comment.LoadAssignees(); err != nil {
|
||||||
ctx.Handle(500, "LoadAssignees", err)
|
ctx.Handle(500, "LoadAssignees", err)
|
||||||
|
|||||||
Reference in New Issue
Block a user