미디어위키:Common.js: 두 판 사이의 차이
편집 요약 없음 |
편집 요약 없음 |
||
| (같은 사용자의 중간 판 472개는 보이지 않습니다) | |||
| 1번째 줄: | 1번째 줄: | ||
/ | mw.loader.using('mediawiki.util', function () { | ||
$(function () { | |||
// Check if the #timetable-indicator span exists | |||
if (document.getElementById('timetable-indicator')) { | |||
const logo = document.querySelector('img.vh-logo'); | |||
logo.src = 'https://w.halv.kr/images/2/27/시각표로고.svg'; | |||
// Create a <style> element | |||
var style = document.createElement('style'); | |||
style.textContent = ` | |||
img.vh-logo { | |||
height: 2rem !important; | |||
} | |||
mw | .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(); | |||
2026년 1월 4일 (일) 19:25 기준 최신판
mw.loader.using('mediawiki.util', function () {
$(function () {
// Check if the #timetable-indicator span exists
if (document.getElementById('timetable-indicator')) {
const logo = document.querySelector('img.vh-logo');
logo.src = 'https://w.halv.kr/images/2/27/시각표로고.svg';
// Create a <style> element
var style = document.createElement('style');
style.textContent = `
img.vh-logo {
height: 2rem !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();