mirror of
https://github.com/ranaldsgift/KefinTweaks.git
synced 2026-11-05 15:52:47 +01:00
Update resolution of kefinTweaksUrl for KefinTweaks-Injector JS Injector script
This commit is contained in:
1 parent
d6ad82cba9
commit
1b77c6f0f7
4 files changed
+123
-40
No files matched your search
+3
-1
@@ -1190,7 +1190,9 @@
|
||||
console.log('[KefinTweaks Injector] Jellyfin major version:', majorVersion ?? 'unknown');
|
||||
|
||||
const config = window.KefinTweaksConfig || {};
|
||||
const root = Loader.normalizeRoot(config.kefinTweaksRoot || '');
|
||||
const root = Loader.getResolvedKefinRoot
|
||||
? Loader.getResolvedKefinRoot(config)
|
||||
: Loader.normalizeRoot(config.kefinTweaksRoot || '');
|
||||
|
||||
try {
|
||||
const plan = Loader.buildLoadPlan(config, majorVersion, {
|
||||
|
||||
+28
-5
@@ -205,7 +205,8 @@ window.KefinTweaksConfig = ${JSON.stringify(config, null, 2)};`;
|
||||
let injectorScriptContent = null;
|
||||
try {
|
||||
const rootRaw = config.kefinTweaksRoot || '';
|
||||
const root = rootRaw.endsWith('/') ? rootRaw : rootRaw + '/';
|
||||
const resolvedRaw = config.kefinTweaksRootResolved || rootRaw;
|
||||
const root = resolvedRaw.endsWith('/') ? resolvedRaw : resolvedRaw + '/';
|
||||
if (root && root !== '/') {
|
||||
await loadKefinTweaksLoaderFromRoot(root);
|
||||
const Loader = window.KefinTweaksLoader;
|
||||
@@ -217,8 +218,11 @@ window.KefinTweaksConfig = ${JSON.stringify(config, null, 2)};`;
|
||||
} catch (e) {
|
||||
console.warn('[KefinTweaks Installer] Could not resolve Jellyfin major for injector bake:', e);
|
||||
}
|
||||
const planRoot = Loader.getResolvedKefinRoot
|
||||
? Loader.getResolvedKefinRoot(config)
|
||||
: root;
|
||||
const plan = Loader.buildLoadPlan(config, major, {
|
||||
root,
|
||||
root: planRoot,
|
||||
configOnly: config.enabled === false
|
||||
});
|
||||
injectorScriptContent = Loader.buildInjectorScript(plan);
|
||||
@@ -334,8 +338,20 @@ window.KefinTweaksConfig = ${JSON.stringify(config, null, 2)};`;
|
||||
}
|
||||
|
||||
try {
|
||||
const root = rootRaw.endsWith('/') ? rootRaw : rootRaw + '/';
|
||||
await loadKefinTweaksLoaderFromRoot(root);
|
||||
const normalize = (r) => {
|
||||
if (!r || typeof r !== 'string') return '';
|
||||
return r.endsWith('/') ? r : r + '/';
|
||||
};
|
||||
|
||||
const expected = normalize(await resolveRootVersion(rootRaw));
|
||||
const current = normalize(config.kefinTweaksRootResolved || '');
|
||||
if (!current || current !== expected) {
|
||||
config.kefinTweaksRootResolved = expected;
|
||||
console.log('[KefinTweaks Installer] Updated kefinTweaksRootResolved:', current || '(none)', '->', expected);
|
||||
}
|
||||
|
||||
const loadRoot = normalize(config.kefinTweaksRootResolved || rootRaw);
|
||||
await loadKefinTweaksLoaderFromRoot(loadRoot);
|
||||
const Loader = window.KefinTweaksLoader;
|
||||
if (!Loader) {
|
||||
return { ok: false, reason: 'KefinTweaksLoader unavailable' };
|
||||
@@ -349,8 +365,9 @@ window.KefinTweaksConfig = ${JSON.stringify(config, null, 2)};`;
|
||||
console.warn('[KefinTweaks Installer] Could not resolve Jellyfin major for auto-create:', e);
|
||||
}
|
||||
|
||||
const resolvedRoot = Loader.getResolvedKefinRoot(config);
|
||||
const plan = Loader.buildLoadPlan(config, major, {
|
||||
root,
|
||||
root: resolvedRoot,
|
||||
configOnly: config.enabled === false
|
||||
});
|
||||
const injectorScriptContent = Loader.buildInjectorScript(plan);
|
||||
@@ -898,6 +915,10 @@ window.KefinTweaksConfig = ${JSON.stringify(config, null, 2)};`;
|
||||
}
|
||||
|
||||
const kefinTweaksRoot = buildKefinTweaksRootUrl(sourceType, source);
|
||||
const kefinTweaksRootResolvedRaw = await resolveRootVersion(kefinTweaksRoot);
|
||||
const kefinTweaksRootResolved = kefinTweaksRootResolvedRaw.endsWith('/')
|
||||
? kefinTweaksRootResolvedRaw
|
||||
: kefinTweaksRootResolvedRaw + '/';
|
||||
|
||||
// Load default config from the selected root
|
||||
let defaultConfig;
|
||||
@@ -908,6 +929,7 @@ window.KefinTweaksConfig = ${JSON.stringify(config, null, 2)};`;
|
||||
// Create minimal config if loading fails
|
||||
defaultConfig = {
|
||||
kefinTweaksRoot: kefinTweaksRoot,
|
||||
kefinTweaksRootResolved: kefinTweaksRootResolved,
|
||||
enabled: true,
|
||||
scripts: {},
|
||||
exclusiveElsewhere: {},
|
||||
@@ -929,6 +951,7 @@ window.KefinTweaksConfig = ${JSON.stringify(config, null, 2)};`;
|
||||
kefinTweaksRoot: kefinTweaksRoot,
|
||||
...(currentConfig || {}),
|
||||
kefinTweaksRoot: kefinTweaksRoot, // Ensure root is updated
|
||||
kefinTweaksRootResolved: kefinTweaksRootResolved,
|
||||
enabled: enabledState // Update enabled state
|
||||
};
|
||||
|
||||
|
||||
@@ -641,6 +641,14 @@
|
||||
return root.endsWith('/') ? root : root + '/';
|
||||
}
|
||||
|
||||
/**
|
||||
* Prefer kefinTweaksRootResolved (commit SHA / verified URL); fall back to symbolic kefinTweaksRoot.
|
||||
*/
|
||||
function getResolvedKefinRoot(config) {
|
||||
const cfg = config || {};
|
||||
return normalizeRoot(cfg.kefinTweaksRootResolved || cfg.kefinTweaksRoot || '');
|
||||
}
|
||||
|
||||
function resolveAssetUrl(root, relativePath) {
|
||||
if (!relativePath) return null;
|
||||
if (/^https?:\/\//i.test(relativePath)) return relativePath;
|
||||
@@ -677,26 +685,29 @@
|
||||
function expandScriptToAssets(scriptDef, root, urlSuffix, thirdParty) {
|
||||
const assets = [];
|
||||
const suffix = urlSuffix || '';
|
||||
const pushRel = (kind, relativePath, name) => {
|
||||
if (!relativePath) return;
|
||||
if (/^https?:\/\//i.test(relativePath)) {
|
||||
assets.push({ kind: kind, url: relativePath, name: name });
|
||||
return;
|
||||
}
|
||||
const url = resolveAssetUrl(root, relativePath);
|
||||
if (!url) return;
|
||||
assets.push({
|
||||
kind: kind,
|
||||
url: url + suffix,
|
||||
path: relativePath,
|
||||
name: name
|
||||
});
|
||||
};
|
||||
for (const tpName of scriptDef.thirdParty || []) {
|
||||
const tp = thirdParty[tpName];
|
||||
if (!tp) continue;
|
||||
(tp.css || []).forEach((css) => {
|
||||
const url = resolveAssetUrl(root, css);
|
||||
if (url) assets.push({ kind: 'css', url: url + (/^https?:/i.test(css) ? '' : suffix), name: tpName });
|
||||
});
|
||||
(tp.js || []).forEach((js) => {
|
||||
const url = resolveAssetUrl(root, js);
|
||||
if (url) assets.push({ kind: 'js', url: url + (/^https?:/i.test(js) ? '' : suffix), name: tpName });
|
||||
});
|
||||
}
|
||||
if (scriptDef.css) {
|
||||
const url = resolveAssetUrl(root, scriptDef.css);
|
||||
if (url) assets.push({ kind: 'css', url: url + suffix, name: scriptDef.name });
|
||||
}
|
||||
if (scriptDef.script) {
|
||||
const url = resolveAssetUrl(root, scriptDef.script);
|
||||
if (url) assets.push({ kind: 'js', url: url + suffix, name: scriptDef.name });
|
||||
(tp.css || []).forEach((css) => pushRel('css', css, tpName));
|
||||
(tp.js || []).forEach((js) => pushRel('js', js, tpName));
|
||||
}
|
||||
if (scriptDef.css) pushRel('css', scriptDef.css, scriptDef.name);
|
||||
if (scriptDef.script) pushRel('js', scriptDef.script, scriptDef.name);
|
||||
return assets;
|
||||
}
|
||||
|
||||
@@ -742,7 +753,11 @@
|
||||
|
||||
function buildLoadPlan(config, majorVersion, options) {
|
||||
options = options || {};
|
||||
const root = normalizeRoot(options.root || (config && config.kefinTweaksRoot) || '');
|
||||
const root = normalizeRoot(
|
||||
options.root
|
||||
|| getResolvedKefinRoot(config)
|
||||
|| ''
|
||||
);
|
||||
if (!root) throw new Error('kefinTweaksRoot is required to build load plan');
|
||||
const urlSuffix = options.urlSuffix || '';
|
||||
const byName = definitionsByName();
|
||||
@@ -764,7 +779,7 @@
|
||||
const seen = new Set();
|
||||
const pushAssets = (list) => {
|
||||
list.forEach((a) => {
|
||||
const key = a.kind + '|' + a.url;
|
||||
const key = a.kind + '|' + (a.url || a.path || '');
|
||||
if (seen.has(key)) return;
|
||||
seen.add(key);
|
||||
assets.push(a);
|
||||
@@ -778,8 +793,18 @@
|
||||
});
|
||||
|
||||
pushAssets([
|
||||
{ kind: 'css', url: resolveAssetUrl(root, CONFIGURATION_FILES.css) + urlSuffix, name: 'configuration' },
|
||||
{ kind: 'js', url: resolveAssetUrl(root, CONFIGURATION_FILES.script) + urlSuffix, name: 'configuration' }
|
||||
{
|
||||
kind: 'css',
|
||||
url: resolveAssetUrl(root, CONFIGURATION_FILES.css) + urlSuffix,
|
||||
path: CONFIGURATION_FILES.css,
|
||||
name: 'configuration'
|
||||
},
|
||||
{
|
||||
kind: 'js',
|
||||
url: resolveAssetUrl(root, CONFIGURATION_FILES.script) + urlSuffix,
|
||||
path: CONFIGURATION_FILES.script,
|
||||
name: 'configuration'
|
||||
}
|
||||
]);
|
||||
|
||||
const stamp = [
|
||||
@@ -907,7 +932,22 @@
|
||||
}
|
||||
|
||||
function buildInjectorScript(loadPlan) {
|
||||
const assetsJson = JSON.stringify(loadPlan.assets || []);
|
||||
// Bake relative paths (and absolute http urls); join with resolved root at runtime
|
||||
const bakeAssets = (loadPlan.assets || []).map((a) => {
|
||||
if (!a) return null;
|
||||
if (a.url && /^https?:\/\//i.test(a.url) && !a.path) {
|
||||
return { kind: a.kind, url: a.url, name: a.name };
|
||||
}
|
||||
if (a.path) {
|
||||
return { kind: a.kind, path: a.path, name: a.name };
|
||||
}
|
||||
if (a.url) {
|
||||
return { kind: a.kind, url: a.url, name: a.name };
|
||||
}
|
||||
return null;
|
||||
}).filter(Boolean);
|
||||
|
||||
const assetsJson = JSON.stringify(bakeAssets);
|
||||
const defsJson = JSON.stringify(loadPlan.definitions || SCRIPT_DEFINITIONS);
|
||||
const stamp = loadPlan.stamp || '';
|
||||
const stampJson = JSON.stringify(stamp);
|
||||
@@ -916,11 +956,22 @@
|
||||
'// kefinTweaksInjectorStamp=' + stamp,
|
||||
'(function () {',
|
||||
' if (window.KefinTweaksScriptsPreloaded) return;',
|
||||
' var root = (window.KefinTweaksConfig && window.KefinTweaksConfig.kefinTweaksRoot) || \'\';',
|
||||
' var isExperimental = /@experimental(\\/|$)/i.test(String(root));',
|
||||
' var isOfficialCdn = /cdn\\.jsdelivr\\.net\\/gh\\/ranaldsgift\\/KefinTweaks@/i.test(String(root));',
|
||||
' if (!String(root).trim()) return;',
|
||||
' var cfg = window.KefinTweaksConfig || {};',
|
||||
' if (cfg.enabled !== true) return;',
|
||||
' var symbolicRoot = cfg.kefinTweaksRoot || \'\';',
|
||||
' var isExperimental = /@experimental(\\/|$)/i.test(String(symbolicRoot));',
|
||||
' var isOfficialCdn = /cdn\\.jsdelivr\\.net\\/gh\\/ranaldsgift\\/KefinTweaks@/i.test(String(symbolicRoot));',
|
||||
' if (!String(symbolicRoot).trim()) return;',
|
||||
' if (!isExperimental && isOfficialCdn) return;',
|
||||
' var resolvedRoot = String(cfg.kefinTweaksRootResolved || cfg.kefinTweaksRoot || \'\').trim();',
|
||||
' if (!resolvedRoot) return;',
|
||||
' if (resolvedRoot.charAt(resolvedRoot.length - 1) !== \'/\') resolvedRoot += \'/\';',
|
||||
' function joinAssetUrl(relativePath) {',
|
||||
' if (!relativePath) return null;',
|
||||
' if (/^https?:\\/\\//i.test(relativePath)) return relativePath;',
|
||||
' var base = resolvedRoot + \'scripts/\';',
|
||||
' try { return new URL(relativePath, base).href; } catch (e) { return base + relativePath; }',
|
||||
' }',
|
||||
' window.KefinTweaksScriptsPreloaded = true;',
|
||||
' window.KefinTweaksInjectorStamp = ' + stampJson + ';',
|
||||
' var SCRIPT_DEFINITIONS_BAKED = ' + defsJson + ';',
|
||||
@@ -972,18 +1023,20 @@
|
||||
' var assets = ' + assetsJson + ';',
|
||||
' for (var i = 0; i < assets.length; i++) {',
|
||||
' var a = assets[i];',
|
||||
' if (!a || !a.url) continue;',
|
||||
' if (!a) continue;',
|
||||
' var href = a.url || joinAssetUrl(a.path);',
|
||||
' if (!href) continue;',
|
||||
' if (a.kind === \'css\') {',
|
||||
' if (document.querySelector(\'link[href="\' + a.url + \'"]\')) continue;',
|
||||
' if (document.querySelector(\'link[href="\' + href + \'"]\')) continue;',
|
||||
' var l = document.createElement(\'link\');',
|
||||
' l.rel = \'stylesheet\';',
|
||||
' l.type = \'text/css\';',
|
||||
' l.href = a.url;',
|
||||
' l.href = href;',
|
||||
' document.head.appendChild(l);',
|
||||
' } else {',
|
||||
' if (document.querySelector(\'script[src="\' + a.url + \'"]\')) continue;',
|
||||
' if (document.querySelector(\'script[src="\' + href + \'"]\')) continue;',
|
||||
' var s = document.createElement(\'script\');',
|
||||
' s.src = a.url;',
|
||||
' s.src = href;',
|
||||
' s.async = false;',
|
||||
' document.head.appendChild(s);',
|
||||
' }',
|
||||
@@ -1183,6 +1236,7 @@
|
||||
isScriptCompatible: isScriptCompatible,
|
||||
mergeEnabledScripts: mergeEnabledScripts,
|
||||
normalizeRoot: normalizeRoot,
|
||||
getResolvedKefinRoot: getResolvedKefinRoot,
|
||||
resolveAssetUrl: resolveAssetUrl,
|
||||
buildLoadPlan: buildLoadPlan,
|
||||
buildInjectorScript: buildInjectorScript,
|
||||
|
||||
+8
-4
@@ -2213,9 +2213,10 @@ window.KefinTweaksConfig = ${JSON.stringify(configToSave, null, 2)};`;
|
||||
// Build / refresh KefinTweaks-injector preload entry (same POST)
|
||||
let injectorScriptContent = null;
|
||||
try {
|
||||
const root = (configToSave.kefinTweaksRoot || '').endsWith('/')
|
||||
? configToSave.kefinTweaksRoot
|
||||
: (configToSave.kefinTweaksRoot || '') + '/';
|
||||
const resolvedOrSymbolic = configToSave.kefinTweaksRootResolved || configToSave.kefinTweaksRoot || '';
|
||||
const root = resolvedOrSymbolic.endsWith('/')
|
||||
? resolvedOrSymbolic
|
||||
: resolvedOrSymbolic + '/';
|
||||
if (root && root !== '/') {
|
||||
if (!window.KefinTweaksLoader) {
|
||||
await new Promise((resolve, reject) => {
|
||||
@@ -2237,8 +2238,11 @@ window.KefinTweaksConfig = ${JSON.stringify(configToSave, null, 2)};`;
|
||||
if (Loader) {
|
||||
Loader.ensureKefinTweaksApi(Loader.SCRIPT_DEFINITIONS);
|
||||
const major = await window.KefinTweaks.getJellyfinMajorVersion();
|
||||
const planRoot = Loader.getResolvedKefinRoot
|
||||
? Loader.getResolvedKefinRoot(configToSave)
|
||||
: root;
|
||||
const plan = Loader.buildLoadPlan(configToSave, major, {
|
||||
root,
|
||||
root: planRoot,
|
||||
configOnly: configToSave.enabled === false
|
||||
});
|
||||
injectorScriptContent = Loader.buildInjectorScript(plan);
|
||||
|
||||
Reference in new issue
Block a user