diff options
author | silverwind <me@silverwind.io> | 2024-06-07 15:42:31 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-06-07 13:42:31 +0000 |
commit | 291a00dc570a143092e5ad19cdad12939d3d70dc (patch) | |
tree | a58aff279e223d3897e7b3e757486f04c942f8d9 /web_src/js | |
parent | 15debbbe4eb94c1855a0178e379b7e3d19bd07ad (diff) | |
download | gitea-291a00dc570a143092e5ad19cdad12939d3d70dc.tar.gz gitea-291a00dc570a143092e5ad19cdad12939d3d70dc.zip |
Fix and clean up `ConfirmModal` (#31283)
Bug: orange button color was removed in
https://github.com/go-gitea/gitea/pull/30475, replaced with red
Bug: translation text was not html-escaped
Refactor: Replaced as much jQuery as possible, added useful
`createElementFromHTML`
Refactor: Remove colors checks that don't exist on `.link-action`
<img width="381" alt="image"
src="https://github.com/go-gitea/gitea/assets/115237/5900bf6a-8a86-4a86-b368-0559cbfea66e">
---------
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: delvh <dev.lh@web.de>
Diffstat (limited to 'web_src/js')
-rw-r--r-- | web_src/js/features/common-global.js | 4 | ||||
-rw-r--r-- | web_src/js/features/comp/ConfirmModal.js | 25 | ||||
-rw-r--r-- | web_src/js/features/repo-issue-list.js | 2 | ||||
-rw-r--r-- | web_src/js/utils/dom.js | 7 | ||||
-rw-r--r-- | web_src/js/utils/dom.test.js | 5 |
5 files changed, 28 insertions, 15 deletions
diff --git a/web_src/js/features/common-global.js b/web_src/js/features/common-global.js index 3b021d4485..65eb237dde 100644 --- a/web_src/js/features/common-global.js +++ b/web_src/js/features/common-global.js @@ -295,8 +295,8 @@ async function linkAction(e) { return; } - const isRisky = el.classList.contains('red') || el.classList.contains('yellow') || el.classList.contains('orange') || el.classList.contains('negative'); - if (await confirmModal({content: modalConfirmContent, buttonColor: isRisky ? 'orange' : 'primary'})) { + const isRisky = el.classList.contains('red') || el.classList.contains('negative'); + if (await confirmModal(modalConfirmContent, {confirmButtonColor: isRisky ? 'red' : 'primary'})) { await doRequest(); } } diff --git a/web_src/js/features/comp/ConfirmModal.js b/web_src/js/features/comp/ConfirmModal.js index e64996a352..f9ad5c39cc 100644 --- a/web_src/js/features/comp/ConfirmModal.js +++ b/web_src/js/features/comp/ConfirmModal.js @@ -1,22 +1,23 @@ import $ from 'jquery'; import {svg} from '../../svg.js'; import {htmlEscape} from 'escape-goat'; +import {createElementFromHTML} from '../../utils/dom.js'; const {i18n} = window.config; -export async function confirmModal(opts = {content: '', buttonColor: 'primary'}) { +export function confirmModal(content, {confirmButtonColor = 'primary'} = {}) { return new Promise((resolve) => { - const $modal = $(` -<div class="ui g-modal-confirm modal"> - <div class="content">${htmlEscape(opts.content)}</div> - <div class="actions"> - <button class="ui cancel button">${svg('octicon-x')} ${i18n.modal_cancel}</button> - <button class="ui ${opts.buttonColor || 'primary'} ok button">${svg('octicon-check')} ${i18n.modal_confirm}</button> - </div> -</div> -`); - - $modal.appendTo(document.body); + const modal = createElementFromHTML(` + <div class="ui g-modal-confirm modal"> + <div class="content">${htmlEscape(content)}</div> + <div class="actions"> + <button class="ui cancel button">${svg('octicon-x')} ${htmlEscape(i18n.modal_cancel)}</button> + <button class="ui ${confirmButtonColor} ok button">${svg('octicon-check')} ${htmlEscape(i18n.modal_confirm)}</button> + </div> + </div> + `); + document.body.append(modal); + const $modal = $(modal); $modal.modal({ onApprove() { resolve(true); diff --git a/web_src/js/features/repo-issue-list.js b/web_src/js/features/repo-issue-list.js index 92f058c4d2..5d18a7ff8d 100644 --- a/web_src/js/features/repo-issue-list.js +++ b/web_src/js/features/repo-issue-list.js @@ -76,7 +76,7 @@ function initRepoIssueListCheckboxes() { // for delete if (action === 'delete') { const confirmText = e.target.getAttribute('data-action-delete-confirm'); - if (!await confirmModal({content: confirmText, buttonColor: 'orange'})) { + if (!await confirmModal(confirmText, {confirmButtonColor: 'red'})) { return; } } diff --git a/web_src/js/utils/dom.js b/web_src/js/utils/dom.js index a48510b191..7289f19cbf 100644 --- a/web_src/js/utils/dom.js +++ b/web_src/js/utils/dom.js @@ -297,3 +297,10 @@ export function replaceTextareaSelection(textarea, text) { textarea.dispatchEvent(new CustomEvent('change', {bubbles: true, cancelable: true})); } } + +// Warning: Do not enter any unsanitized variables here +export function createElementFromHTML(htmlString) { + const div = document.createElement('div'); + div.innerHTML = htmlString.trim(); + return div.firstChild; +} diff --git a/web_src/js/utils/dom.test.js b/web_src/js/utils/dom.test.js new file mode 100644 index 0000000000..fd7d97cad5 --- /dev/null +++ b/web_src/js/utils/dom.test.js @@ -0,0 +1,5 @@ +import {createElementFromHTML} from './dom.js'; + +test('createElementFromHTML', () => { + expect(createElementFromHTML('<a>foo<span>bar</span></a>').outerHTML).toEqual('<a>foo<span>bar</span></a>'); +}); |