Difference between revisions of "MediaWiki:Timeless.js"
From Medivia Online Wiki
| (4 intermediate revisions by the same user not shown) | |||
| Line 1: | Line 1: | ||
(function () { | (function () { | ||
function normalizeToFileTitle(val) { | function normalizeRoot(root) { | ||
if (root && (root.nodeType === 1 || root.nodeType === 9) && typeof root.querySelector === "function") { | |||
val = val.trim(); | return root; | ||
if (!val) | } | ||
return document; | |||
} | |||
function normalizeToFileTitle(val) { | |||
if (!val) return ""; | |||
val = ("" + val).trim(); | |||
if (!val) return ""; | |||
// Handle full wikilink formats: | |||
// [[File:Name.png]] | |||
// [[File:Name.png|...]] | |||
// [[Image:Name.png]] (alias) | |||
// Strip trailing ]] / leading [[ if someone pastes partial | |||
val = val.replace(/^\[\[\s*/, "").replace(/\s*\]\]$/, ""); | |||
// If still contains pipe, keep left side | |||
if (val.includes("|")) val = val.split("|")[0].trim(); | |||
// Convert Image: to File: | |||
val = val.replace(/^Image:/i, "File:"); | |||
// Ensure File: | |||
if (!/^File:/i.test(val)) val = "File:" + val.trim(); | |||
return val; | |||
} | |||
function fileTitleToThumbUrl(fileTitle) { | function fileTitleToThumbUrl(fileTitle) { | ||
var name = fileTitle.replace(/^File:/i, ""); | var name = fileTitle.replace(/^File:/i, ""); | ||
return mw.util.getUrl("Special:Redirect/file/" + name) + "?width=64"; | return mw.util.getUrl("Special:Redirect/file/" + name) + "?width=64"; | ||
} | } | ||
function | function ensurePreviewDiv(input) { | ||
var existing = document.getElementById("pf-image-preview"); | |||
if (existing) return existing; | |||
var div = document.createElement("div"); | |||
div.id = "pf-image-preview"; | |||
div.style.width = "64px"; | |||
div.style.height = "64px"; | |||
div.style.border = "1px solid #333"; | |||
div.style.marginTop = "6px"; | |||
div.style.display = "flex"; | |||
div.style.alignItems = "center"; | |||
div.style.justifyContent = "center"; | |||
div.style.fontSize = "11px"; | |||
div.style.textAlign = "center"; | |||
div.style.backgroundRepeat = "no-repeat"; | |||
div.style.backgroundPosition = "center"; | |||
div.style.backgroundSize = "contain"; | |||
div.style.color = "#aaa"; | |||
div.textContent = "No image"; | |||
input.parentNode.appendChild(div); | |||
return div; | |||
} | |||
function hookItemImagePreview(root) { | |||
root = normalizeRoot(root); | |||
var input = root.querySelector("input.pf-item-image"); | |||
if (!input) return; | |||
var | var preview = ensurePreviewDiv(input); | ||
function update() { | function update() { | ||
var fileTitle = normalizeToFileTitle(input.value); | var fileTitle = normalizeToFileTitle(input.value); | ||
if (!fileTitle) { | if (!fileTitle) { | ||
preview.style.backgroundImage = ""; | |||
preview.textContent = "No image"; | |||
return; | return; | ||
} | } | ||
var url = fileTitleToThumbUrl(fileTitle); | var url = fileTitleToThumbUrl(fileTitle); | ||
// Test image existence using background image load trick | |||
var test = new Image(); | |||
test.onload = function () { | |||
preview.style.backgroundImage = "url('" + url + "')"; | |||
preview.textContent = ""; | |||
}; | }; | ||
test.onerror = function () { | |||
preview.style.backgroundImage = ""; | |||
preview.textContent = "Not found"; | |||
}; | }; | ||
test.src = url; | |||
} | } | ||
input.addEventListener("input", update); | input.addEventListener("input", update); | ||
input.addEventListener("change", update); | input.addEventListener("change", update); | ||
update(); | |||
} | |||
function run(root) { | |||
setTimeout(function () { hookItemImagePreview(root); }, 150); | |||
setTimeout(function () { hookItemImagePreview(root); }, 600); | |||
} | } | ||
mw.hook("wikipage.content").add(function () { | if (window.mw && mw.hook) { | ||
mw.hook("wikipage.content").add(run); | |||
} | |||
document.addEventListener("DOMContentLoaded", function () { | |||
run(document); | |||
}); | }); | ||
})(); | })(); | ||
Latest revision as of 20:33, 17 January 2026
(function () {
function normalizeRoot(root) {
if (root && (root.nodeType === 1 || root.nodeType === 9) && typeof root.querySelector === "function") {
return root;
}
return document;
}
function normalizeToFileTitle(val) {
if (!val) return "";
val = ("" + val).trim();
if (!val) return "";
// Handle full wikilink formats:
// [[File:Name.png]]
// [[File:Name.png|...]]
// [[Image:Name.png]] (alias)
// Strip trailing ]] / leading [[ if someone pastes partial
val = val.replace(/^\[\[\s*/, "").replace(/\s*\]\]$/, "");
// If still contains pipe, keep left side
if (val.includes("|")) val = val.split("|")[0].trim();
// Convert Image: to File:
val = val.replace(/^Image:/i, "File:");
// Ensure File:
if (!/^File:/i.test(val)) val = "File:" + val.trim();
return val;
}
function fileTitleToThumbUrl(fileTitle) {
var name = fileTitle.replace(/^File:/i, "");
return mw.util.getUrl("Special:Redirect/file/" + name) + "?width=64";
}
function ensurePreviewDiv(input) {
var existing = document.getElementById("pf-image-preview");
if (existing) return existing;
var div = document.createElement("div");
div.id = "pf-image-preview";
div.style.width = "64px";
div.style.height = "64px";
div.style.border = "1px solid #333";
div.style.marginTop = "6px";
div.style.display = "flex";
div.style.alignItems = "center";
div.style.justifyContent = "center";
div.style.fontSize = "11px";
div.style.textAlign = "center";
div.style.backgroundRepeat = "no-repeat";
div.style.backgroundPosition = "center";
div.style.backgroundSize = "contain";
div.style.color = "#aaa";
div.textContent = "No image";
input.parentNode.appendChild(div);
return div;
}
function hookItemImagePreview(root) {
root = normalizeRoot(root);
var input = root.querySelector("input.pf-item-image");
if (!input) return;
var preview = ensurePreviewDiv(input);
function update() {
var fileTitle = normalizeToFileTitle(input.value);
if (!fileTitle) {
preview.style.backgroundImage = "";
preview.textContent = "No image";
return;
}
var url = fileTitleToThumbUrl(fileTitle);
// Test image existence using background image load trick
var test = new Image();
test.onload = function () {
preview.style.backgroundImage = "url('" + url + "')";
preview.textContent = "";
};
test.onerror = function () {
preview.style.backgroundImage = "";
preview.textContent = "Not found";
};
test.src = url;
}
input.addEventListener("input", update);
input.addEventListener("change", update);
update();
}
function run(root) {
setTimeout(function () { hookItemImagePreview(root); }, 150);
setTimeout(function () { hookItemImagePreview(root); }, 600);
}
if (window.mw && mw.hook) {
mw.hook("wikipage.content").add(run);
}
document.addEventListener("DOMContentLoaded", function () {
run(document);
});
})();