aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwxiaoguang <wxiaoguang@gmail.com>2024-12-04 10:11:34 +0800
committerGitHub <noreply@github.com>2024-12-04 02:11:34 +0000
commitc9e582c6b6cbc7beae66d24b05be6e1d338aa81b (patch)
treee2212df009376c6bde41296232e414b2388b8ae5
parent2f43536c3eb6ba20e43521f5539df8372f225652 (diff)
downloadgitea-c9e582c6b6cbc7beae66d24b05be6e1d338aa81b.tar.gz
gitea-c9e582c6b6cbc7beae66d24b05be6e1d338aa81b.zip
Refactor markdown editor and use it for milestone description editor (#32688)
Refactor markdown editor to clarify its "preview" behavior and remove jQuery code. Close #15045 --------- Co-authored-by: silverwind <me@silverwind.io>
-rw-r--r--modules/web/route.go5
-rw-r--r--options/locale/locale_en-US.ini1
-rw-r--r--routers/web/web.go2
-rw-r--r--templates/devtest/devtest-footer.tmpl2
-rw-r--r--templates/devtest/devtest-header.tmpl2
-rw-r--r--templates/devtest/gitea-ui.tmpl3
-rw-r--r--templates/org/settings/options.tmpl1
-rw-r--r--templates/projects/new.tmpl11
-rw-r--r--templates/repo/diff/box.tmpl5
-rw-r--r--templates/repo/diff/comment_form.tmpl12
-rw-r--r--templates/repo/diff/new_review.tmpl4
-rw-r--r--templates/repo/issue/comment_tab.tmpl7
-rw-r--r--templates/repo/issue/fields/textarea.tmpl7
-rw-r--r--templates/repo/issue/milestone_new.tmpl9
-rw-r--r--templates/repo/issue/view_content.tmpl5
-rw-r--r--templates/repo/release/new.tmpl5
-rw-r--r--templates/repo/wiki/new.tmpl8
-rw-r--r--templates/shared/combomarkdowneditor.tmpl38
-rw-r--r--templates/user/settings/profile.tmpl1
-rw-r--r--web_src/css/editor/combomarkdowneditor.css5
-rw-r--r--web_src/css/repo.css2
-rw-r--r--web_src/css/review.css25
-rw-r--r--web_src/js/features/common-form.ts8
-rw-r--r--web_src/js/features/comp/ComboMarkdownEditor.ts58
-rw-r--r--web_src/js/features/repo-editor.ts8
-rw-r--r--web_src/js/features/repo-issue.ts5
-rw-r--r--web_src/js/features/repo-release.ts10
-rw-r--r--web_src/js/features/repo-wiki.ts7
-rw-r--r--web_src/js/index.ts7
29 files changed, 147 insertions, 116 deletions
diff --git a/modules/web/route.go b/modules/web/route.go
index 77c411a97b..787521dfb0 100644
--- a/modules/web/route.go
+++ b/modules/web/route.go
@@ -9,6 +9,7 @@ import (
"reflect"
"strings"
+ "code.gitea.io/gitea/modules/htmlutil"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/web/middleware"
@@ -214,7 +215,9 @@ func (r *Router) normalizeRequestPath(resp http.ResponseWriter, req *http.Reques
normalizedPath = "/"
} else if !strings.HasPrefix(normalizedPath+"/", "/v2/") {
// do not respond to other requests, to simulate a real sub-path environment
- http.Error(resp, "404 page not found, sub-path is: "+setting.AppSubURL, http.StatusNotFound)
+ resp.Header().Add("Content-Type", "text/html; charset=utf-8")
+ resp.WriteHeader(http.StatusNotFound)
+ _, _ = resp.Write([]byte(htmlutil.HTMLFormat(`404 page not found, sub-path is: <a href="%s">%s</a>`, setting.AppSubURL, setting.AppSubURL)))
return
}
normalized = true
diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini
index 8da7412ade..57d2d89c5a 100644
--- a/options/locale/locale_en-US.ini
+++ b/options/locale/locale_en-US.ini
@@ -2590,7 +2590,6 @@ diff.generated = generated
diff.vendored = vendored
diff.comment.add_line_comment = Add line comment
diff.comment.placeholder = Leave a comment
-diff.comment.markdown_info = Styling with markdown is supported.
diff.comment.add_single_comment = Add single comment
diff.comment.add_review_comment = Add comment
diff.comment.start_review = Start review
diff --git a/routers/web/web.go b/routers/web/web.go
index 5ed046a983..e89d069449 100644
--- a/routers/web/web.go
+++ b/routers/web/web.go
@@ -485,6 +485,8 @@ func registerRoutes(m *web.Router) {
m.Methods("GET, HEAD", "/*", public.FileHandlerFunc())
}, optionsCorsHandler())
+ m.Post("/-/markup", reqSignIn, web.Bind(structs.MarkupOption{}), misc.Markup)
+
m.Group("/explore", func() {
m.Get("", func(ctx *context.Context) {
ctx.Redirect(setting.AppSubURL + "/explore/repos")
diff --git a/templates/devtest/devtest-footer.tmpl b/templates/devtest/devtest-footer.tmpl
index 1c755508a5..a1b3b86e5c 100644
--- a/templates/devtest/devtest-footer.tmpl
+++ b/templates/devtest/devtest-footer.tmpl
@@ -1,3 +1,3 @@
{{/* TODO: the devtest.js is isolated from index.js, so no module is shared and many index.js functions do not work in devtest.ts */}}
<script src="{{AssetUrlPrefix}}/js/devtest.js?v={{AssetVersion}}"></script>
-{{template "base/footer" dict}}
+{{template "base/footer" ctx.RootData}}
diff --git a/templates/devtest/devtest-header.tmpl b/templates/devtest/devtest-header.tmpl
index a5910b96e6..ee08545640 100644
--- a/templates/devtest/devtest-header.tmpl
+++ b/templates/devtest/devtest-header.tmpl
@@ -1,2 +1,2 @@
-{{template "base/head" dict}}
+{{template "base/head" ctx.RootData}}
<link rel="stylesheet" href="{{AssetUrlPrefix}}/css/devtest.css?v={{AssetVersion}}">
diff --git a/templates/devtest/gitea-ui.tmpl b/templates/devtest/gitea-ui.tmpl
index 303421fe13..5b40268761 100644
--- a/templates/devtest/gitea-ui.tmpl
+++ b/templates/devtest/gitea-ui.tmpl
@@ -183,8 +183,7 @@
<div>
<h1>ComboMarkdownEditor</h1>
- <div>ps: no JS code attached, so just a layout</div>
- {{template "shared/combomarkdowneditor" .}}
+ {{template "shared/combomarkdowneditor" dict "MarkdownPreviewContext" "/owner/path"}}
</div>
<h1>Tailwind CSS Demo</h1>
diff --git a/templates/org/settings/options.tmpl b/templates/org/settings/options.tmpl
index 62debfc0ae..3b817d068b 100644
--- a/templates/org/settings/options.tmpl
+++ b/templates/org/settings/options.tmpl
@@ -23,6 +23,7 @@
<input id="email" name="email" type="email" value="{{.Org.Email}}" maxlength="255">
</div>
<div class="field {{if .Err_Description}}error{{end}}">
+ {{/* it is rendered as markdown, but the length is limited, so at the moment we do not use the markdown editor here */}}
<label for="description">{{ctx.Locale.Tr "org.org_desc"}}</label>
<textarea id="description" name="description" rows="2" maxlength="255">{{.Org.Description}}</textarea>
</div>
diff --git a/templates/projects/new.tmpl b/templates/projects/new.tmpl
index bd173b54bc..a936079c46 100644
--- a/templates/projects/new.tmpl
+++ b/templates/projects/new.tmpl
@@ -18,7 +18,16 @@
</div>
<div class="field">
<label>{{ctx.Locale.Tr "repo.projects.description"}}</label>
- <textarea name="content" placeholder="{{ctx.Locale.Tr "repo.projects.description_placeholder"}}">{{.content}}</textarea>
+ {{/* TODO: repo-level project and org-level project have different behaviros to render */}}
+ {{/* the "Repository" is nil when the project is org-level */}}
+ {{template "shared/combomarkdowneditor" (dict
+ "MarkdownPreviewInRepo" $.Repository
+ "MarkdownPreviewContext" (Iif $.Repository "" .HomeLink)
+ "MarkdownPreviewMode" (Iif $.Repository "comment")
+ "TextareaName" "content"
+ "TextareaContent" .content
+ "TextareaPlaceholder" (ctx.Locale.Tr "repo.projects.description_placeholder")
+ )}}
</div>
{{if not .PageIsEditProjects}}
diff --git a/templates/repo/diff/box.tmpl b/templates/repo/diff/box.tmpl
index 20e0c9db66..0f1458bfbf 100644
--- a/templates/repo/diff/box.tmpl
+++ b/templates/repo/diff/box.tmpl
@@ -240,8 +240,9 @@
<template id="issue-comment-editor-template">
<div class="ui form comment">
{{template "shared/combomarkdowneditor" (dict
- "MarkdownPreviewUrl" (print $.Repository.Link "/markup")
- "MarkdownPreviewContext" $.RepoLink
+ "CustomInit" true
+ "MarkdownPreviewInRepo" $.Repository
+ "MarkdownPreviewMode" "comment"
"TextareaName" "content"
"DropzoneParentContainer" ".ui.form"
)}}
diff --git a/templates/repo/diff/comment_form.tmpl b/templates/repo/diff/comment_form.tmpl
index 856b3da01a..964dc2adc7 100644
--- a/templates/repo/diff/comment_form.tmpl
+++ b/templates/repo/diff/comment_form.tmpl
@@ -9,24 +9,24 @@
<input type="hidden" name="diff_start_cid">
<input type="hidden" name="diff_end_cid">
<input type="hidden" name="diff_base_cid">
-
+ <div class="field">
{{template "shared/combomarkdowneditor" (dict
- "MarkdownPreviewUrl" (print $.root.Repository.Link "/markup")
- "MarkdownPreviewContext" $.root.RepoLink
+ "CustomInit" true
+ "MarkdownPreviewInRepo" $.root.Repository
+ "MarkdownPreviewMode" "comment"
"TextareaName" "content"
"TextareaPlaceholder" (ctx.Locale.Tr "repo.diff.comment.placeholder")
"DropzoneParentContainer" "form"
"DisableAutosize" "true"
)}}
-
+ </div>
{{if $.root.IsAttachmentEnabled}}
<div class="field">
{{template "repo/upload" $.root}}
</div>
{{end}}
- <div class="field footer tw-mx-2">
- <span class="markup-info">{{svg "octicon-markdown"}} {{ctx.Locale.Tr "repo.diff.comment.markdown_info"}}</span>
+ <div class="field footer">
<div class="tw-text-right">
{{if $.reply}}
<button class="ui submit primary tiny button btn-reply" type="submit">{{ctx.Locale.Tr "repo.diff.comment.reply"}}</button>
diff --git a/templates/repo/diff/new_review.tmpl b/templates/repo/diff/new_review.tmpl
index 1b74a230f4..2febc6303a 100644
--- a/templates/repo/diff/new_review.tmpl
+++ b/templates/repo/diff/new_review.tmpl
@@ -16,8 +16,8 @@
</div>
<div class="field">
{{template "shared/combomarkdowneditor" (dict
- "MarkdownPreviewUrl" (print .Repository.Link "/markup")
- "MarkdownPreviewContext" .RepoLink
+ "MarkdownPreviewInRepo" $.Repository
+ "MarkdownPreviewMode" "comment"
"TextareaName" "content"
"TextareaPlaceholder" (ctx.Locale.Tr "repo.diff.review.placeholder")
"DropzoneParentContainer" "form"
diff --git a/templates/repo/issue/comment_tab.tmpl b/templates/repo/issue/comment_tab.tmpl
index 4197ea4f65..a4626dd89e 100644
--- a/templates/repo/issue/comment_tab.tmpl
+++ b/templates/repo/issue/comment_tab.tmpl
@@ -5,11 +5,12 @@
<div class="field">
{{template "shared/combomarkdowneditor" (dict
- "MarkdownPreviewUrl" (print .Repository.Link "/markup")
- "MarkdownPreviewContext" .RepoLink
+ "CustomInit" true
+ "MarkdownPreviewInRepo" $.Repository
+ "MarkdownPreviewMode" "comment"
"TextareaName" "content"
"TextareaContent" $textareaContent
- "TextareaPlaceholder" (ctx.Locale.Tr "repo.diff.comment.placeholder")
+ "TextareaPlaceholder" (ctx.Locale.Tr "repo.diff.comment.placeholder")
"DropzoneParentContainer" "form, .ui.form"
)}}
</div>
diff --git a/templates/repo/issue/fields/textarea.tmpl b/templates/repo/issue/fields/textarea.tmpl
index 3ad69e1220..722b67015f 100644
--- a/templates/repo/issue/fields/textarea.tmpl
+++ b/templates/repo/issue/fields/textarea.tmpl
@@ -7,11 +7,12 @@
{{if $useMarkdownEditor}}
{{template "shared/combomarkdowneditor" (dict
+ "CustomInit" true
"ContainerClasses" "tw-hidden"
- "MarkdownPreviewUrl" (print .root.RepoLink "/markup")
- "MarkdownPreviewContext" .root.RepoLink
+ "MarkdownPreviewInRepo" $.root.Repository
+ "MarkdownPreviewMode" "comment"
"TextareaContent" .item.Attributes.value
- "TextareaPlaceholder" .item.Attributes.placeholder
+ "TextareaPlaceholder" .item.Attributes.placeholder
"DropzoneParentContainer" ".combo-editor-dropzone"
)}}
diff --git a/templates/repo/issue/milestone_new.tmpl b/templates/repo/issue/milestone_new.tmpl
index 96a3879b80..4809149a21 100644
--- a/templates/repo/issue/milestone_new.tmpl
+++ b/templates/repo/issue/milestone_new.tmpl
@@ -36,9 +36,14 @@
</div>
<div class="field">
<label>{{ctx.Locale.Tr "repo.milestones.desc"}}</label>
- <textarea name="content">{{.content}}</textarea>
+ {{template "shared/combomarkdowneditor" (dict
+ "MarkdownPreviewInRepo" $.Repository
+ "MarkdownPreviewMode" "comment"
+ "TextareaName" "content"
+ "TextareaContent" .content
+ "TextareaPlaceholder" (ctx.Locale.Tr "repo.milestones.desc")
+ )}}
</div>
- <div class="divider"></div>
<div class="tw-text-right">
{{if .PageIsEditMilestone}}
<a class="ui primary basic button" href="{{.RepoLink}}/milestones">
diff --git a/templates/repo/issue/view_content.tmpl b/templates/repo/issue/view_content.tmpl
index 3f7b2dc78f..69b5a11a14 100644
--- a/templates/repo/issue/view_content.tmpl
+++ b/templates/repo/issue/view_content.tmpl
@@ -142,8 +142,9 @@
<div class="ui form comment">
<div class="field">
{{template "shared/combomarkdowneditor" (dict
- "MarkdownPreviewUrl" (print .Repository.Link "/markup")
- "MarkdownPreviewContext" .RepoLink
+ "CustomInit" true
+ "MarkdownPreviewInRepo" $.Repository
+ "MarkdownPreviewMode" "comment"
"TextareaName" "content"
"DropzoneParentContainer" ".ui.form"
)}}
diff --git a/templates/repo/release/new.tmpl b/templates/repo/release/new.tmpl
index c01f9a421b..574b0d0311 100644
--- a/templates/repo/release/new.tmpl
+++ b/templates/repo/release/new.tmpl
@@ -50,12 +50,11 @@
</div>
<div class="field">
{{template "shared/combomarkdowneditor" (dict
- "MarkdownPreviewUrl" (print .Repository.Link "/markup")
- "MarkdownPreviewContext" .RepoLink
+ "MarkdownPreviewInRepo" $.Repository
+ "MarkdownPreviewMode" "comment"
"TextareaName" "content"
"TextareaContent" .content
"TextareaPlaceholder" (ctx.Locale.Tr "repo.release.message")
- "TextareaAriaLabel" (ctx.Locale.Tr "repo.release.message")
"DropzoneParentContainer" "form"
)}}
</div>
diff --git a/templates/repo/wiki/new.tmpl b/templates/repo/wiki/new.tmpl
index 0f10e60c4f..ea2913c0fd 100644
--- a/templates/repo/wiki/new.tmpl
+++ b/templates/repo/wiki/new.tmpl
@@ -23,12 +23,12 @@
{{$content = ctx.Locale.Tr "repo.wiki.welcome"}}
{{end}}
{{template "shared/combomarkdowneditor" (dict
- "MarkdownPreviewUrl" (print .Repository.Link "/markup")
- "MarkdownPreviewContext" .RepoLink
+ "CustomInit" true
+ "MarkdownPreviewInRepo" $.Repository
+ "MarkdownPreviewMode" "wiki"
"TextareaName" "content"
- "TextareaPlaceholder" (ctx.Locale.Tr "repo.wiki.page_content")
- "TextareaAriaLabel" (ctx.Locale.Tr "repo.wiki.page_content")
"TextareaContent" $content
+ "TextareaPlaceholder" (ctx.Locale.Tr "repo.wiki.page_content")
)}}
<div class="field tw-mt-4">
diff --git a/templates/shared/combomarkdowneditor.tmpl b/templates/shared/combomarkdowneditor.tmpl
index 6ee989d1d6..3191346f59 100644
--- a/templates/shared/combomarkdowneditor.tmpl
+++ b/templates/shared/combomarkdowneditor.tmpl
@@ -1,23 +1,39 @@
{{/*
Template Attributes:
+* CustomInit: do not initialize the editor automatically
* ContainerId: id attribute for the container element
* ContainerClasses: additional classes for the container element
-* MarkdownPreviewUrl: preview url for the preview tab
-* MarkdownPreviewContext: preview context for the preview tab
+* MarkdownPreviewInRepo: the repo to preview markdown
+* MarkdownPreviewContext: preview context (the related url path when rendering) for the preview tab, eg: repo link or user home link
+* MarkdownPreviewMode: content mode for the editor, eg: wiki, comment or default
* TextareaName: name attribute for the textarea
* TextareaContent: content for the textarea
+* TextareaMaxLength: maxlength attribute for the textarea
* TextareaPlaceholder: placeholder attribute for the textarea
* TextareaAriaLabel: aria-label attribute for the textarea
* DropzoneParentContainer: container for file upload (leave it empty if no upload)
* DisableAutosize: whether to disable automatic height resizing
*/}}
-<div {{if .ContainerId}}id="{{.ContainerId}}"{{end}} class="combo-markdown-editor {{.ContainerClasses}}" data-dropzone-parent-container="{{.DropzoneParentContainer}}">
- {{if .MarkdownPreviewUrl}}
+{{$ariaLabel := or .TextareaAriaLabel .TextareaPlaceholder}}
+{{$repo := .MarkdownPreviewInRepo}}
+{{$previewContext := .MarkdownPreviewContext}}
+{{$previewMode := .MarkdownPreviewMode}}
+{{$previewUrl := print AppSubUrl "/-/markup"}}
+{{if $repo}}
+ {{$previewUrl = print $repo.Link "/markup"}}
+{{end}}
+{{$supportEasyMDE := or (eq $previewMode "comment") (eq $previewMode "wiki")}}
+<div {{if .ContainerId}}id="{{.ContainerId}}"{{end}} class="combo-markdown-editor {{if .CustomInit}}custom-init{{end}} {{.ContainerClasses}}"
+ data-dropzone-parent-container="{{.DropzoneParentContainer}}"
+ data-content-mode="{{$previewMode}}"
+ data-support-easy-mde="{{$supportEasyMDE}}"
+ data-preview-url="{{$previewUrl}}"
+ data-preview-context="{{$previewContext}}"
+>
<div class="ui top tabular menu">
<a class="active item" data-tab-for="markdown-writer">{{template "shared/misc/tabtitle" (ctx.Locale.Tr "write")}}</a>
- <a class="item" data-tab-for="markdown-previewer" data-preview-url="{{.MarkdownPreviewUrl}}" data-preview-context="{{.MarkdownPreviewContext}}">{{template "shared/misc/tabtitle" (ctx.Locale.Tr "preview")}}</a>
+ <a class="item" data-tab-for="markdown-previewer">{{template "shared/misc/tabtitle" (ctx.Locale.Tr "preview")}}</a>
</div>
- {{end}}
<div class="ui tab active" data-tab-panel="markdown-writer">
<markdown-toolbar>
<div class="markdown-toolbar-group">
@@ -40,17 +56,25 @@ Template Attributes:
<md-task-list class="markdown-toolbar-button" data-tooltip-content="{{ctx.Locale.Tr "editor.buttons.list.task.tooltip"}}">{{svg "octicon-tasklist"}}</md-task-list>
<button class="markdown-toolbar-button markdown-button-table-add" data-tooltip-content="{{ctx.Locale.Tr "editor.buttons.table.add.tooltip"}}">{{svg "octicon-table"}}</button>
</div>
+ {{if eq $previewMode "comment"}}
<div class="markdown-toolbar-group">
<md-mention class="markdown-toolbar-button" data-tooltip-content="{{ctx.Locale.Tr "editor.buttons.mention.tooltip"}}">{{svg "octicon-mention"}}</md-mention>
<md-ref class="markdown-toolbar-button" data-tooltip-content="{{ctx.Locale.Tr "editor.buttons.ref.tooltip"}}">{{svg "octicon-cross-reference"}}</md-ref>
</div>
+ {{end}}
<div class="markdown-toolbar-group">
<button class="markdown-toolbar-button markdown-switch-monospace" role="switch" data-enable-text="{{ctx.Locale.Tr "editor.buttons.enable_monospace_font"}}" data-disable-text="{{ctx.Locale.Tr "editor.buttons.disable_monospace_font"}}">{{svg "octicon-typography"}}</button>
+ {{if $supportEasyMDE}}
<button class="markdown-toolbar-button markdown-switch-easymde" data-tooltip-content="{{ctx.Locale.Tr "editor.buttons.switch_to_legacy.tooltip"}}">{{svg "octicon-arrow-switch"}}</button>
+ {{end}}
</div>
</markdown-toolbar>
<text-expander keys=": @ #" multiword="#" suffix="">
- <textarea class="markdown-text-editor"{{if .TextareaName}} name="{{.TextareaName}}"{{end}}{{if .TextareaPlaceholder}} placeholder="{{.TextareaPlaceholder}}"{{end}}{{if .TextareaAriaLabel}} aria-label="{{.TextareaAriaLabel}}"{{end}}{{if .DisableAutosize}} data-disable-autosize="{{.DisableAutosize}}"{{end}}>{{.TextareaContent}}</textarea>
+ <textarea class="markdown-text-editor"
+ {{if .TextareaName}}name="{{.TextareaName}}"{{end}} {{if .TextareaMaxLength}}maxlength="{{.TextareaMaxLength}}"{{end}}
+ {{if .TextareaPlaceholder}}placeholder="{{.TextareaPlaceholder}}"{{end}} {{if $ariaLabel}}aria-label="{{$ariaLabel}}"{{end}}
+ {{if .DisableAutosize}}data-disable-autosize="{{.DisableAutosize}}"{{end}}
+ >{{.TextareaContent}}</textarea>
</text-expander>
<script>
if (localStorage?.getItem('markdown-editor-monospace') === 'true') {
diff --git a/templates/user/settings/profile.tmpl b/templates/user/settings/profile.tmpl
index f879587c71..197763425c 100644
--- a/templates/user/settings/profile.tmpl
+++ b/templates/user/settings/profile.tmpl
@@ -29,6 +29,7 @@
<p id="signed-user-email">{{.SignedUser.Email}}</p>
</div>
<div class="field {{if .Err_Description}}error{{end}}">
+ {{/* it is rendered as markdown, but the length is limited, so at the moment we do not use the markdown editor here */}}
<label for="description">{{ctx.Locale.Tr "user.user_bio"}}</label>
<textarea id="description" name="description" rows="2" placeholder="{{ctx.Locale.Tr "settings.biography_placeholder"}}" maxlength="255">{{.SignedUser.Description}}</textarea>
</div>
diff --git a/web_src/css/editor/combomarkdowneditor.css b/web_src/css/editor/combomarkdowneditor.css
index 97a8b70227..835286b795 100644
--- a/web_src/css/editor/combomarkdowneditor.css
+++ b/web_src/css/editor/combomarkdowneditor.css
@@ -96,6 +96,11 @@
font-size: 0.85em;
}
+.combo-markdown-editor .ui.tab.markup[data-tab-panel="markdown-previewer"] {
+ border-bottom: 1px solid var(--color-secondary);
+ padding-bottom: 1rem;
+}
+
text-expander {
display: block;
position: relative;
diff --git a/web_src/css/repo.css b/web_src/css/repo.css
index 12cdc4657b..b40859975c 100644
--- a/web_src/css/repo.css
+++ b/web_src/css/repo.css
@@ -1005,7 +1005,7 @@ td .commit-summary {
}
.repository.view.issue .comment-list .code-comment .comment-content {
- margin-left: 36px;
+ margin-left: 24px;
}
.repository.view.issue .comment-list .comment > .avatar {
diff --git a/web_src/css/review.css b/web_src/css/review.css
index 0d69e36681..036ad017f8 100644
--- a/web_src/css/review.css
+++ b/web_src/css/review.css
@@ -102,19 +102,11 @@
cursor: pointer;
}
-.comment-code-cloud .ui.active.tab {
- padding: 0.5em;
-}
-
.comment-code-cloud .ui.active.tab.markup {
padding: 1em;
min-height: 168px;
}
-.comment-code-cloud .ui.tabular.menu {
- margin: 0.5em;
-}
-
.comment-code-cloud .editor-statusbar {
display: none;
}
@@ -123,23 +115,6 @@
padding: 10px 0;
}
-.comment-code-cloud .footer .markup-info {
- display: inline-block;
- margin: 5px 0;
- font-size: 12px;
- color: var(--color-text-light);
-}
-
-.comment-code-cloud .footer .ui.right.floated {
- padding-top: 6px;
-}
-
-.comment-code-cloud .footer::after {
- clear: both;
- content: "";
- display: block;
-}
-
.diff-file-body .comment-form {
margin: 0 0 0 3em;
}
diff --git a/web_src/js/features/common-form.ts b/web_src/js/features/common-form.ts
index 1aca93169d..86323e352e 100644
--- a/web_src/js/features/common-form.ts
+++ b/web_src/js/features/common-form.ts
@@ -1,5 +1,7 @@
import {applyAreYouSure, initAreYouSure} from '../vendor/jquery.are-you-sure.ts';
import {handleGlobalEnterQuickSubmit} from './comp/QuickSubmit.ts';
+import {queryElems} from '../utils/dom.ts';
+import {initComboMarkdownEditor} from './comp/ComboMarkdownEditor.ts';
export function initGlobalFormDirtyLeaveConfirm() {
initAreYouSure(window.jQuery);
@@ -11,7 +13,7 @@ export function initGlobalFormDirtyLeaveConfirm() {
}
export function initGlobalEnterQuickSubmit() {
- document.addEventListener('keydown', (e) => {
+ document.addEventListener('keydown', (e: KeyboardEvent & {target: HTMLElement}) => {
if (e.key !== 'Enter') return;
const hasCtrlOrMeta = ((e.ctrlKey || e.metaKey) && !e.altKey);
if (hasCtrlOrMeta && e.target.matches('textarea')) {
@@ -27,3 +29,7 @@ export function initGlobalEnterQuickSubmit() {
}
});
}
+
+export function initGlobalComboMarkdownEditor() {
+ queryElems<HTMLElement>(document, '.combo-markdown-editor:not(.custom-init)', (el) => initComboMarkdownEditor(el));
+}
diff --git a/web_src/js/features/comp/ComboMarkdownEditor.ts b/web_src/js/features/comp/ComboMarkdownEditor.ts
index 7117952fa3..80eabaa37a 100644
--- a/web_src/js/features/comp/ComboMarkdownEditor.ts
+++ b/web_src/js/features/comp/ComboMarkdownEditor.ts
@@ -1,6 +1,5 @@
import '@github/markdown-toolbar-element';
import '@github/text-expander-element';
-import $ from 'jquery';
import {attachTribute} from '../tribute.ts';
import {hideElem, showElem, autosize, isElemVisible} from '../../utils/dom.ts';
import {
@@ -23,6 +22,8 @@ import {
} from './EditorMarkdown.ts';
import {DropzoneCustomEventReloadFiles, initDropzone} from '../dropzone.ts';
import {createTippy} from '../../modules/tippy.ts';
+import {fomanticQuery} from '../../modules/fomantic/base.ts';
+import type EasyMDE from 'easymde';
let elementIdCounter = 0;
@@ -48,18 +49,23 @@ export function validateTextareaNonEmpty(textarea) {
return true;
}
+type ComboMarkdownEditorOptions = {
+ editorHeights?: {minHeight?: string, height?: string, maxHeight?: string},
+ easyMDEOptions?: EasyMDE.Options,
+};
+
export class ComboMarkdownEditor {
static EventEditorContentChanged = EventEditorContentChanged;
static EventUploadStateChanged = EventUploadStateChanged;
public container : HTMLElement;
- // TODO: use correct types to replace these "any" types
- options: any;
+ options: ComboMarkdownEditorOptions;
tabEditor: HTMLElement;
tabPreviewer: HTMLElement;
+ supportEasyMDE: boolean;
easyMDE: any;
easyMDEToolbarActions: any;
easyMDEToolbarDefault: any;
@@ -71,11 +77,12 @@ export class ComboMarkdownEditor {
dropzone: HTMLElement;
attachedDropzoneInst: any;
+ previewMode: string;
previewUrl: string;
previewContext: string;
- previewMode: string;
- constructor(container, options = {}) {
+ constructor(container, options:ComboMarkdownEditorOptions = {}) {
+ if (container._giteaComboMarkdownEditor) throw new Error('ComboMarkdownEditor already initialized');
container._giteaComboMarkdownEditor = this;
this.options = options;
this.container = container;
@@ -99,6 +106,10 @@ export class ComboMarkdownEditor {
}
setupContainer() {
+ this.supportEasyMDE = this.container.getAttribute('data-support-easy-mde') === 'true';
+ this.previewMode = this.container.getAttribute('data-content-mode');
+ this.previewUrl = this.container.getAttribute('data-preview-url');
+ this.previewContext = this.container.getAttribute('data-preview-context');
initTextExpander(this.container.querySelector('text-expander'));
}
@@ -137,12 +148,14 @@ export class ComboMarkdownEditor {
monospaceButton.setAttribute('aria-checked', String(enabled));
});
- const easymdeButton = this.container.querySelector('.markdown-switch-easymde');
- easymdeButton.addEventListener('click', async (e) => {
- e.preventDefault();
- this.userPreferredEditor = 'easymde';
- await this.switchToEasyMDE();
- });
+ if (this.supportEasyMDE) {
+ const easymdeButton = this.container.querySelector('.markdown-switch-easymde');
+ easymdeButton.addEventListener('click', async (e) => {
+ e.preventDefault();
+ this.userPreferredEditor = 'easymde';
+ await this.switchToEasyMDE();
+ });
+ }
this.initMarkdownButtonTableAdd();
@@ -187,6 +200,7 @@ export class ComboMarkdownEditor {
setupTab() {
const tabs = this.container.querySelectorAll<HTMLElement>('.tabular.menu > .item');
+ if (!tabs.length) return;
// Fomantic Tab requires the "data-tab" to be globally unique.
// So here it uses our defined "data-tab-for" and "data-tab-panel" to generate the "data-tab" attribute for Fomantic.
@@ -207,11 +221,8 @@ export class ComboMarkdownEditor {
});
});
- $(tabs).tab();
+ fomanticQuery(tabs).tab();
- this.previewUrl = this.tabPreviewer.getAttribute('data-preview-url');
- this.previewContext = this.tabPreviewer.getAttribute('data-preview-context');
- this.previewMode = this.options.previewMode ?? 'comment';
this.tabPreviewer.addEventListener('click', async () => {
const formData = new FormData();
formData.append('mode', this.previewMode);
@@ -219,7 +230,7 @@ export class ComboMarkdownEditor {
formData.append('text', this.value());
const response = await POST(this.previewUrl, {data: formData});
const data = await response.text();
- renderPreviewPanelContent($(panelPreviewer), data);
+ renderPreviewPanelContent(panelPreviewer, data);
});
}
@@ -284,7 +295,7 @@ export class ComboMarkdownEditor {
}
async switchToUserPreference() {
- if (this.userPreferredEditor === 'easymde') {
+ if (this.userPreferredEditor === 'easymde' && this.supportEasyMDE) {
await this.switchToEasyMDE();
} else {
this.switchToTextarea();
@@ -304,7 +315,7 @@ export class ComboMarkdownEditor {
if (this.easyMDE) return;
// EasyMDE's CSS should be loaded via webpack config, otherwise our own styles can not overwrite the default styles.
const {default: EasyMDE} = await import(/* webpackChunkName: "easymde" */'easymde');
- const easyMDEOpt = {
+ const easyMDEOpt: EasyMDE.Options = {
autoDownloadFontAwesome: false,
element: this.textarea,
forceSync: true,
@@ -384,19 +395,20 @@ export class ComboMarkdownEditor {
}
get userPreferredEditor() {
- return window.localStorage.getItem(`markdown-editor-${this.options.useScene ?? 'default'}`);
+ return window.localStorage.getItem(`markdown-editor-${this.previewMode ?? 'default'}`);
}
set userPreferredEditor(s) {
- window.localStorage.setItem(`markdown-editor-${this.options.useScene ?? 'default'}`, s);
+ window.localStorage.setItem(`markdown-editor-${this.previewMode ?? 'default'}`, s);
}
}
export function getComboMarkdownEditor(el) {
- if (el instanceof $) el = el[0];
- return el?._giteaComboMarkdownEditor;
+ if (!el) return null;
+ if (el.length) el = el[0];
+ return el._giteaComboMarkdownEditor;
}
-export async function initComboMarkdownEditor(container: HTMLElement, options = {}) {
+export async function initComboMarkdownEditor(container: HTMLElement, options:ComboMarkdownEditorOptions = {}) {
if (!container) {
throw new Error('initComboMarkdownEditor: container is null');
}
diff --git a/web_src/js/features/repo-editor.ts b/web_src/js/features/repo-editor.ts
index 6ea9347eba..adae55f25c 100644
--- a/web_src/js/features/repo-editor.ts
+++ b/web_src/js/features/repo-editor.ts
@@ -201,10 +201,8 @@ export function initRepoEditor() {
})();
}
-export function renderPreviewPanelContent($previewPanel, data) {
- $previewPanel.html(data);
+export function renderPreviewPanelContent(previewPanel: Element, content: string) {
+ previewPanel.innerHTML = content;
initMarkupContent();
-
- const $refIssues = $previewPanel.find('p .ref-issue');
- attachRefIssueContextPopup($refIssues);
+ attachRefIssueContextPopup(previewPanel.querySelectorAll('p .ref-issue'));
}
diff --git a/web_src/js/features/repo-issue.ts b/web_src/js/features/repo-issue.ts
index 9cc478712b..a59e4319ab 100644
--- a/web_src/js/features/repo-issue.ts
+++ b/web_src/js/features/repo-issue.ts
@@ -414,11 +414,6 @@ export function initRepoPullRequestReview() {
await handleReply(this);
});
- const elReviewBox = document.querySelector('.review-box-panel');
- if (elReviewBox) {
- initComboMarkdownEditor(elReviewBox.querySelector('.combo-markdown-editor'));
- }
-
// The following part is only for diff views
if (!$('.repository.pull.diff').length) return;
diff --git a/web_src/js/features/repo-release.ts b/web_src/js/features/repo-release.ts
index 7589c77136..c59ab1f323 100644
--- a/web_src/js/features/repo-release.ts
+++ b/web_src/js/features/repo-release.ts
@@ -1,5 +1,4 @@
import {hideElem, showElem} from '../utils/dom.ts';
-import {initComboMarkdownEditor} from './comp/ComboMarkdownEditor.ts';
export function initRepoRelease() {
document.addEventListener('click', (e) => {
@@ -16,7 +15,6 @@ export function initRepoReleaseNew() {
if (!document.querySelector('.repository.new.release')) return;
initTagNameEditor();
- initRepoReleaseEditor();
}
function initTagNameEditor() {
@@ -48,11 +46,3 @@ function initTagNameEditor() {
hideTargetInput(e.target);
});
}
-
-function initRepoReleaseEditor() {
- const editor = document.querySelector<HTMLElement>('.repository.new.release .combo-markdown-editor');
- if (!editor) {
- return;
- }
- initComboMarkdownEditor(editor);
-}
diff --git a/web_src/js/features/repo-wiki.ts b/web_src/js/features/repo-wiki.ts
index 0e72b87109..69188d6ae2 100644
--- a/web_src/js/features/repo-wiki.ts
+++ b/web_src/js/features/repo-wiki.ts
@@ -2,6 +2,7 @@ import {initMarkupContent} from '../markup/content.ts';
import {validateTextareaNonEmpty, initComboMarkdownEditor} from './comp/ComboMarkdownEditor.ts';
import {fomanticMobileScreen} from '../modules/fomantic.ts';
import {POST} from '../modules/fetch.ts';
+import type {ComboMarkdownEditor} from './comp/ComboMarkdownEditor.ts';
async function initRepoWikiFormEditor() {
const editArea = document.querySelector<HTMLTextAreaElement>('.repository.wiki .combo-markdown-editor textarea');
@@ -9,7 +10,7 @@ async function initRepoWikiFormEditor() {
const form = document.querySelector('.repository.wiki.new .ui.form');
const editorContainer = form.querySelector<HTMLElement>('.combo-markdown-editor');
- let editor;
+ let editor: ComboMarkdownEditor;
let renderRequesting = false;
let lastContent;
@@ -45,12 +46,10 @@ async function initRepoWikiFormEditor() {
renderEasyMDEPreview();
editor = await initComboMarkdownEditor(editorContainer, {
- useScene: 'wiki',
// EasyMDE has some problems of height definition, it has inline style height 300px by default, so we also use inline styles to override it.
// And another benefit is that we only need to write the style once for both editors.
// TODO: Move height style to CSS after EasyMDE removal.
editorHeights: {minHeight: '300px', height: 'calc(100vh - 600px)'},
- previewMode: 'wiki',
easyMDEOptions: {
previewRender: (_content, previewTarget) => previewTarget.innerHTML, // disable builtin preview render
toolbar: ['bold', 'italic', 'strikethrough', '|',
@@ -59,7 +58,7 @@ async function initRepoWikiFormEditor() {
'unordered-list', 'ordered-list', '|',
'link', 'image', 'table', 'horizontal-rule', '|',
'preview', 'fullscreen', 'side-by-side', '|', 'gitea-switch-to-textarea',
- ],
+ ] as any, // to use custom toolbar buttons
},
});
diff --git a/web_src/js/index.ts b/web_src/js/index.ts
index 90e2d29225..48c4b76cee 100644
--- a/web_src/js/index.ts
+++ b/web_src/js/index.ts
@@ -83,7 +83,11 @@ import {
initGlobalButtons,
initGlobalDeleteButton,
} from './features/common-button.ts';
-import {initGlobalEnterQuickSubmit, initGlobalFormDirtyLeaveConfirm} from './features/common-form.ts';
+import {
+ initGlobalComboMarkdownEditor,
+ initGlobalEnterQuickSubmit,
+ initGlobalFormDirtyLeaveConfirm,
+} from './features/common-form.ts';
initGiteaFomantic();
initDirAuto();
@@ -127,6 +131,7 @@ onDomReady(() => {
initGlobalCopyToClipboardListener,
initGlobalEnterQuickSubmit,
initGlobalFormDirtyLeaveConfirm,
+ initGlobalComboMarkdownEditor,
initGlobalDeleteButton,
initCommonOrganization,