chore: refactor legacy JS init code to use "data-global-init" (#39836)

Move the remaining legacy init code, which probed page classes with
`querySelector`, to `data-global-init`, so each feature initializes from
its own element. `hashchange` listeners now go through one module that
runs them in priority order, because independent listeners broke when
mount order changed.

- Convert issue list, diff, repo create, settings and org team inits to
`data-global-init`
- Run `hashchange` listeners by priority, the diff scroll handler last
- Make the devtest mock's failing log requests deterministic
- Add e2e tests for diff tree navigation to folded files and job log
permalinks

---------

Co-authored-by: silverwind <me@silverwind.io>
This commit is contained in:
wxiaoguangandsilverwind authored and GitHub committed 2026-10-18 13:59:51 +00:00
1 parent ae17c14cff
commit f690ea8efd
26 files changed
+122 -125

No files matched your search

+19 -7
View File
@@ -1,6 +1,6 @@
import {createApp} from 'vue';
import DiffFileTree from '../components/DiffFileTree.vue';
import {initRepoIssueContentHistory} from './repo-issue-content.ts';
import {initDiffFileTree} from './repo-diff-filetree.ts';
import {initDiffCommitSelect} from './repo-diff-commitselect.ts';
import {validateTextareaNonEmpty} from './comp/ComboMarkdownEditor.ts';
import {initExpandAndCollapseFilesButton, initDiffFileViewedForm} from './pull-view-file.ts';
import {showErrorToast} from '../modules/toast.ts';
@@ -12,8 +12,10 @@ import {invertFileFolding} from './file-fold.ts';
import {parseDom} from '../utils.ts';
import {registerGlobalEventFunc, registerGlobalInitFunc} from '../modules/observer.ts';
import {performFetchActionTrigger} from '../modules/fetch-action.ts';
import {applyFiltersToFileBoxes, diffTreeStore} from '../modules/diff-file.ts';
import {applyFiltersToFileBoxes, type DiffFileTreeLocale, diffTreeStore} from '../modules/diff-file.ts';
import {initImageDiff} from './imagediff.ts';
import DiffCommitSelector from '../components/DiffCommitSelector.vue';
import {registerAsyncHashChangeListener} from '../modules/hashchange.ts';
function initDiffFileViewToggle(el: HTMLElement) {
// switch between "rendered" and "source", for image and CSV files
@@ -245,6 +247,15 @@ async function onLocationHashChange() {
}
}
function initDiffFileTree(el: HTMLElement) {
const locale = JSON.parse(el.getAttribute('data-locale')!) as DiffFileTreeLocale;
createApp(DiffFileTree, {locale}).mount(el);
}
function initDiffCommitSelect(el: HTMLElement) {
createApp(DiffCommitSelector).mount(el);
}
export function initRepoDiffView() {
initRepoDiffConversationForm(); // such form appears on the "conversation" page and "diff" page
registerGlobalEventFunc('click', 'diffLoadMoreFiles', (el) => { diffLoadMoreFiles(el) });
@@ -254,13 +265,14 @@ export function initRepoDiffView() {
registerGlobalInitFunc('initDiffFileViewedForm', initDiffFileViewedForm);
registerGlobalInitFunc('initDiffFileImageDiff', initImageDiff);
registerGlobalInitFunc('initDiffFileViewToggle', initDiffFileViewToggle);
registerGlobalInitFunc('initDiffFileTree', initDiffFileTree);
registerGlobalInitFunc('initDiffCommitSelect', initDiffCommitSelect);
if (!document.querySelector('#diff-file-boxes')) return;
initRepoDiffConversationNav(); // "previous" and "next" buttons only appear on "diff" page
initDiffFileTree();
initDiffCommitSelect();
initExpandAndCollapseFilesButton();
window.addEventListener('hashchange', onLocationHashChange);
onLocationHashChange();
// onLocationHashChange does very complicated things (e.g.: load incomplete content and scroll), and it might change the URL hash
// so make it run after all other hash change listeners
registerAsyncHashChangeListener(onLocationHashChange, 999);
}