Skip to content

Commit 79a19b0

Browse files
committed
bugfix:1. 修复文档为空附件不能下载;2. 修复文档设置为非markdown编辑附件不能下载;3. 兼容现存问题文档;4. 非markdown编辑文档,阅读时增加文档修改信息。 resolves mindoc-org#850
1 parent 62bf578 commit 79a19b0

File tree

3 files changed

+103
-97
lines changed

3 files changed

+103
-97
lines changed

models/DocumentModel.go

+100-94
Original file line numberDiff line numberDiff line change
@@ -267,127 +267,133 @@ func (item *Document) ReleaseContent() error {
267267
return nil
268268
}
269269

270-
//处理文档的外链,附件,底部编辑信息等.
270+
// Processor 调用位置两处:
271+
// 1. 项目发布和文档发布: 处理文档的外链,附件,底部编辑信息等;
272+
// 2. 文档阅读:可以修复存在问题的文档,使其能正常显示附件下载和文档作者信息等。
271273
func (item *Document) Processor() *Document {
272274
if item.Release != "" {
273275
item.Release = utils.SafetyProcessor(item.Release)
276+
} else {
277+
// Release内容为空,直接赋值文档标签,保证附件下载正常
278+
item.Release = "<div class=\"whole-article-wrap\"></div>"
279+
}
274280

275-
//安全过滤,移除危险标签和属性
276-
if docQuery, err := goquery.NewDocumentFromReader(bytes.NewBufferString(item.Release)); err == nil {
281+
// Next: 生成文档的一些附加信息
282+
if docQuery, err := goquery.NewDocumentFromReader(bytes.NewBufferString(item.Release)); err == nil {
277283

284+
//处理附件
285+
if selector := docQuery.Find("div.attach-list").First(); selector.Size() <= 0 {
278286
//处理附件
279-
if selector := docQuery.Find("div.attach-list").First(); selector.Size() <= 0 {
280-
//处理附件
281-
attachList, err := NewAttachment().FindListByDocumentId(item.DocumentId)
282-
if err == nil && len(attachList) > 0 {
283-
content := bytes.NewBufferString("<div class=\"attach-list\"><strong>" + i18n.Tr(item.Lang, "doc.attachment") + "</strong><ul>")
284-
for _, attach := range attachList {
285-
if strings.HasPrefix(attach.HttpPath, "/") {
286-
attach.HttpPath = strings.TrimSuffix(conf.BaseUrl, "/") + attach.HttpPath
287-
}
288-
li := fmt.Sprintf("<li><a href=\"%s\" target=\"_blank\" title=\"%s\">%s</a></li>", attach.HttpPath, attach.FileName, attach.FileName)
289-
290-
content.WriteString(li)
287+
attachList, err := NewAttachment().FindListByDocumentId(item.DocumentId)
288+
if err == nil && len(attachList) > 0 {
289+
content := bytes.NewBufferString("<div class=\"attach-list\"><strong>" + i18n.Tr(item.Lang, "doc.attachment") + "</strong><ul>")
290+
for _, attach := range attachList {
291+
if strings.HasPrefix(attach.HttpPath, "/") {
292+
attach.HttpPath = strings.TrimSuffix(conf.BaseUrl, "/") + attach.HttpPath
291293
}
292-
content.WriteString("</ul></div>")
293-
if docQuery == nil {
294-
docQuery, err = goquery.NewDocumentFromReader(content)
295-
} else {
296-
if selector := docQuery.Find("div.wiki-bottom").First(); selector.Size() > 0 {
297-
selector.BeforeHtml(content.String())
298-
} else if selector := docQuery.Find("div.markdown-article").First(); selector.Size() > 0 {
299-
selector.AppendHtml(content.String())
300-
} else if selector := docQuery.Find("article.markdown-article-inner").First(); selector.Size() > 0 {
301-
selector.AppendHtml(content.String())
302-
}
294+
li := fmt.Sprintf("<li><a href=\"%s\" target=\"_blank\" title=\"%s\">%s</a></li>", attach.HttpPath, attach.FileName, attach.FileName)
295+
296+
content.WriteString(li)
297+
}
298+
content.WriteString("</ul></div>")
299+
if docQuery == nil {
300+
docQuery, err = goquery.NewDocumentFromReader(content)
301+
} else {
302+
if selector := docQuery.Find("div.wiki-bottom").First(); selector.Size() > 0 {
303+
selector.BeforeHtml(content.String()) //This branch should be a compatible branch.
304+
} else if selector := docQuery.Find("div.markdown-article").First(); selector.Size() > 0 {
305+
selector.AppendHtml(content.String()) //The document produced by the editor of Markdown will have this tag.class.
306+
} else if selector := docQuery.Find("div.whole-article-wrap").First(); selector.Size() > 0 {
307+
selector.AppendHtml(content.String()) //All documents should have this tag.
303308
}
304309
}
305310
}
311+
}
306312

307-
//处理了文档底部信息
308-
if selector := docQuery.Find("div.wiki-bottom").First(); selector.Size() <= 0 && item.MemberId > 0 {
309-
//处理文档结尾信息
310-
docCreator, err := NewMember().Find(item.MemberId, "real_name", "account")
311-
release := "<div class=\"wiki-bottom\">"
313+
//处理了文档底部信息
314+
if selector := docQuery.Find("div.wiki-bottom").First(); selector.Size() <= 0 && item.MemberId > 0 {
315+
//处理文档结尾信息
316+
docCreator, err := NewMember().Find(item.MemberId, "real_name", "account")
317+
release := "<div class=\"wiki-bottom\">"
318+
319+
release += i18n.Tr(item.Lang, "doc.ft_author")
320+
if err == nil && docCreator != nil {
321+
if docCreator.RealName != "" {
322+
release += docCreator.RealName
323+
} else {
324+
release += docCreator.Account
325+
}
326+
}
327+
release += " &nbsp;" + i18n.Tr(item.Lang, "doc.ft_create_time") + item.CreateTime.Local().Format("2006-01-02 15:04") + "<br>"
312328

313-
release += i18n.Tr(item.Lang, "doc.ft_author")
314-
if err == nil && docCreator != nil {
315-
if docCreator.RealName != "" {
316-
release += docCreator.RealName
329+
if item.ModifyAt > 0 {
330+
docModify, err := NewMember().Find(item.ModifyAt, "real_name", "account")
331+
if err == nil {
332+
if docModify.RealName != "" {
333+
release += i18n.Tr(item.Lang, "doc.ft_last_editor") + docModify.RealName
317334
} else {
318-
release += docCreator.Account
319-
}
320-
}
321-
release += " &nbsp;" + i18n.Tr(item.Lang, "doc.ft_create_time") + item.CreateTime.Local().Format("2006-01-02 15:04") + "<br>"
322-
323-
if item.ModifyAt > 0 {
324-
docModify, err := NewMember().Find(item.ModifyAt, "real_name", "account")
325-
if err == nil {
326-
if docModify.RealName != "" {
327-
release += i18n.Tr(item.Lang, "doc.ft_last_editor") + docModify.RealName
328-
} else {
329-
release += i18n.Tr(item.Lang, "doc.ft_last_editor") + docModify.Account
330-
}
335+
release += i18n.Tr(item.Lang, "doc.ft_last_editor") + docModify.Account
331336
}
332337
}
333-
release += " &nbsp;" + i18n.Tr(item.Lang, "doc.ft_update_time") + item.ModifyTime.Local().Format("2006-01-02 15:04") + "<br>"
334-
release += "</div>"
338+
}
339+
release += " &nbsp;" + i18n.Tr(item.Lang, "doc.ft_update_time") + item.ModifyTime.Local().Format("2006-01-02 15:04") + "<br>"
340+
release += "</div>"
335341

336-
if selector := docQuery.Find("div.markdown-article").First(); selector.Size() > 0 {
337-
selector.AppendHtml(release)
338-
} else if selector := docQuery.Find("article.markdown-article-inner").First(); selector.Size() > 0 {
339-
selector.First().AppendHtml(release)
340-
}
342+
if selector := docQuery.Find("div.markdown-article").First(); selector.Size() > 0 {
343+
selector.AppendHtml(release)
344+
} else if selector := docQuery.Find("div.whole-article-wrap").First(); selector.Size() > 0 {
345+
selector.AppendHtml(release)
341346
}
342-
cdnimg, _ := web.AppConfig.String("cdnimg")
347+
}
348+
cdnimg, _ := web.AppConfig.String("cdnimg")
343349

344-
docQuery.Find("img").Each(func(i int, selection *goquery.Selection) {
350+
docQuery.Find("img").Each(func(i int, selection *goquery.Selection) {
345351

346-
if src, ok := selection.Attr("src"); ok {
347-
src = strings.TrimSpace(strings.ToLower(src))
348-
//过滤掉没有链接的图片标签
349-
if src == "" || strings.HasPrefix(src, "data:text/html") {
350-
selection.Remove()
351-
return
352-
}
352+
if src, ok := selection.Attr("src"); ok {
353+
src = strings.TrimSpace(strings.ToLower(src))
354+
//过滤掉没有链接的图片标签
355+
if src == "" || strings.HasPrefix(src, "data:text/html") {
356+
selection.Remove()
357+
return
358+
}
353359

354-
//设置图片为CDN地址
355-
if cdnimg != "" && strings.HasPrefix(src, "/uploads/") {
356-
selection.SetAttr("src", utils.JoinURI(cdnimg, src))
357-
}
360+
//设置图片为CDN地址
361+
if cdnimg != "" && strings.HasPrefix(src, "/uploads/") {
362+
selection.SetAttr("src", utils.JoinURI(cdnimg, src))
363+
}
358364

365+
}
366+
selection.RemoveAttr("onerror").RemoveAttr("onload")
367+
})
368+
//过滤A标签的非法连接
369+
docQuery.Find("a").Each(func(i int, selection *goquery.Selection) {
370+
if val, exists := selection.Attr("href"); exists {
371+
if val == "" {
372+
selection.SetAttr("href", "#")
373+
return
359374
}
360-
selection.RemoveAttr("onerror").RemoveAttr("onload")
361-
})
362-
//过滤A标签的非法连接
363-
docQuery.Find("a").Each(func(i int, selection *goquery.Selection) {
364-
if val, exists := selection.Attr("href"); exists {
365-
if val == "" {
366-
selection.SetAttr("href", "#")
367-
return
368-
}
369-
val = strings.Replace(strings.ToLower(val), " ", "", -1)
370-
//移除危险脚本链接
371-
if strings.HasPrefix(val, "data:text/html") ||
372-
strings.HasPrefix(val, "vbscript:") ||
373-
strings.HasPrefix(val, "&#106;avascript:") ||
374-
strings.HasPrefix(val, "javascript:") {
375-
selection.SetAttr("href", "#")
376-
}
375+
val = strings.Replace(strings.ToLower(val), " ", "", -1)
376+
//移除危险脚本链接
377+
if strings.HasPrefix(val, "data:text/html") ||
378+
strings.HasPrefix(val, "vbscript:") ||
379+
strings.HasPrefix(val, "&#106;avascript:") ||
380+
strings.HasPrefix(val, "javascript:") {
381+
selection.SetAttr("href", "#")
377382
}
378-
//移除所有 onerror 属性
379-
selection.RemoveAttr("onerror").RemoveAttr("onload").RemoveAttr("onclick")
380-
})
383+
}
384+
//移除所有 onerror 属性
385+
selection.RemoveAttr("onerror").RemoveAttr("onload").RemoveAttr("onclick")
386+
})
381387

382-
docQuery.Find("script").Remove()
383-
docQuery.Find("link").Remove()
384-
docQuery.Find("vbscript").Remove()
388+
docQuery.Find("script").Remove()
389+
docQuery.Find("link").Remove()
390+
docQuery.Find("vbscript").Remove()
385391

386-
if html, err := docQuery.Html(); err == nil {
387-
item.Release = strings.TrimSuffix(strings.TrimPrefix(strings.TrimSpace(html), "<html><head></head><body>"), "</body></html>")
388-
}
392+
if html, err := docQuery.Html(); err == nil {
393+
item.Release = strings.TrimSuffix(strings.TrimPrefix(strings.TrimSpace(html), "<html><head></head><body>"), "</body></html>")
389394
}
390395
}
396+
391397
return item
392398
}
393399

utils/html.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,8 @@ func SafetyProcessor(html string) string {
110110
}
111111
})
112112
//添加文档标签包裹
113-
if selector := docQuery.Find("article.markdown-article-inner").First(); selector.Size() <= 0 {
114-
docQuery.Children().WrapAllHtml("<article class=\"markdown-article-inner\"></article>")
113+
if selector := docQuery.Find("div.whole-article-wrap").First(); selector.Size() <= 0 {
114+
docQuery.Find("body").Children().WrapAllHtml("<div class=\"whole-article-wrap\"></div>")
115115
}
116116
//解决文档内容缺少包裹标签的问题
117117
if selector := docQuery.Find("div.markdown-article").First(); selector.Size() <= 0 {

views/blog/index.tpl

+1-1
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@
9595
<div class="article-body markdown-body editormd-preview-container content">
9696
{{.Content}}
9797
{{if .Model.AttachList}}
98-
<div class="attach-list"><strong>{{i18n .Lang "blog.attachment"}}</strong><ul>
98+
<div class="attach-list"><strong>{{i18n .Lang "doc.attachment"}}</strong><ul>
9999
{{range $index,$item := .Model.AttachList}}
100100
<li><a href="{{$item.HttpPath}}" title="{{$item.FileName}}">{{$item.FileName}}</a> </li>
101101
{{end}}

0 commit comments

Comments
 (0)