From 5cc0801de90d16b4d528e62de11c9b525be5d122 Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Mon, 3 Apr 2023 18:06:57 +0800 Subject: [PATCH] Introduce GitHub markdown editor, keep EasyMDE as fallback (#23876) The first step of the plan * #23290 Thanks to @silverwind for the first try in #15394 . Close #10729 and a lot of related issues. The EasyMDE is not removed, now it works as a fallback, users can switch between these two editors. Editor list: * Issue / PR comment * Issue / PR comment edit * Issue / PR comment quote reply * PR diff view, inline comment * PR diff view, inline comment edit * PR diff view, inline comment quote reply * Release editor * Wiki editor Some editors have attached dropzone Screenshots:
![image](https://user-images.githubusercontent.com/2114189/229363558-7e44dcd4-fb6d-48a0-92f8-bd12f57bb0a0.png) ![image](https://user-images.githubusercontent.com/2114189/229363566-781489c8-5306-4347-9714-d71af5d5b0b1.png) ![image](https://user-images.githubusercontent.com/2114189/229363771-1717bf5c-0f2a-4fc2-ba84-4f5b2a343a11.png) ![image](https://user-images.githubusercontent.com/2114189/229363793-ad362d0f-a045-47bd-8f9d-05a9a842bb39.png)
--------- Co-authored-by: silverwind --- package-lock.json | 6 + package.json | 1 + routers/web/devtest/devtest.go | 35 ++ routers/web/misc/markup.go | 18 - routers/web/org/setting.go | 1 - routers/web/repo/commit.go | 1 - routers/web/repo/compare.go | 1 - routers/web/repo/editor.go | 2 - routers/web/repo/issue.go | 2 - routers/web/repo/issue_label.go | 1 - routers/web/repo/pull.go | 2 - routers/web/repo/release.go | 4 - routers/web/web.go | 7 + templates/base/head_script.tmpl | 24 +- templates/devtest/gitea-ui.tmpl | 12 + templates/devtest/list.tmpl | 5 + templates/repo/diff/box.tmpl | 21 +- templates/repo/diff/comment_form.tmpl | 22 +- templates/repo/diff/new_review.tmpl | 9 +- templates/repo/issue/comment_tab.tmpl | 28 +- templates/repo/issue/fields/textarea.tmpl | 2 +- .../repo/issue/labels/edit_delete_label.tmpl | 2 +- templates/repo/issue/labels/label_new.tmpl | 2 +- templates/repo/issue/view_content.tmpl | 25 +- templates/repo/release/new.tmpl | 21 +- templates/repo/wiki/new.tmpl | 21 +- templates/shared/combomarkdowneditor.tmpl | 47 +++ web_src/css/editor-markdown.css | 25 ++ web_src/css/editor.css | 1 - web_src/css/index.css | 1 + web_src/css/repository.css | 4 - web_src/css/review.css | 5 + .../js/features/comp/ComboMarkdownEditor.js | 277 +++++++++++++++ web_src/js/features/comp/EasyMDE.js | 181 ---------- web_src/js/features/comp/ImagePaste.js | 51 +-- .../js/features/comp/MarkupContentPreview.js | 25 -- web_src/js/features/contextpopup.js | 13 +- web_src/js/features/repo-diff.js | 2 +- web_src/js/features/repo-issue.js | 74 +--- web_src/js/features/repo-legacy.js | 331 ++++++++---------- web_src/js/features/repo-release.js | 17 +- web_src/js/features/repo-wiki.js | 220 +++--------- web_src/js/features/tribute.js | 33 +- web_src/js/index.js | 3 - web_src/js/utils.js | 5 - web_src/js/utils.test.js | 6 +- 46 files changed, 763 insertions(+), 833 deletions(-) create mode 100644 routers/web/devtest/devtest.go create mode 100644 templates/devtest/gitea-ui.tmpl create mode 100644 templates/devtest/list.tmpl create mode 100644 templates/shared/combomarkdowneditor.tmpl create mode 100644 web_src/css/editor-markdown.css create mode 100644 web_src/js/features/comp/ComboMarkdownEditor.js delete mode 100644 web_src/js/features/comp/EasyMDE.js delete mode 100644 web_src/js/features/comp/MarkupContentPreview.js diff --git a/package-lock.json b/package-lock.json index 9d0c83f65..b9d998a69 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,6 +12,7 @@ "@citation-js/plugin-csl": "0.6.7", "@citation-js/plugin-software-formats": "0.6.1", "@claviska/jquery-minicolors": "2.3.6", + "@github/markdown-toolbar-element": "2.1.1", "@mcaptcha/vanilla-glue": "0.1.0-alpha-3", "@primer/octicons": "18.3.0", "@vue/compiler-sfc": "3.2.47", @@ -838,6 +839,11 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, + "node_modules/@github/markdown-toolbar-element": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@github/markdown-toolbar-element/-/markdown-toolbar-element-2.1.1.tgz", + "integrity": "sha512-J++rpd5H9baztabJQB82h26jtueOeBRSTqetk9Cri+Lj/s28ndu6Tovn0uHQaOKtBWDobFunk9b5pP5vcqt7cA==" + }, "node_modules/@humanwhocodes/config-array": { "version": "0.11.8", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", diff --git a/package.json b/package.json index 8ac5c312f..3ccf0c084 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "@citation-js/plugin-csl": "0.6.7", "@citation-js/plugin-software-formats": "0.6.1", "@claviska/jquery-minicolors": "2.3.6", + "@github/markdown-toolbar-element": "2.1.1", "@mcaptcha/vanilla-glue": "0.1.0-alpha-3", "@primer/octicons": "18.3.0", "@vue/compiler-sfc": "3.2.47", diff --git a/routers/web/devtest/devtest.go b/routers/web/devtest/devtest.go new file mode 100644 index 000000000..eb77d0b92 --- /dev/null +++ b/routers/web/devtest/devtest.go @@ -0,0 +1,35 @@ +// Copyright 2023 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package devtest + +import ( + "net/http" + "path" + "strings" + + "code.gitea.io/gitea/modules/base" + "code.gitea.io/gitea/modules/context" + "code.gitea.io/gitea/modules/templates" +) + +// List all devtest templates, they will be used for e2e tests for the UI components +func List(ctx *context.Context) { + templateNames := templates.GetTemplateAssetNames() + var subNames []string + const prefix = "templates/devtest/" + for _, tmplName := range templateNames { + if strings.HasPrefix(tmplName, prefix) { + subName := strings.TrimSuffix(strings.TrimPrefix(tmplName, prefix), ".tmpl") + if subName != "list" { + subNames = append(subNames, subName) + } + } + } + ctx.Data["SubNames"] = subNames + ctx.HTML(http.StatusOK, "devtest/list") +} + +func Tmpl(ctx *context.Context) { + ctx.HTML(http.StatusOK, base.TplName("devtest"+path.Clean("/"+ctx.Params("sub")))) +} diff --git a/routers/web/misc/markup.go b/routers/web/misc/markup.go index f678316f4..169037894 100644 --- a/routers/web/misc/markup.go +++ b/routers/web/misc/markup.go @@ -15,24 +15,6 @@ import ( // Markup render markup document to HTML func Markup(ctx *context.Context) { - // swagger:operation POST /markup miscellaneous renderMarkup - // --- - // summary: Render a markup document as HTML - // parameters: - // - name: body - // in: body - // schema: - // "$ref": "#/definitions/MarkupOption" - // consumes: - // - application/json - // produces: - // - text/html - // responses: - // "200": - // "$ref": "#/responses/MarkupRender" - // "422": - // "$ref": "#/responses/validationError" - form := web.GetForm(ctx).(*api.MarkupOption) if ctx.HasAPIError() { diff --git a/routers/web/org/setting.go b/routers/web/org/setting.go index 654e9000f..7d84c101d 100644 --- a/routers/web/org/setting.go +++ b/routers/web/org/setting.go @@ -246,7 +246,6 @@ func Labels(ctx *context.Context) { ctx.Data["Title"] = ctx.Tr("repo.labels") ctx.Data["PageIsOrgSettings"] = true ctx.Data["PageIsOrgSettingsLabels"] = true - ctx.Data["RequireTribute"] = true ctx.Data["LabelTemplates"] = repo_module.LabelTemplates ctx.HTML(http.StatusOK, tplSettingsLabels) } diff --git a/routers/web/repo/commit.go b/routers/web/repo/commit.go index 843b1d8df..7439c2411 100644 --- a/routers/web/repo/commit.go +++ b/routers/web/repo/commit.go @@ -253,7 +253,6 @@ func FileHistory(ctx *context.Context) { // Diff show different from current commit to previous commit func Diff(ctx *context.Context) { ctx.Data["PageIsDiff"] = true - ctx.Data["RequireTribute"] = true userName := ctx.Repo.Owner.Name repoName := ctx.Repo.Repository.Name diff --git a/routers/web/repo/compare.go b/routers/web/repo/compare.go index d7e7bac7b..c49eb762d 100644 --- a/routers/web/repo/compare.go +++ b/routers/web/repo/compare.go @@ -781,7 +781,6 @@ func CompareDiff(ctx *context.Context) { ctx.Data["IsRepoToolbarCommits"] = true ctx.Data["IsDiffCompare"] = true - ctx.Data["RequireTribute"] = true templateErrs := setTemplateIfExists(ctx, pullRequestTemplateKey, pullRequestTemplateCandidates) if len(templateErrs) > 0 { diff --git a/routers/web/repo/editor.go b/routers/web/repo/editor.go index 2b66be22a..f65e1ad3d 100644 --- a/routers/web/repo/editor.go +++ b/routers/web/repo/editor.go @@ -538,7 +538,6 @@ func DeleteFilePost(ctx *context.Context) { // UploadFile render upload file page func UploadFile(ctx *context.Context) { ctx.Data["PageIsUpload"] = true - ctx.Data["RequireTribute"] = true upload.AddUploadContext(ctx, "repo") canCommit := renderCommitRights(ctx) treePath := cleanUploadFileName(ctx.Repo.TreePath) @@ -573,7 +572,6 @@ func UploadFile(ctx *context.Context) { func UploadFilePost(ctx *context.Context) { form := web.GetForm(ctx).(*forms.UploadRepoFileForm) ctx.Data["PageIsUpload"] = true - ctx.Data["RequireTribute"] = true upload.AddUploadContext(ctx, "repo") canCommit := renderCommitRights(ctx) diff --git a/routers/web/repo/issue.go b/routers/web/repo/issue.go index 612222598..e4f1172dd 100644 --- a/routers/web/repo/issue.go +++ b/routers/web/repo/issue.go @@ -849,7 +849,6 @@ func NewIssue(ctx *context.Context) { ctx.Data["Title"] = ctx.Tr("repo.issues.new") ctx.Data["PageIsIssueList"] = true ctx.Data["NewIssueChooseTemplate"] = ctx.HasIssueTemplatesOrContactLinks() - ctx.Data["RequireTribute"] = true ctx.Data["PullRequestWorkInProgressPrefixes"] = setting.Repository.PullRequest.WorkInProgressPrefixes title := ctx.FormString("title") ctx.Data["TitleQuery"] = title @@ -1295,7 +1294,6 @@ func ViewIssue(ctx *context.Context) { ctx.Data["IssueType"] = "all" } - ctx.Data["RequireTribute"] = true ctx.Data["IsProjectsEnabled"] = ctx.Repo.CanRead(unit.TypeProjects) ctx.Data["IsAttachmentEnabled"] = setting.Attachment.Enabled upload.AddUploadContext(ctx, "comment") diff --git a/routers/web/repo/issue_label.go b/routers/web/repo/issue_label.go index 31bf85fed..3123359a6 100644 --- a/routers/web/repo/issue_label.go +++ b/routers/web/repo/issue_label.go @@ -28,7 +28,6 @@ func Labels(ctx *context.Context) { ctx.Data["Title"] = ctx.Tr("repo.labels") ctx.Data["PageIsIssueList"] = true ctx.Data["PageIsLabels"] = true - ctx.Data["RequireTribute"] = true ctx.Data["LabelTemplates"] = repo_module.LabelTemplates ctx.HTML(http.StatusOK, tplLabels) } diff --git a/routers/web/repo/pull.go b/routers/web/repo/pull.go index 4f9968773..c37d52640 100644 --- a/routers/web/repo/pull.go +++ b/routers/web/repo/pull.go @@ -791,7 +791,6 @@ func ViewPullFiles(ctx *context.Context) { setCompareContext(ctx, baseCommit, commit, ctx.Repo.Owner.Name, ctx.Repo.Repository.Name) - ctx.Data["RequireTribute"] = true if ctx.Data["Assignees"], err = repo_model.GetRepoAssignees(ctx, ctx.Repo.Repository); err != nil { ctx.ServerError("GetAssignees", err) return @@ -1160,7 +1159,6 @@ func CompareAndPullRequestPost(ctx *context.Context) { ctx.Data["PageIsComparePull"] = true ctx.Data["IsDiffCompare"] = true ctx.Data["IsRepoToolbarCommits"] = true - ctx.Data["RequireTribute"] = true ctx.Data["PullRequestWorkInProgressPrefixes"] = setting.Repository.PullRequest.WorkInProgressPrefixes ctx.Data["IsAttachmentEnabled"] = setting.Attachment.Enabled upload.AddUploadContext(ctx, "comment") diff --git a/routers/web/repo/release.go b/routers/web/repo/release.go index 3ffadd34a..b8c5f67f4 100644 --- a/routers/web/repo/release.go +++ b/routers/web/repo/release.go @@ -308,7 +308,6 @@ func LatestRelease(ctx *context.Context) { func NewRelease(ctx *context.Context) { ctx.Data["Title"] = ctx.Tr("repo.release.new_release") ctx.Data["PageIsReleaseList"] = true - ctx.Data["RequireTribute"] = true ctx.Data["tag_target"] = ctx.Repo.Repository.DefaultBranch if tagName := ctx.FormString("tag"); len(tagName) > 0 { rel, err := repo_model.GetRelease(ctx.Repo.Repository.ID, tagName) @@ -351,7 +350,6 @@ func NewReleasePost(ctx *context.Context) { form := web.GetForm(ctx).(*forms.NewReleaseForm) ctx.Data["Title"] = ctx.Tr("repo.release.new_release") ctx.Data["PageIsReleaseList"] = true - ctx.Data["RequireTribute"] = true if ctx.HasError() { ctx.HTML(http.StatusOK, tplReleaseNew) @@ -469,7 +467,6 @@ func EditRelease(ctx *context.Context) { ctx.Data["Title"] = ctx.Tr("repo.release.edit_release") ctx.Data["PageIsReleaseList"] = true ctx.Data["PageIsEditRelease"] = true - ctx.Data["RequireTribute"] = true ctx.Data["IsAttachmentEnabled"] = setting.Attachment.Enabled upload.AddUploadContext(ctx, "release") @@ -514,7 +511,6 @@ func EditReleasePost(ctx *context.Context) { ctx.Data["Title"] = ctx.Tr("repo.release.edit_release") ctx.Data["PageIsReleaseList"] = true ctx.Data["PageIsEditRelease"] = true - ctx.Data["RequireTribute"] = true tagName := ctx.Params("*") rel, err := repo_model.GetRelease(ctx.Repo.Repository.ID, tagName) diff --git a/routers/web/web.go b/routers/web/web.go index 4bd2f76c5..6b62ff6f8 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -27,6 +27,7 @@ import ( "code.gitea.io/gitea/modules/web/routing" "code.gitea.io/gitea/routers/web/admin" "code.gitea.io/gitea/routers/web/auth" + "code.gitea.io/gitea/routers/web/devtest" "code.gitea.io/gitea/routers/web/events" "code.gitea.io/gitea/routers/web/explore" "code.gitea.io/gitea/routers/web/feed" @@ -1491,6 +1492,12 @@ func RegisterRoutes(m *web.Route) { if setting.API.EnableSwagger { m.Get("/swagger.v1.json", SwaggerV1Json) } + + if !setting.IsProd { + m.Any("/devtest", devtest.List) + m.Any("/devtest/{sub}", devtest.Tmpl) + } + m.NotFound(func(w http.ResponseWriter, req *http.Request) { ctx := context.GetContext(req) ctx.NotFound("", nil) diff --git a/templates/base/head_script.tmpl b/templates/base/head_script.tmpl index 62fb10d89..670d146b5 100644 --- a/templates/base/head_script.tmpl +++ b/templates/base/head_script.tmpl @@ -15,23 +15,19 @@ If you introduce mistakes in it, Gitea JavaScript code wouldn't run correctly. useServiceWorker: {{UseServiceWorker}}, csrfToken: '{{.CsrfToken}}', pageData: {{.PageData}}, - requireTribute: {{.RequireTribute}}, notificationSettings: {{NotificationSettings}}, {{/*a map provided by NewFuncMap in helper.go*/}} enableTimeTracking: {{EnableTimetracking}}, - {{if .RequireTribute}} + {{if or .Participants .Assignees .MentionableTeams}} tributeValues: Array.from(new Map([ - {{range .Participants}} - ['{{.Name}}', {key: '{{.Name}} {{.FullName}}', value: '{{.Name}}', - name: '{{.Name}}', fullname: '{{.FullName}}', avatar: '{{.AvatarLink $.Context}}'}], - {{end}} - {{range .Assignees}} - ['{{.Name}}', {key: '{{.Name}} {{.FullName}}', value: '{{.Name}}', - name: '{{.Name}}', fullname: '{{.FullName}}', avatar: '{{.AvatarLink $.Context}}'}], - {{end}} - {{range .MentionableTeams}} - ['{{$.MentionableTeamsOrg}}/{{.Name}}', {key: '{{$.MentionableTeamsOrg}}/{{.Name}}', value: '{{$.MentionableTeamsOrg}}/{{.Name}}', - name: '{{$.MentionableTeamsOrg}}/{{.Name}}', avatar: '{{$.MentionableTeamsOrgAvatar}}'}], - {{end}} + {{- range .Participants -}} + ['{{.Name}}', {key: '{{.Name}} {{.FullName}}', value: '{{.Name}}', name: '{{.Name}}', fullname: '{{.FullName}}', avatar: '{{.AvatarLink $.Context}}'}], + {{- end -}} + {{- range .Assignees -}} + ['{{.Name}}', {key: '{{.Name}} {{.FullName}}', value: '{{.Name}}', name: '{{.Name}}', fullname: '{{.FullName}}', avatar: '{{.AvatarLink $.Context}}'}], + {{- end -}} + {{- range .MentionableTeams -}} + ['{{$.MentionableTeamsOrg}}/{{.Name}}', {key: '{{$.MentionableTeamsOrg}}/{{.Name}}', value: '{{$.MentionableTeamsOrg}}/{{.Name}}', name: '{{$.MentionableTeamsOrg}}/{{.Name}}', avatar: '{{$.MentionableTeamsOrgAvatar}}'}], + {{- end -}} ]).values()), {{end}} mermaidMaxSourceCharacters: {{MermaidMaxSourceCharacters}}, diff --git a/templates/devtest/gitea-ui.tmpl b/templates/devtest/gitea-ui.tmpl new file mode 100644 index 000000000..c5ab863d0 --- /dev/null +++ b/templates/devtest/gitea-ui.tmpl @@ -0,0 +1,12 @@ +{{template "base/head" .}} +
+
+ + +
+
+ text with tooltip +
+ {{template "shared/combomarkdowneditor" .}} +
+{{template "base/footer" .}} diff --git a/templates/devtest/list.tmpl b/templates/devtest/list.tmpl new file mode 100644 index 000000000..3a519c328 --- /dev/null +++ b/templates/devtest/list.tmpl @@ -0,0 +1,5 @@ + diff --git a/templates/repo/diff/box.tmpl b/templates/repo/diff/box.tmpl index 36e669276..21ea63cc0 100644 --- a/templates/repo/diff/box.tmpl +++ b/templates/repo/diff/box.tmpl @@ -198,24 +198,21 @@ {{if not $.Repository.IsArchived}} -
+ {{end}} {{template "repo/issue/view_content/reference_issue_dialog" .}} diff --git a/templates/repo/diff/comment_form.tmpl b/templates/repo/diff/comment_form.tmpl index 394a392bb..109f16796 100644 --- a/templates/repo/diff/comment_form.tmpl +++ b/templates/repo/diff/comment_form.tmpl @@ -9,18 +9,16 @@ - -
-
- -
-
- {{.locale.Tr "loading"}} -
-
+ + {{template "shared/combomarkdowneditor" (dict + "locale" $.root.locale + "MarkdownPreviewUrl" (print $.root.Repository.Link "/markup") + "MarkdownPreviewContext" $.root.RepoLink + "TextareaName" "content" + "TextareaPlaceholder" ($.locale.Tr "repo.diff.comment.placeholder") + "DropzoneParentContainer" "form" + )}} +