Skip to content

Commit 41e8b83

Browse files
silverwindlafrikstechknowlogick
authored
Markdown task list improvements (#13952)
* Markdown task list improvements - Remove `.ui` class and wrappers to prevent fomantic from messing with it. - Change rendered HTML to match GitHub. - Add custom styling for the checkboxes. * fix unittest Co-authored-by: Lauris BH <[email protected]> Co-authored-by: techknowlogick <[email protected]>
1 parent 287b594 commit 41e8b83

File tree

5 files changed

+60
-16
lines changed

5 files changed

+60
-16
lines changed

modules/markup/markdown/goldmark.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -357,9 +357,9 @@ func (r *HTMLRenderer) renderTaskCheckBoxListItem(w util.BufWriter, source []byt
357357
}
358358
var err error
359359
if n.IsChecked {
360-
_, err = w.WriteString(`<span class="ui checked checkbox"><input type="checkbox" checked="" readonly="readonly"` + end + `<label>`)
360+
_, err = w.WriteString(`<input type="checkbox" disabled="" checked=""` + end)
361361
} else {
362-
_, err = w.WriteString(`<span class="ui checkbox"><input type="checkbox" readonly="readonly"` + end + `<label>`)
362+
_, err = w.WriteString(`<input type="checkbox" disabled=""` + end)
363363
}
364364
if err != nil {
365365
return ast.WalkStop, err
@@ -371,7 +371,7 @@ func (r *HTMLRenderer) renderTaskCheckBoxListItem(w util.BufWriter, source []byt
371371
}
372372
}
373373
} else {
374-
_, _ = w.WriteString("</label></span></li>\n")
374+
_, _ = w.WriteString("</li>\n")
375375
}
376376
return ast.WalkContinue, nil
377377
}

