미디어위키:Common.js
참고: 설정을 저장한 후에 바뀐 점을 확인하기 위해서는 브라우저의 캐시를 새로 고쳐야 합니다.
- 파이어폭스 / 사파리: Shift 키를 누르면서 새로 고침을 클릭하거나, Ctrl-F5 또는 Ctrl-R을 입력 (Mac에서는 ⌘-R)
- 구글 크롬: Ctrl-Shift-R키를 입력 (Mac에서는 ⌘-Shift-R)
- 엣지: Ctrl 키를 누르면서 새로 고침을 클릭하거나, Ctrl-F5를 입력.
mw.loader.using('mediawiki.util', function () {
$(function () {
// Check if the #timetable-indicator span exists
if (document.getElementById('timetable-indicator')) {
// Create a <style> element
var style = document.createElement('style');
style.textContent = `
.Liberty .nav-wrapper .navbar .navbar-brand {
background: transparent
url(/images/2/27/%EC%8B%9C%EA%B0%81%ED%91%9C%EB%A1%9C%EA%B3%A0.svg)
no-repeat left center / auto 1.6em !important;
}
.mw-page-title-namespace::after {
background-color: #ef4137;
}
:root {
--vh-navbar-bg: #ef4137 !important;
}
`;
document.head.appendChild(style);
}
});
});
(function () {
function initStickyBorders(wrap) {
const sticky = wrap.querySelector('#stickyparent');
if (!sticky) return;
function updateStickyWidth() {
const w = sticky.getBoundingClientRect().width;
wrap.style.setProperty('--sticky-w', w + 'px');
}
function updateScrollState() {
const atLeft = wrap.scrollLeft < 5;
wrap.classList.toggle('at-left', atLeft);
wrap.classList.toggle('scrolled', !atLeft); // ← 추가: 왼쪽이 아니면 '띄우기' 상태
}
updateStickyWidth();
updateScrollState();
wrap.addEventListener('scroll', updateScrollState, { passive: true });
window.addEventListener('resize', updateStickyWidth);
if (document.fonts && document.fonts.ready) {
document.fonts.ready.then(updateStickyWidth).catch(function(){});
}
}
document.querySelectorAll('.table-wrap').forEach(initStickyBorders);
})();
(function () {
function unwrapLibertyTable(wrapper) {
if (!wrapper || !wrapper.querySelector('.timetable')) return;
const table = wrapper.querySelector('.timetable');
wrapper.parentNode.insertBefore(table, wrapper);
wrapper.remove();
}
// Remove any that already exist
document.querySelectorAll('.liberty-table-wrapper').forEach(unwrapLibertyTable);
// Watch for new ones being added to the DOM
const observer = new MutationObserver(mutations => {
mutations.forEach(mutation => {
mutation.addedNodes.forEach(node => {
if (!(node instanceof HTMLElement)) return;
if (node.matches('.liberty-table-wrapper') && node.querySelector('.timetable')) {
unwrapLibertyTable(node);
} else if (node.querySelector) {
// If it's a container, check inside it
node.querySelectorAll('.liberty-table-wrapper').forEach(unwrapLibertyTable);
}
});
});
});
observer.observe(document.body, {
childList: true,
subtree: true
});
})();
const gemstoneColors = {
"흙": "#4b4b4b", // Coal - Dark gray
"구리": "#c68346", // Copper - Reddish-brown
"청동": "#547865", // Bronze - Warm brown
"은": "#c0c0c0", // Silver - Metallic silver
"금": "#efbf04", // Gold - Golden yellow
"자수정": "#9966cc", // Amethyst - Purple
"터키석": "#069e80", // Turquoise - Light blue
"가넷": "#9b111e", // Garnet - Deep red
"토파즈": "#f0a641", // Topaz - Golden orange
"페리도트": "#81b11f", // Peridot - Light green
"에메랄드 I": "#39b647", // Emerald - Bright green
"에메랄드 II": "#39b647",// Emerald - Bright green (variant)
"에메랄드 III": "#39b647",// Emerald - Bright green (variant)
"사파이어 I": "#0f52ba", // Sapphire - Rich blue
"사파이어 II": "#0f52ba",// Sapphire - Rich blue (variant)
"사파이어 III": "#0f52ba",// Sapphire - Rich blue (variant)
"루비 I": "#e0115f", // Ruby - Vivid red
"루비 II": "#e0115f", // Ruby - Vivid red (variant)
"루비 III": "#e0115f", // Ruby - Vivid red (variant)
"다이아몬드 I": "#b9fcff", // Diamond - Pale blue/white
"다이아몬드 II": "#b9fcff",// Diamond - Pale blue/white (variant)
"다이아몬드 III": "#b9fcff"
};
// Function to update background color
function updateBackgroundColor() {
const existing = document.querySelector('span.pjcg-hwijang');
const appendafterthis = document.querySelector('.vh-rc');
if (existing) {
const newDiv = document.createElement('div');
newDiv.className = 'vh-sidebar-section';
newDiv.setAttribute(
'style',
`
margin-top: 1rem;
background: url(https://w.halv.kr/images/4/4c/%EC%B2%AD%EA%B4%91%ED%9C%98%EC%9E%A5.png) center no-repeat, light-dark(#fff,#1c1d1f) !important;
background-size: contain !important;
height: 14.5rem !important;
`
);
appendafterthis.insertAdjacentElement('afterend', newDiv);
};
const targetElements = document.querySelectorAll('.vh-rc');
targetElements.forEach((el) => {
el.insertAdjacentHTML(
'beforebegin',
`<a href="https://buymeacoffee.com/halv/">
<div class="vh-sidebar-section" style="
margin-bottom: 1rem;
padding: 0;
height: 90px;
background: url(https://w.halv.kr/images/b/bd/후원처란.png) center no-repeat, light-dark(#fff,#1c1d1f) !important;
background-size: contain !important;
"></div>
</a>`
);
});
const element = document.getElementById("honorific-level");
const leveler = document.getElementById("points-level");
const childElement = leveler.firstElementChild; // Access the first child of leveler
const text = element.textContent.trim().replace(/[()]/g, ""); // Remove parentheses
// Check if the text matches specific diamond levels and update the child element color
if (text === "다이아몬드 I" || text === "다이아몬드 II" || text === "다이아몬드 III") {
leveler.style.background = gemstoneColors[text] || "transparent";
leveler.style.borderColor = "#22636652";
if (childElement) {
childElement.style.color = "#226366cc"; // Set the child element's text color to red
}
} else if (gemstoneColors[text]) {
leveler.style.background = gemstoneColors[text];
leveler.style.borderColor = gemstoneColors[text] + "52";
if (childElement) {
childElement.style.color = ""; // Reset child element's text color
}
} else {
leveler.style.background = "transparent"; // Default if no match
leveler.style.borderColor = "";
if (childElement) {
childElement.style.color = ""; // Reset child element's text color
}
}
}
const head = document.head;
const link3 = document.createElement('link');
link3.rel = 'stylesheet';
link3.href = 'https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@100..900&family=Noto+Serif+KR:wght@300;400;500;700;900&family=Hahmlet:wght@300;400;500;700;900&family=Zen+Kaku+Gothic+Antique:wght@300;400;500;700;900&display=swap';
const link4 = document.createElement('link');
link4.rel = 'stylesheet';
link4.href = 'https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/static/pretendard.min.css';
head.appendChild(link3);
head.appendChild(link4);
function stretchText(el) {
// 1) target width in px from data-max-width (in rem)
const maxWidth =
parseFloat(getComputedStyle(document.documentElement).fontSize) *
parseFloat(el.dataset.maxWidth);
// 2) get the child <span> in a Safari-safe way
const span = (el.querySelector && (el.querySelector(':scope > span') || el.querySelector('span'))) || null;
if (!span) return;
// 3) ensure predictable measuring
const prev = el.style.transform;
el.style.transform = 'translateX(-50%)'; // remove previous scale while measuring
const measure = () => {
// If fonts aren't ready yet, Safari may report 0
const w = span.scrollWidth || span.getBoundingClientRect().width;
if (!w) return requestAnimationFrame(measure);
const scale = maxWidth / w;
el.style.transformOrigin = 'center center';
el.style.transform = `translateX(-50%) scaleX(${scale})`;
el.style.position = 'absolute';
el.style.position = 'absolute';
};
// Wait for fonts/layout in Safari
if (document.fonts && document.fonts.ready) {
document.fonts.ready.then(() => requestAnimationFrame(measure));
} else {
requestAnimationFrame(measure);
}
}
// run once and on resize
const runAll = () => document.querySelectorAll('.stretch-text').forEach(stretchText);
runAll();
addEventListener('resize', runAll);
// Call the function
updateBackgroundColor();
changeTimeColor();