mirror of
https://github.com/go-gitea/gitea.git
synced 2026-10-12 15:14:13 +00:00
feat: global shortcut support (#39604)
* Fix #5796 Global shortcuts can be easily introduced by adding "data-shortcut-keys" to the elements --------- Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
This commit is contained in:
1 parent
9b1d6f47f1
commit
4cba1e18ed
10 files changed
+374
-67
No files matched your search
@@ -16,7 +16,6 @@ let i18nTextDeleteFromHistoryConfirm: string;
|
||||
function showContentHistoryDetail(issueBaseUrl: string, commentId: string, historyId: string, itemTitleHtml: string) {
|
||||
const elDetailDialog = createElementFromHTML(html`
|
||||
<div class="ui modal content-history-detail-dialog">
|
||||
${svgRaw('octicon-x', 16, 'close icon inside')}
|
||||
<div class="header flex-left-right">
|
||||
<div>${htmlRaw(itemTitleHtml)}</div>
|
||||
<div class="ui dropdown dialog-header-options tw-mr-8 tw-hidden">
|
||||
@@ -26,6 +25,7 @@ function showContentHistoryDetail(issueBaseUrl: string, commentId: string, histo
|
||||
<div class="item tw-text-red" data-option-item="delete">${i18nTextDeleteFromHistory}</div>
|
||||
</div>
|
||||
</div>
|
||||
${svgRaw('octicon-x', 16, 'close-modal')}
|
||||
</div>
|
||||
<div class="comment-diff-data is-loading"></div>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
import {tryShortcutQuoteReply} from './repo-issue-edit.ts';
|
||||
|
||||
test('tryShortcutQuoteReply', () => {
|
||||
const container = document.createElement('div');
|
||||
container.innerHTML = `
|
||||
<div class="comment-container">
|
||||
<button class="quote-reply">Quote reply</button>
|
||||
<div class="render-content markup">Comment text</div>
|
||||
<div class="raw-content">Raw text</div>
|
||||
</div>
|
||||
`;
|
||||
document.body.append(container);
|
||||
const selection = window.getSelection()!;
|
||||
onTestFinished(() => {
|
||||
selection.removeAllRanges();
|
||||
container.remove();
|
||||
});
|
||||
const button = container.querySelector('button')!;
|
||||
const onClick = vi.fn();
|
||||
button.addEventListener('click', onClick);
|
||||
|
||||
selection.removeAllRanges();
|
||||
expect(tryShortcutQuoteReply()).toBe(false);
|
||||
|
||||
selection.selectAllChildren(container.querySelector('.raw-content')!);
|
||||
expect(tryShortcutQuoteReply()).toBe(false);
|
||||
|
||||
const range = document.createRange();
|
||||
range.selectNodeContents(container.querySelector('.render-content')!.firstChild!);
|
||||
selection.removeAllRanges();
|
||||
selection.addRange(range);
|
||||
selection.collapseToStart();
|
||||
expect(tryShortcutQuoteReply()).toBe(false);
|
||||
expect(onClick).not.toHaveBeenCalled();
|
||||
|
||||
selection.removeAllRanges();
|
||||
selection.addRange(range);
|
||||
expect(tryShortcutQuoteReply()).toBe(true);
|
||||
expect(onClick).toHaveBeenCalledTimes(1);
|
||||
|
||||
button.remove();
|
||||
expect(tryShortcutQuoteReply()).toBe(false);
|
||||
});
|
||||
@@ -7,6 +7,7 @@ import {errorMessage} from '../modules/errors.ts';
|
||||
import {triggerUploadStateChanged} from './comp/EditorUpload.ts';
|
||||
import {convertHtmlToMarkdown} from '../markup/html2markdown.ts';
|
||||
import {applyAreYouSure} from '../modules/are-you-sure.ts';
|
||||
import {registerShortcutHandler} from '../modules/shortcut.ts';
|
||||
|
||||
async function tryOnEditContent(e: Event) {
|
||||
const clickTarget = (e.target as HTMLElement).closest('.edit-content');
|
||||
@@ -150,9 +151,32 @@ async function tryOnQuoteReply(e: Event) {
|
||||
editor.moveCursorToEnd();
|
||||
}
|
||||
|
||||
export function tryShortcutQuoteReply(): boolean {
|
||||
const selection = window.getSelection();
|
||||
if (!selection?.rangeCount || selection.isCollapsed) return false;
|
||||
const node = selection.getRangeAt(0).commonAncestorContainer;
|
||||
const el = node instanceof HTMLElement ? node : node.parentElement;
|
||||
|
||||
const commentContainer = el?.closest<HTMLElement>('.render-content.markup')?.closest('.comment-container');
|
||||
if (!commentContainer) return false;
|
||||
|
||||
const quoteReplyBtn = commentContainer.querySelector<HTMLElement>('.quote-reply')!;
|
||||
if (!quoteReplyBtn) return false;
|
||||
|
||||
quoteReplyBtn.click();
|
||||
return true;
|
||||
}
|
||||
|
||||
export function initRepoIssueCommentEdit() {
|
||||
document.addEventListener('click', (e) => {
|
||||
tryOnEditContent(e); // Edit issue or comment content
|
||||
tryOnQuoteReply(e); // Quote reply to the comment editor
|
||||
});
|
||||
// TODO: it is not list in the shortcut help modal at the moment, there are many details:
|
||||
// 1. not every page supports such "r"
|
||||
// 2. "r" only works when there is a ".quote-reply" menu item, but it is not for a single one
|
||||
// To make the framework fully support such mechanism correctly, we might also need to consider about dynamically added elements.
|
||||
// The shortcut "r" was chosen by https://github.com/go-gitea/gitea/issues/5796#issuecomment-5528657082
|
||||
// and GitLab: https://gitlab.com/gitlab-org/gitlab-foss/-/commit/ca5d0c82509cedb94f9bfa4a40e77706a58faafe
|
||||
registerShortcutHandler('r', tryShortcutQuoteReply);
|
||||
}
|
||||
Reference in new issue
Block a user