modules/markup/markdown/markdown_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -142,9 +142,9 @@ func testAnswers(baseURLContent, baseURLImages string) []string {
142142
<p>(from <a href="https://www.markdownguide.org/extended-syntax/" rel="nofollow">https://www.markdownguide.org/extended-syntax/</a>)</p>
143143
<h3 id="user-content-checkboxes">Checkboxes</h3>
144144
<ul>
145-
<li class="task-list-item"><span class="ui checkbox"><input type="checkbox" readonly="readonly"/><label>unchecked</label></span></li>
146-
<li class="task-list-item"><span class="ui checked checkbox"><input type="checkbox" checked="" readonly="readonly"/><label>checked</label></span></li>
147-
<li class="task-list-item"><span class="ui checkbox"><input type="checkbox" readonly="readonly"/><label>still unchecked</label></span></li>
145+
<li class="task-list-item"><input type="checkbox" disabled=""/>unchecked</li>
146+
<li class="task-list-item"><input type="checkbox" disabled="" checked=""/>checked</li>
147+
<li class="task-list-item"><input type="checkbox" disabled=""/>still unchecked</li>
148148
</ul>
149149
<h3 id="user-content-definition-list">Definition list</h3>
150150
<dl>

modules/markup/sanitizer.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ func ReplaceSanitizer() {
4343

4444
// Checkboxes
4545
sanitizer.policy.AllowAttrs("type").Matching(regexp.MustCompile(`^checkbox$`)).OnElements("input")
46-
sanitizer.policy.AllowAttrs("checked", "disabled", "readonly").OnElements("input")
46+
sanitizer.policy.AllowAttrs("checked", "disabled").OnElements("input")
4747

4848
// Custom URL-Schemes
4949
sanitizer.policy.AllowURLSchemes(setting.Markdown.CustomURLSchemes...)
@@ -66,8 +66,8 @@ func ReplaceSanitizer() {
6666
// Allow classes for emojis
6767
sanitizer.policy.AllowAttrs("class").Matching(regexp.MustCompile(`emoji`)).OnElements("img")
6868

69-
// Allow icons, checkboxes, emojis, and chroma syntax on span
70-
sanitizer.policy.AllowAttrs("class").Matching(regexp.MustCompile(`^((icon(\s+[\p{L}\p{N}_-]+)+)|(ui checkbox)|(ui checked checkbox)|(emoji))$|^([a-z][a-z0-9]{0,2})$`)).OnElements("span")
69+
// Allow icons, emojis, and chroma syntax on span
70+
sanitizer.policy.AllowAttrs("class").Matching(regexp.MustCompile(`^((icon(\s+[\p{L}\p{N}_-]+)+)|(emoji))$|^([a-z][a-z0-9]{0,2})$`)).OnElements("span")
7171

7272
// Allow generally safe attributes
7373
generalSafeAttrs := []string{"abbr", "accept", "accept-charset",

modules/markup/sanitizer_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ func Test_Sanitizer(t *testing.T) {
4040
`<kbd>Ctrl + C</kbd>`, `<kbd>Ctrl + C</kbd>`,
4141
`<i class="dropdown icon">NAUGHTY</i>`, `<i>NAUGHTY</i>`,
4242
`<i class="icon dropdown"></i>`, `<i class="icon dropdown"></i>`,
43-
`<span class="ui checkbox"><input type="checkbox" readonly="readonly"/><label>unchecked</label></span>`, `<span class="ui checkbox"><input type="checkbox" readonly="readonly"/><label>unchecked</label></span>`,
43+
`<input type="checkbox" disabled=""/>unchecked`, `<input type="checkbox" disabled=""/>unchecked`,
4444
`<span class="emoji dropdown">NAUGHTY</span>`, `<span>NAUGHTY</span>`,
4545
`<span class="emoji">contents</span>`, `<span class="emoji">contents</span>`,
4646
}

web_src/less/_markdown.less

Lines changed: 50 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -162,9 +162,57 @@
162162
list-style-type: none;
163163
}
164164

165-
li.task-list-item {
165+
.task-list-item {
166166
list-style-type: none;
167-
margin-left: calc(-2em + 2px);
167+
168+
input[type="checkbox"] {
169+
margin: 0 6px .25em -1.6em;
170+
}
171+
}
172+
173+
.task-list-item + .task-list-item {
174+
margin-top: 3px;
175+
}
176+
177+
input[type="checkbox"] {
178+
-webkit-appearance: none;
179+
-moz-appearance: none;
180+
appearance: none;
181+
position: relative;
182+
border: 1px solid var(--color-secondary);
183+
border-radius: 2px;
184+
background: var(--color-input-background);
185+
height: 14px;
186+
width: 14px;
187+
opacity: 1 !important; // override fomantic on edit preview
188+
pointer-events: auto !important; // override fomantic on edit preview
189+
vertical-align: middle !important; // override fomantic on edit preview
190+
}
191+
192+
input[type="checkbox"]:not([disabled]):hover,
193+
input[type="checkbox"]:not([disabled]):active {
194+
border-color: var(--color-primary);
195+
}
196+
197+
input[type="checkbox"]::after {
198+
position: absolute;
199+
left: 0;
200+
top: 0;
201+
bottom: 0;
202+
right: 0;
203+
pointer-events: none;
204+
background: var(--color-text);
205+
mask-size: cover;
206+
}
207+
208+
input[type="checkbox"]:checked::after {
209+
content: "";
210+
mask-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="-1 -1 18 18" width="16" height="16"><path fill-rule="evenodd" d="M13.78 4.22a.75.75 0 010 1.06l-7.25 7.25a.75.75 0 01-1.06 0L2.22 9.28a.75.75 0 011.06-1.06L6 10.94l6.72-6.72a.75.75 0 011.06 0z"></path></svg>');
211+
}
212+
213+
input[type="checkbox"]:indeterminate::after {
214+
content: "";
215+
mask-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M2 7.75A.75.75 0 012.75 7h10a.75.75 0 010 1.5h-10A.75.75 0 012 7.75z"></path></svg>');
168216
}
169217

170218
ul ul,
@@ -422,10 +470,6 @@
422470
box-shadow: inset 0 -1px 0 var(--color-secondary);
423471
}
424472

425-
input[type="checkbox"] {
426-
vertical-align: middle !important;
427-
}
428-
429473
.csv-data td,
430474
.csv-data th {
431475
padding: 5px;

0 commit comments

Comments
 (0)