* Add test Signed-off-by: Andrew Thornton <art27@cantab.net> * Restore checkbox rendering and prevent poor sanitization of spans Signed-off-by: Andrew Thornton <art27@cantab.net> * Also fix preview context Signed-off-by: Andrew Thornton <art27@cantab.net> * Also fix preview context Signed-off-by: Andrew Thornton <art27@cantab.net>tags/v1.21.12.1
| @@ -140,6 +140,12 @@ func testAnswers(baseURLContent, baseURLImages string) []string { | |||||
| </ol> | </ol> | ||||
| <h2 id="user-content-custom-id">More tests</h2> | <h2 id="user-content-custom-id">More tests</h2> | ||||
| <p>(from <a href="https://www.markdownguide.org/extended-syntax/" rel="nofollow">https://www.markdownguide.org/extended-syntax/</a>)</p> | <p>(from <a href="https://www.markdownguide.org/extended-syntax/" rel="nofollow">https://www.markdownguide.org/extended-syntax/</a>)</p> | ||||
| <h3 id="user-content-checkboxes">Checkboxes</h3> | |||||
| <ul class="task-list"> | |||||
| <li><span class="ui checkbox"><input type="checkbox" readonly="readonly"/><label>unchecked</label></span></li> | |||||
| <li><span class="ui checked checkbox"><input type="checkbox" checked="" readonly="readonly"/><label>checked</label></span></li> | |||||
| <li><span class="ui checkbox"><input type="checkbox" readonly="readonly"/><label>still unchecked</label></span></li> | |||||
| </ul> | |||||
| <h3 id="user-content-definition-list">Definition list</h3> | <h3 id="user-content-definition-list">Definition list</h3> | ||||
| <dl> | <dl> | ||||
| <dt>First Term</dt> | <dt>First Term</dt> | ||||
| @@ -207,6 +213,12 @@ Here are some links to the most important topics. You can find the full list of | |||||
| (from https://www.markdownguide.org/extended-syntax/) | (from https://www.markdownguide.org/extended-syntax/) | ||||
| ### Checkboxes | |||||
| - [ ] unchecked | |||||
| - [x] checked | |||||
| - [ ] still unchecked | |||||
| ### Definition list | ### Definition list | ||||
| First Term | First Term | ||||
| @@ -58,15 +58,16 @@ func ReplaceSanitizer() { | |||||
| // Allow icons | // Allow icons | ||||
| sanitizer.policy.AllowAttrs("class").Matching(regexp.MustCompile(`^icon(\s+[\p{L}\p{N}_-]+)+$`)).OnElements("i") | sanitizer.policy.AllowAttrs("class").Matching(regexp.MustCompile(`^icon(\s+[\p{L}\p{N}_-]+)+$`)).OnElements("i") | ||||
| sanitizer.policy.AllowAttrs("class").Matching(regexp.MustCompile(`^((icon(\s+[\p{L}\p{N}_-]+)+)|(ui checkbox)|(ui checked checkbox))$`)).OnElements("span") | |||||
| // Allow unlabelled labels | // Allow unlabelled labels | ||||
| sanitizer.policy.AllowNoAttrs().OnElements("label") | sanitizer.policy.AllowNoAttrs().OnElements("label") | ||||
| // Allow classes for emojis | // Allow classes for emojis | ||||
| sanitizer.policy.AllowAttrs("class").Matching(regexp.MustCompile(`emoji`)).OnElements("span") | |||||
| sanitizer.policy.AllowAttrs("class").Matching(regexp.MustCompile(`emoji`)).OnElements("img") | sanitizer.policy.AllowAttrs("class").Matching(regexp.MustCompile(`emoji`)).OnElements("img") | ||||
| // Allow icons, checkboxes and emojis on span | |||||
| sanitizer.policy.AllowAttrs("class").Matching(regexp.MustCompile(`^((icon(\s+[\p{L}\p{N}_-]+)+)|(ui checkbox)|(ui checked checkbox)|(emoji))$`)).OnElements("span") | |||||
| // Allow generally safe attributes | // Allow generally safe attributes | ||||
| generalSafeAttrs := []string{"abbr", "accept", "accept-charset", | generalSafeAttrs := []string{"abbr", "accept", "accept-charset", | ||||
| "accesskey", "action", "align", "alt", | "accesskey", "action", "align", "alt", | ||||
| @@ -38,6 +38,11 @@ func Test_Sanitizer(t *testing.T) { | |||||
| // <kbd> tags | // <kbd> tags | ||||
| `<kbd>Ctrl + C</kbd>`, `<kbd>Ctrl + C</kbd>`, | `<kbd>Ctrl + C</kbd>`, `<kbd>Ctrl + C</kbd>`, | ||||
| `<i class="dropdown icon">NAUGHTY</i>`, `<i>NAUGHTY</i>`, | |||||
| `<i class="icon dropdown"></i>`, `<i class="icon dropdown"></i>`, | |||||
| `<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>`, | |||||
| `<span class="emoji dropdown">NAUGHTY</span>`, `<span>NAUGHTY</span>`, | |||||
| `<span class="emoji">contents</span>`, `<span class="emoji">contents</span>`, | |||||
| } | } | ||||
| for i := 0; i < len(testCases); i += 2 { | for i := 0; i < len(testCases); i += 2 { | ||||
| @@ -65,7 +65,7 @@ function initEditPreviewTab($form) { | |||||
| previewFileModes = $previewTab.data('preview-file-modes').split(','); | previewFileModes = $previewTab.data('preview-file-modes').split(','); | ||||
| $previewTab.on('click', function () { | $previewTab.on('click', function () { | ||||
| const $this = $(this); | const $this = $(this); | ||||
| let context = `{$this.data('context')}/`; | |||||
| let context = `${$this.data('context')}/`; | |||||
| const treePathEl = $form.find('input#tree_path'); | const treePathEl = $form.find('input#tree_path'); | ||||
| if (treePathEl.length > 0) { | if (treePathEl.length > 0) { | ||||
| context += treePathEl.val(); | context += treePathEl.val(); | ||||