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

+3 -3
View File
@@ -15,6 +15,7 @@ import type {ActionsArtifact, ActionsJob, ActionsRun, ActionsStatus} from '../mo
import {AnsiLineRenderer} from '../render/ansi.ts';
import {createLogLineMessage, parseLogLineCommand} from './ActionRunView.ts';
import type {ActionRunViewStore, LogLine, LogLineCommand} from './ActionRunView.ts';
import {registerAsyncHashChangeListener, removeAsyncHashChangeListener} from '../modules/hashchange.ts';
function isLogElementInViewport(el: Element, {extraViewPortHeight} = {extraViewPortHeight: 0}): boolean {
const rect = el.getBoundingClientRect();
@@ -176,13 +177,12 @@ onMounted(async () => {
});
intervalID = setInterval(() => loadJob(), 1000);
hashChangeListener();
window.addEventListener('hashchange', hashChangeListener);
registerAsyncHashChangeListener(hashChangeListener);
});
onBeforeUnmount(() => {
menuTippy.destroy();
window.removeEventListener('hashchange', hashChangeListener);
removeAsyncHashChangeListener(hashChangeListener);
// clear the interval timer when the component is unmounted
// even our page is rendered once, not spa style
if (intervalID) {
+3 -3
View File
@@ -7,6 +7,7 @@ import {diffTreeStore, filterDiffTree, applyFiltersToFileBoxes, extensionFilterT
import {setFileFolding} from '../features/file-fold.ts';
import {onMounted, onUnmounted, computed, watch} from 'vue';
import {localUserSettings} from '../modules/user-settings.ts';
import {registerAsyncHashChangeListener, removeAsyncHashChangeListener} from '../modules/hashchange.ts';
const LOCAL_STORAGE_KEY = 'diff_file_tree_visible';
@@ -28,13 +29,12 @@ onMounted(() => {
// while the tree is hidden there is no control to clear a filter restored from the URL
if (store.fileTreeIsVisible) applyFiltersToFileBoxes(store); else store.activeExtensions = 'all';
document.querySelector('.diff-toggle-file-tree-button')!.addEventListener('click', toggleVisibility);
hashChangeListener();
window.addEventListener('hashchange', hashChangeListener);
registerAsyncHashChangeListener(hashChangeListener);
});
onUnmounted(() => {
document.querySelector('.diff-toggle-file-tree-button')!.removeEventListener('click', toggleVisibility);
window.removeEventListener('hashchange', hashChangeListener);
removeAsyncHashChangeListener(hashChangeListener);
});
function hashChangeListener() {