dikdimon's picture
Upload 4 files
b36697d verified
(function () {
'use strict';
const FIX_TAG = '[a1111-fix]';
const FIX_VERSION = 'v5.2-hardened';
if (window.__a1111_fix_v52_applied) {
console.warn(FIX_TAG, 'already applied, skipping duplicate load');
return;
}
window.__a1111_fix_v52_applied = true;
const wrappedCache = new WeakMap();
const crashLogOnce = new WeakMap();
const slowLogOnce = new WeakMap();
function markWeakOnce(store, callback, kind) {
if (typeof callback !== 'function') return false;
let kinds = store.get(callback);
if (!kinds) {
kinds = new Set();
store.set(callback, kinds);
}
if (kinds.has(kind)) return false;
kinds.add(kind);
return true;
}
function isWrappedForKind(callback, kind) {
return !!(
callback &&
typeof callback === 'function' &&
callback.__a1111_fix_wrapped === true &&
callback.__a1111_fix_kind === kind &&
typeof callback.__a1111_fix_original === 'function'
);
}
function getWrappedCallback(callback, kind, slowThresholdMs) {
if (typeof callback !== 'function') return callback;
if (isWrappedForKind(callback, kind)) return callback;
let sourceCallback = callback;
if (
callback.__a1111_fix_wrapped === true &&
callback.__a1111_fix_kind === kind &&
typeof callback.__a1111_fix_original === 'function'
) {
sourceCallback = callback.__a1111_fix_original;
}
let perKind = wrappedCache.get(sourceCallback);
if (!perKind) {
perKind = Object.create(null);
wrappedCache.set(sourceCallback, perKind);
}
if (perKind[kind]) return perKind[kind];
const wrapped = function (arg) {
const t0 = performance.now();
try {
return sourceCallback(arg);
} catch (e) {
if (markWeakOnce(crashLogOnce, sourceCallback, kind)) {
console.error(FIX_TAG, kind + ' callback crashed:', sourceCallback.name || '(anonymous)', e);
}
} finally {
const elapsed = performance.now() - t0;
if (elapsed > slowThresholdMs && markWeakOnce(slowLogOnce, sourceCallback, kind)) {
console.warn(
FIX_TAG,
'SLOW ' + kind + ': "' + (sourceCallback.name || '(anonymous)') + '" took ' + elapsed.toFixed(0) + 'ms'
);
}
}
};
wrapped.__a1111_fix_wrapped = true;
wrapped.__a1111_fix_original = sourceCallback;
wrapped.__a1111_fix_kind = kind;
perKind[kind] = wrapped;
return wrapped;
}
function wrapQueue(queue, kind, slowThresholdMs) {
if (!Array.isArray(queue)) return 0;
let wrappedCount = 0;
for (let i = 0; i < queue.length; i++) {
if (typeof queue[i] === 'function' && !isWrappedForKind(queue[i], kind)) {
queue[i] = getWrappedCallback(queue[i], kind, slowThresholdMs);
wrappedCount++;
}
}
return wrappedCount;
}
function patchQueuePush(queue, kind, slowThresholdMs) {
if (!Array.isArray(queue) || queue.__a1111_fix_push_patched) return false;
const originalPush = queue.push;
if (typeof originalPush !== 'function') return false;
queue.push = function (...items) {
const wrappedItems = items.map((item) =>
typeof item === 'function' ? getWrappedCallback(item, kind, slowThresholdMs) : item
);
return originalPush.apply(this, wrappedItems);
};
queue.__a1111_fix_push_patched = true;
return true;
}
function safeGradioApp() {
try {
if (typeof window.gradioApp === 'function') {
return window.gradioApp();
}
} catch (e) {
console.warn(FIX_TAG, 'gradioApp() failed while resolving accordion:', e);
}
return document;
}
function applyFix1() {
const originalSchedule = window.scheduleAfterUiUpdateCallbacks;
if (typeof originalSchedule !== 'function' ||
typeof window.executeCallbacks !== 'function' ||
!Array.isArray(window.uiAfterUpdateCallbacks)) {
console.warn(FIX_TAG, 'scheduleAfterUiUpdateCallbacks/executeCallbacks/uiAfterUpdateCallbacks not found, skipping FIX-1');
return;
}
if (originalSchedule.__a1111_fix_afterupdate_patched) {
console.warn(FIX_TAG, 'FIX-1 already patched, skipping duplicate apply');
return;
}
const MAX_WAIT_MS = 1000;
let maxWaitTimer = null;
let running = false;
function clearMaxWaitTimer() {
if (maxWaitTimer) {
clearTimeout(maxWaitTimer);
maxWaitTimer = null;
}
}
function runAfterUpdateNow() {
clearMaxWaitTimer();
const timeoutId = window.uiAfterUpdateTimeout;
if (timeoutId) {
clearTimeout(timeoutId);
window.uiAfterUpdateTimeout = null;
}
if (running) return;
running = true;
try {
if (typeof window.executeCallbacks === 'function') {
window.executeCallbacks(window.uiAfterUpdateCallbacks);
}
} finally {
running = false;
}
}
if (!window.executeCallbacks.__a1111_fix_afterupdate_guard) {
const previousExecuteCallbacks = window.executeCallbacks;
const guardedExecuteCallbacks = function (queue, arg) {
if (queue === window.uiAfterUpdateCallbacks) {
clearMaxWaitTimer();
}
return previousExecuteCallbacks(queue, arg);
};
guardedExecuteCallbacks.__a1111_fix_afterupdate_guard = true;
guardedExecuteCallbacks.__a1111_fix_afterupdate_guard_original = previousExecuteCallbacks;
window.executeCallbacks = guardedExecuteCallbacks;
}
const patchedSchedule = function (...args) {
const result = originalSchedule.apply(this, args);
if (!maxWaitTimer) {
maxWaitTimer = setTimeout(runAfterUpdateNow, MAX_WAIT_MS);
}
return result;
};
patchedSchedule.__a1111_fix_afterupdate_patched = true;
patchedSchedule.__a1111_fix_afterupdate_original = originalSchedule;
window.scheduleAfterUiUpdateCallbacks = patchedSchedule;
console.log(FIX_TAG, 'FIX-1: bounded after-update max-wait=' + MAX_WAIT_MS + 'ms applied (wrapper mode)');
}
function applyFix2() {
const configs = [
{ queueName: 'uiLoadedCallbacks', registerName: 'onUiLoaded', slowThresholdMs: 100 },
{ queueName: 'uiAfterUpdateCallbacks', registerName: 'onAfterUiUpdate', slowThresholdMs: 100 },
{ queueName: 'uiUpdateCallbacks', registerName: 'onUiUpdate', slowThresholdMs: 50 },
{ queueName: 'optionsChangedCallbacks', registerName: 'onOptionsChanged', slowThresholdMs: 50 },
{ queueName: 'optionsAvailableCallbacks', registerName: 'onOptionsAvailable', slowThresholdMs: 50 },
{ queueName: 'uiTabChangeCallbacks', registerName: 'onUiTabChange', slowThresholdMs: 50 },
];
const activeConfigs = [];
const summary = [];
for (const cfg of configs) {
const queue = window[cfg.queueName];
const register = window[cfg.registerName];
if (!Array.isArray(queue) || typeof register !== 'function') {
continue;
}
const existingCount = wrapQueue(queue, cfg.registerName, cfg.slowThresholdMs);
patchQueuePush(queue, cfg.registerName, cfg.slowThresholdMs);
if (!register.__a1111_fix_register_patched) {
const originalRegister = register;
const patchedRegister = function (callback) {
return originalRegister(getWrappedCallback(callback, cfg.registerName, cfg.slowThresholdMs));
};
patchedRegister.__a1111_fix_register_patched = true;
patchedRegister.__a1111_fix_register_original = originalRegister;
window[cfg.registerName] = patchedRegister;
}
activeConfigs.push(cfg);
summary.push(cfg.registerName + '=' + existingCount);
}
if (activeConfigs.length === 0) {
console.warn(FIX_TAG, 'no callback queues found, skipping FIX-2');
return;
}
if (typeof window.executeCallbacks === 'function' && !window.executeCallbacks.__a1111_fix_patched) {
const originalExecuteCallbacks = window.executeCallbacks;
const patchedExecuteCallbacks = function (queue, arg) {
for (const cfg of activeConfigs) {
if (queue === window[cfg.queueName]) {
wrapQueue(queue, cfg.registerName, cfg.slowThresholdMs);
break;
}
}
return originalExecuteCallbacks(queue, arg);
};
patchedExecuteCallbacks.__a1111_fix_patched = true;
patchedExecuteCallbacks.__a1111_fix_original = originalExecuteCallbacks;
window.executeCallbacks = patchedExecuteCallbacks;
}
console.log(FIX_TAG, 'FIX-2: callback guards applied to', summary.join(', '));
}
function applyFix3() {
if (typeof window.inputAccordionChecked !== 'function') {
console.warn(FIX_TAG, 'inputAccordionChecked not found, skipping FIX-3');
return;
}
const warnedOnce = new Set();
function isRealAccordion(el) {
return !!(
el &&
el.visibleCheckbox instanceof HTMLInputElement &&
typeof el.onVisibleCheckboxChange === 'function'
);
}
function resolveRealAccordion(id) {
const app = safeGradioApp();
const direct = app.getElementById ? app.getElementById(id) : null;
if (isRealAccordion(direct)) return direct;
const dotted = app.getElementById ? app.getElementById('.' + id) : null;
if (isRealAccordion(dotted)) return dotted;
if (direct && typeof direct.querySelector === 'function') {
const nestedCheckbox = direct.querySelector('.input-accordion-checkbox');
if (nestedCheckbox) {
const parentAccordion = nestedCheckbox.closest('.input-accordion');
if (isRealAccordion(parentAccordion)) return parentAccordion;
}
}
return null;
}
window.inputAccordionChecked = function (id, checked) {
const realEl = resolveRealAccordion(id);
if (!realEl) {
if (!warnedOnce.has(id)) {
warnedOnce.add(id);
const app = safeGradioApp();
const direct = app.getElementById ? app.getElementById(id) : null;
const dotted = app.getElementById ? app.getElementById('.' + id) : null;
console.error(
FIX_TAG, 'FIX-3: cannot resolve accordion for id:', id,
'\n direct el:', direct,
'\n direct.visibleCheckbox:', direct && direct.visibleCheckbox,
'\n direct.visibleCheckbox instanceof HTMLInputElement:',
direct && (direct.visibleCheckbox instanceof HTMLInputElement),
'\n dotted el:', dotted
);
}
return;
}
realEl.visibleCheckbox.checked = checked;
realEl.onVisibleCheckboxChange();
};
console.log(FIX_TAG, 'FIX-3: resilient accordion resolver applied');
}
function applyFix4() {
window.__a1111ScriptRegistry = window.__a1111ScriptRegistry || {
mode: 'unknown',
scripts: {},
loaded: {},
errors: {},
injected_order: [],
};
function registerScriptElement(el) {
if (!el || el.tagName !== 'SCRIPT') return;
if (typeof window.__a1111RegisterScript === 'function') {
window.__a1111RegisterScript(el);
return;
}
const src = el.getAttribute('src') || '';
window.__a1111ScriptRegistry.scripts[src] = {
role: el.getAttribute('data-a1111-role') || 'unknown',
mode: el.getAttribute('data-a1111-mode') || 'unknown',
path: el.getAttribute('data-a1111-path') || src,
basedir: el.getAttribute('data-a1111-basedir') || '',
};
if (!window.__a1111ScriptRegistry.injected_order.includes(src)) {
window.__a1111ScriptRegistry.injected_order.push(src);
}
}
window.addEventListener('error', function (event) {
const target = event && event.target;
if (target && target.tagName === 'SCRIPT') {
registerScriptElement(target);
const src = target.getAttribute('src') || '';
window.__a1111ScriptRegistry.errors[src] = true;
return;
}
const filename = event && event.filename;
if (filename) {
console.error(FIX_TAG, 'window error from script:', filename, event.error || event.message || event);
}
}, true);
window.addEventListener('unhandledrejection', function (event) {
console.error(FIX_TAG, 'unhandled promise rejection:', event.reason || event);
});
function summarizeRegistry() {
const registry = window.__a1111ScriptRegistry || {};
const scripts = registry.scripts || {};
const loaded = registry.loaded || {};
const errors = registry.errors || {};
const order = registry.injected_order || [];
const ok = [];
const failed = [];
const pending = [];
for (const src of order.length ? order : Object.keys(scripts)) {
const meta = scripts[src] || {};
const item = {
src,
role: meta.role || 'unknown',
mode: meta.mode || 'unknown',
path: meta.path || src,
};
if (errors[src]) {
failed.push(item);
} else if (loaded[src]) {
ok.push(item);
} else {
pending.push(item);
}
}
return { ok, failed, pending, mode: registry.mode || 'unknown' };
}
function summarizeCallbacks() {
const groups = [
['uiLoadedCallbacks', 'onUiLoaded'],
['uiAfterUpdateCallbacks', 'onAfterUiUpdate'],
['uiUpdateCallbacks', 'onUiUpdate'],
['optionsChangedCallbacks', 'onOptionsChanged'],
['optionsAvailableCallbacks', 'onOptionsAvailable'],
['uiTabChangeCallbacks', 'onUiTabChange'],
];
return groups.map(([queueName, registerName]) => {
const queue = window[queueName];
return {
queue: queueName,
register: registerName,
present: Array.isArray(queue),
count: Array.isArray(queue) ? queue.length : 0,
};
});
}
window.__a1111FixReport = function () {
const report = summarizeRegistry();
const callbacks = summarizeCallbacks();
console.log(FIX_TAG, 'loader mode =', report.mode);
console.log(FIX_TAG, 'loaded scripts =', report.ok.length, 'failed =', report.failed.length, 'pending =', report.pending.length);
console.table(callbacks);
if (report.failed.length) {
console.warn(FIX_TAG, 'failed scripts:');
console.table(report.failed);
}
if (report.pending.length) {
console.warn(FIX_TAG, 'pending/unconfirmed scripts:');
console.table(report.pending);
}
if (!report.failed.length && !report.pending.length) {
console.log(FIX_TAG, 'all tracked scripts loaded cleanly');
}
return { ...report, callbacks };
};
window.addEventListener('load', function () {
setTimeout(function () {
const report = window.__a1111FixReport();
if (report.failed.length || report.pending.length) {
console.warn(FIX_TAG, 'FIX-4: loader diagnostics detected script issues; inspect __a1111FixReport() output');
}
}, 1500);
}, { once: true });
console.log(FIX_TAG, 'FIX-4: loader diagnostics ready');
}
applyFix1();
applyFix2();
applyFix3();
applyFix4();
console.log(FIX_TAG, FIX_VERSION, 'ready');
})();