최근 바뀜
도구
업로드
도움말
길라잡이
위키 문법
특수 문서
문의·신고
디스코드
IP 사용자
216.73.216.32
로그인
미디어위키:Common.js 문서 원본 보기
←
미디어위키:Common.js
편집
토론
역사
새로고침
주시
역링크
정보
문서 편집 권한이 없습니다. 다음 이유를 확인해주세요:
요청한 명령은 다음 권한을 가진 사용자에게 제한됩니다:
사용자
.
이 문서는 이 위키의 소프트웨어 인터페이스에 쓰이는 문서로, 부정 행위를 막기 위해 보호되어 있습니다. 모든 위키에 대한 번역을 추가하거나 바꾸려면 미디어위키 지역화 프로젝트인
translatewiki.net
에 참여하시기 바랍니다.
모든 방문자에게 영향을 미칠 수 있기 때문에 이 자바스크립트 문서의 편집 권한이 없습니다.
문서의 원본을 보거나 복사할 수 있습니다.
/** * 이 스크립트는 위키백과 전체에 적용됩니다. 고칠 때는 주의해주세요. * [[위키백과:위키프로젝트 시스템]] 참고 * * 스크립트를 넣을 때는 충분한 설명, 출처를 넣어주세요! 이후 관리가 어려워집니다. **/ (function () { "use strict"; function initAll() { var scrollers = document.querySelectorAll('.tt-scroller'); for (var i = 0; i < scrollers.length; i++) { var table = scrollers[i].querySelector('table.timetable[data-sticky-cols]:not([data-fixed-ready="1"])'); if (table) initOne(scrollers[i], table); } } function initOne(scroller, table) { var freeze = parseInt(table.getAttribute('data-sticky-cols') || '0', 10); if (!freeze || isNaN(freeze) || freeze <= 0) return; table.setAttribute('data-fixed-ready', '1'); // 왼쪽 복제용 컨테이너 생성 var fixedWrap = document.createElement('div'); fixedWrap.className = 'tt-fixed-left'; scroller.appendChild(fixedWrap); var fixedShadow = document.createElement('div'); fixedShadow.className = 'tt-fixed-left-shadow'; fixedWrap.appendChild(fixedShadow); // 테이블 복제 var fixedTable = table.cloneNode(true); fixedTable.removeAttribute('data-fixed-ready'); // 자기 자신 중복 방지 fixedWrap.appendChild(fixedTable); // 그리드 인덱스(시작 열) 계산: rowspan/colspan 고려 assignGridColStarts(table); assignGridColStarts(fixedTable); // 복제 테이블에서는 freeze 이후 열을 제거 stripColumns(fixedTable, freeze, /*keepLeft=*/true); // 본 테이블에서는 고정 열의 내용만 숨기기(레이아웃 유지) hideLeftCells(table, freeze); // 최초 레이아웃 계산 및 동기화 layout(); // 관찰 및 갱신 var ro = (typeof ResizeObserver !== "undefined") ? new ResizeObserver(function () { layout(); }) : null; if (ro) { ro.observe(table); ro.observe(fixedTable); ro.observe(scroller); } if (document.fonts && document.fonts.ready && typeof document.fonts.ready.then === "function") { document.fonts.ready.then(function () { layout(); }); } var pending = null; window.addEventListener('resize', function () { if (pending) cancelAnimationFrame(pending); pending = requestAnimationFrame(function () { layout(); }); }); // 동적으로 행 높이 달라질 수 있으므로(줄바꿈 등) 약간의 지연 후 재정렬 setTimeout(layout, 0); function layout() { // 행 높이 동기화 syncRowHeights(table, fixedTable); // freeze 폭 측정(실측 좌표 기반) var frozenWidth = measureFrozenWidth(table, freeze, scroller); // 고정 래퍼 폭/높이 적용 fixedWrap.style.width = frozenWidth + 'px'; fixedWrap.style.height = table.getBoundingClientRect().height + 'px'; // 그림자 위치 업데이트 fixedShadow.style.left = (frozenWidth - 1) + 'px'; // 초기 가시영역을 고정열 다음으로 이동 if (!scroller.__tt_initialized) { scroller.scrollLeft = Math.round(frozenWidth); scroller.__tt_initialized = true; } // 고정 테이블을 본 테이블과 정확히 겹치도록 좌표 보정 var base = table.getBoundingClientRect().top - scroller.getBoundingClientRect().top; fixedWrap.style.top = Math.round(base + scroller.scrollTop) + 'px'; } // 수직 스크롤(있다면) 동기화 scroller.addEventListener('scroll', function () { // 수평 스크롤은 본문만, 수직 스크롤은 두 테이블이 동일하게 보여야 함 fixedWrap.style.transform = 'translateY(' + (-scroller.scrollTop) + 'px)'; }); } // --- 유틸들 --- function assignGridColStarts(tbl) { var rows = Array.prototype.slice.call(tbl.rows); var occ = []; for (var r = 0; r < rows.length; r++) { var tr = rows[r]; if (!occ[r]) occ[r] = []; var cIndex = 0; while (occ[r][cIndex]) cIndex++; var cells = Array.prototype.slice.call(tr.cells); for (var j = 0; j < cells.length; j++) { var cell = cells[j]; while (occ[r][cIndex]) cIndex++; var colspan = Math.max(1, cell.colSpan || 1); var rowspan = Math.max(1, cell.rowSpan || 1); // mark future rows occupied for (var rr = 1; rr < rowspan; rr++) { var rf = r + rr; if (!occ[rf]) occ[rf] = []; for (var cc = 0; cc < colspan; cc++) occ[rf][cIndex + cc] = true; } cell.setAttribute('data-grid-col-start', String(cIndex)); cIndex += colspan; } } } function stripColumns(tbl, freeze, keepLeft) { var rows = Array.prototype.slice.call(tbl.rows); for (var r = 0; r < rows.length; r++) { var cells = Array.prototype.slice.call(rows[r].cells); for (var j = cells.length - 1; j >= 0; j--) { var cell = cells[j]; var start = parseInt(cell.getAttribute('data-grid-col-start') || '0', 10); var colspan = Math.max(1, cell.colSpan || 1); // 셀이 경계를 가로지르면 양쪽으로 나눠야 하지만, // 고정 테이블에서는 "왼쪽에 걸친 부분만" 남기고 오른쪽은 버립니다. // (본문 테이블이 레이아웃을 유지하므로 시각적으로 문제 없음) if (keepLeft) { if (start >= freeze) { cell.parentNode.removeChild(cell); } else if (start + colspan > freeze) { // 경계 걸침: 고정 테이블에서는 freeze - start 만큼만 보유 cell.colSpan = freeze - start; } } } } } function hideLeftCells(tbl, freeze) { var rows = Array.prototype.slice.call(tbl.rows); for (var r = 0; r < rows.length; r++) { var cells = Array.prototype.slice.call(rows[r].cells); for (var j = 0; j < cells.length; j++) { var cell = cells[j]; var start = parseInt(cell.getAttribute('data-grid-col-start') || '0', 10); var colspan = Math.max(1, cell.colSpan || 1); if (start < freeze) { // 경계 걸침 셀은 오른쪽 부분이 본문 영역에 남으므로 숨기면 안 됨. // -> 경계 이전(완전히 왼쪽)인 셀만 숨김 if (start + colspan <= freeze) { cell.classList.add('tt-hidden-cell'); } } } } } function measureFrozenWidth(tbl, freeze, scroller) { // 스크롤러 content-box 기준 좌표로 측정(분수 테두리 대응) var rectS = scroller.getBoundingClientRect(); var cs = window.getComputedStyle(scroller); var borderL = parseFloat(cs.borderLeftWidth) || 0; var padL = parseFloat(cs.paddingLeft) || 0; var contentLeft = rectS.left + borderL + padL; // 각 시작열의 최소 left 기록 var rows = Array.prototype.slice.call(tbl.rows); var lefts = []; var i, r, j; for (i = 0; i < freeze; i++) lefts[i] = Infinity; for (r = 0; r < rows.length; r++) { var cells = Array.prototype.slice.call(rows[r].cells); for (j = 0; j < cells.length; j++) { var cell = cells[j]; var start = parseInt(cell.getAttribute('data-grid-col-start') || '0', 10); if (start < freeze) { var rect = cell.getBoundingClientRect(); var leftIn = (rect.left - contentLeft) + scroller.scrollLeft; if (leftIn < lefts[start]) lefts[start] = leftIn; } } } // freeze 구간의 폭 = freeze 시작열의 좌표 중 최소값과, freeze 경계 직전의 마지막 열의 오른쪽까지 // 오른쪽 끝 좌표도 실측 var right = 0; for (r = 0; r < rows.length; r++) { var cells2 = Array.prototype.slice.call(rows[r].cells); for (j = 0; j < cells2.length; j++) { var cell2 = cells2[j]; var start2 = parseInt(cell2.getAttribute('data-grid-col-start') || '0', 10); var colspan2 = Math.max(1, cell2.colSpan || 1); if (start2 < freeze) { var rect2 = cell2.getBoundingClientRect(); var leftIn2 = (rect2.left - contentLeft) + scroller.scrollLeft; var width2 = rect2.width; // border-spacing까지 포함한 실제 너비 var rEdge = leftIn2 + width2; if (rEdge > right) right = rEdge; } } } // 첫 열의 기준점을 0으로 리베이스 var base = (isFinite(lefts[0]) ? lefts[0] : 0); var width = Math.max(0, right - base); // 반픽셀 제거 var dpr = window.devicePixelRatio || 1; width = Math.round(width * dpr) / dpr; return width; } function syncRowHeights(mainTable, fixedTable) { var mr = Array.prototype.slice.call(mainTable.rows); var fr = Array.prototype.slice.call(fixedTable.rows); var count = Math.min(mr.length, fr.length); for (var i = 0; i < count; i++) { // 초기화 mr[i].style.height = ''; fr[i].style.height = ''; // 둘 중 큰 값으로 맞춤 var mh = mr[i].getBoundingClientRect().height; var fh = fr[i].getBoundingClientRect().height; var h = Math.max(mh, fh); mr[i].style.height = h + 'px'; fr[i].style.height = h + 'px'; } } if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', initAll); } else { initAll(); } // 동적 삽입 시 재실행 훅 window.reflowTimetableFixedColumns = initAll; })(); mw.loader.using( ['mediawiki.util', 'mediawiki.notify', 'jquery.client'], function () { /* Begin of mw.loader.using callback */ /** * Map addPortletLink to mw.util * * @deprecated: Use mw.util.addPortletLink instead. */ mw.log.deprecate( window, 'addPortletLink', mw.util.addPortletLink, 'Use mw.util.addPortletLink instead' ); /** * Extract a URL parameter from the current URL * * @deprecated: Use mw.util.getParamValue with proper escaping */ mw.log.deprecate( window, 'getURLParamValue', mw.util.getParamValue, 'Use mw.util.getParamValue instead' ); /** * Test if an element has a certain class * * @deprecated: Use $(element).hasClass() instead. */ mw.log.deprecate( window, 'hasClass', function ( element, className ) { return $( element ).hasClass( className ); }, 'Use jQuery.hasClass() instead' ); /** * @source www.mediawiki.org/wiki/Snippets/Load_JS_and_CSS_by_URL * @rev 5 */ // CSS var extraCSS = mw.util.getParamValue( 'withCSS' ); if ( extraCSS ) { if ( extraCSS.match( /^MediaWiki:[^&<>=%#]*\.css$/ ) ) { importStylesheet( extraCSS ); } else { mw.notify( 'Only pages from the MediaWiki namespace are allowed.', { title: 'Invalid withCSS value' } ); } } // JS var extraJS = mw.util.getParamValue( 'withJS' ); if ( extraJS ) { if ( extraJS.match( /^MediaWiki:[^&<>=%#]*\.js$/ ) ) { importScript( extraJS ); } else { mw.notify( 'Only pages from the MediaWiki namespace are allowed.', { title: 'Invalid withJS value' } ); } } /** * Import more specific scripts if necessary */ if ( mw.config.get( 'wgNamespaceNumber' ) === 6 ) { /* file description page scripts */ importScript( 'MediaWiki:Common.js/file.js' ); } /* ([[위키백과:관리자 요청/2007년 5월#스크립트 추가 요청]]) */ /** Collapsible tables ********************************************************* * * Description: Allows tables to be collapsed, showing only the header. See * [[:en:Wikipedia:NavFrame]]. * Maintainers: [[:en:User:R. Koot]] */ var autoCollapse = 2; var collapseCaption = '숨기기'; var expandCaption = '보이기'; window.collapseTable = function ( tableIndex ) { var Button = document.getElementById( 'collapseButton' + tableIndex ); var Table = document.getElementById( 'collapsibleTable' + tableIndex ); if ( !Table || !Button ) { return false; } var Rows = Table.rows; var i; if ( Button.firstChild.data === collapseCaption ) { for ( i = 1; i < Rows.length; i++ ) { Rows[i].style.display = 'none'; } Button.firstChild.data = expandCaption; } else { for ( i = 1; i < Rows.length; i++ ) { Rows[i].style.display = Rows[0].style.display; } Button.firstChild.data = collapseCaption; } }; function createCollapseButtons() { var tableIndex = 0; var NavigationBoxes = {}; var Tables = document.getElementsByTagName( 'table' ); var i; function handleButtonLink( index, e ) { window.collapseTable( index ); e.preventDefault(); } for ( i = 0; i < Tables.length; i++ ) { if ( $( Tables[i] ).hasClass( 'collapsible' ) ) { /* only add button and increment count if there is a header row to work with */ var HeaderRow = Tables[i].getElementsByTagName( 'tr' )[0]; if ( !HeaderRow ) continue; var Header = HeaderRow.getElementsByTagName( 'th' )[0]; if ( !Header ) continue; NavigationBoxes[ tableIndex ] = Tables[i]; Tables[i].setAttribute( 'id', 'collapsibleTable' + tableIndex ); var Button = document.createElement( 'span' ); var ButtonLink = document.createElement( 'a' ); var ButtonText = document.createTextNode( collapseCaption ); Button.className = 'collapseButton'; /* Styles are declared in Common.css */ ButtonLink.style.color = Header.style.color; ButtonLink.setAttribute( 'id', 'collapseButton' + tableIndex ); ButtonLink.setAttribute( 'href', '#' ); $( ButtonLink ).on( 'click', $.proxy( handleButtonLink, ButtonLink, tableIndex ) ); ButtonLink.appendChild( ButtonText ); Button.appendChild( document.createTextNode( '[' ) ); Button.appendChild( ButtonLink ); Button.appendChild( document.createTextNode( ']' ) ); Header.insertBefore( Button, Header.firstChild ); tableIndex++; } } for ( i = 0; i < tableIndex; i++ ) { if ( $( NavigationBoxes[i] ).hasClass( 'collapsed' ) || ( tableIndex >= autoCollapse && $( NavigationBoxes[i] ).hasClass( 'autocollapse' ) ) ) { window.collapseTable( i ); } else if ( $( NavigationBoxes[i] ).hasClass ( 'innercollapse' ) ) { var element = NavigationBoxes[i]; while ((element = element.parentNode)) { if ( $( element ).hasClass( 'outercollapse' ) ) { window.collapseTable ( i ); break; } } } } } mw.hook( 'wikipage.content' ).add( createCollapseButtons ); /* ([[위키백과:관리자 요청/2007년 5월#스크립트 추가 요청]]) */ /** Dynamic Navigation Bars (experimental) ************************************* * * Description: See [[:en:Wikipedia:NavFrame]]. * Maintainers: UNMAINTAINED */ // set up the words in your language /* set up the words in your language */ var NavigationBarHide = '[' + collapseCaption + ']'; var NavigationBarShow = '[' + expandCaption + ']'; /** * Shows and hides content and picture (if available) of navigation bars * Parameters: * indexNavigationBar: the index of navigation bar to be toggled **/ window.toggleNavigationBar = function ( indexNavigationBar, event ) { var NavToggle = document.getElementById( 'NavToggle' + indexNavigationBar ); var NavFrame = document.getElementById( 'NavFrame' + indexNavigationBar ); var NavChild; if ( !NavFrame || !NavToggle ) { return false; } /* if shown now */ if ( NavToggle.firstChild.data === NavigationBarHide ) { for ( NavChild = NavFrame.firstChild; NavChild !== null; NavChild = NavChild.nextSibling ) { if ( $( NavChild ).hasClass( 'NavContent' ) || $( NavChild ).hasClass( 'NavPic' ) ) { NavChild.style.display = 'none'; } } NavToggle.firstChild.data = NavigationBarShow; /* if hidden now */ } else if ( NavToggle.firstChild.data === NavigationBarShow ) { for ( NavChild = NavFrame.firstChild; NavChild !== null; NavChild = NavChild.nextSibling ) { if ( $( NavChild ).hasClass( 'NavContent' ) || $( NavChild ).hasClass( 'NavPic' ) ) { NavChild.style.display = 'block'; } } NavToggle.firstChild.data = NavigationBarHide; } event.preventDefault(); }; /* adds show/hide-button to navigation bars */ function createNavigationBarToggleButton() { var indexNavigationBar = 0; var NavFrame; var NavChild; /* iterate over all < div >-elements */ var divs = document.getElementsByTagName( 'div' ); for ( var i = 0; (NavFrame = divs[i]); i++ ) { /* if found a navigation bar */ if ( $( NavFrame ).hasClass( 'NavFrame' ) ) { indexNavigationBar++; var NavToggle = document.createElement( 'a' ); NavToggle.className = 'NavToggle'; NavToggle.setAttribute( 'id', 'NavToggle' + indexNavigationBar ); NavToggle.setAttribute( 'href', '#' ); $( NavToggle ).on( 'click', $.proxy( window.toggleNavigationBar, window, indexNavigationBar ) ); var isCollapsed = $( NavFrame ).hasClass( 'collapsed' ); /** * Check if any children are already hidden. This loop is here for backwards compatibility: * the old way of making NavFrames start out collapsed was to manually add style="display:none" * to all the NavPic/NavContent elements. Since this was bad for accessibility (no way to make * the content visible without JavaScript support), the new recommended way is to add the class * "collapsed" to the NavFrame itself, just like with collapsible tables. */ for ( NavChild = NavFrame.firstChild; NavChild != null && !isCollapsed; NavChild = NavChild.nextSibling ) { if ( $( NavChild ).hasClass( 'NavPic' ) || $( NavChild ).hasClass( 'NavContent' ) ) { if ( NavChild.style.display === 'none' ) { isCollapsed = true; } } } if ( isCollapsed ) { for ( NavChild = NavFrame.firstChild; NavChild != null; NavChild = NavChild.nextSibling ) { if ( $( NavChild ).hasClass( 'NavPic' ) || $( NavChild ).hasClass( 'NavContent' ) ) { NavChild.style.display = 'none'; } } } var NavToggleText = document.createTextNode( isCollapsed ? NavigationBarShow : NavigationBarHide ); NavToggle.appendChild( NavToggleText ); /* Find the NavHead and attach the toggle link (Must be this complicated because Moz's firstChild handling is borked) */ for( var j = 0; j < NavFrame.childNodes.length; j++ ) { if ( $( NavFrame.childNodes[j] ).hasClass( 'NavHead' ) ) { NavToggle.style.color = NavFrame.childNodes[j].style.color; NavFrame.childNodes[j].appendChild( NavToggle ); } } NavFrame.setAttribute( 'id', 'NavFrame' + indexNavigationBar ); } } } mw.hook( 'wikipage.content' ).add( createNavigationBarToggleButton ); /***** 그림 정보 틀을 자동으로 불러옴 ******** * Adds a link to subpages of current page * from commons.wikimedia.org * Maintainers: [[User:Yonidebest]], [[User:Dschwen]] * [[사용자:Kwj2772]]가 수정 * JSconfig items: bool 'loadAutoInformationTemplate' * (true=enabled (default), false=disabled) * JSConfig를 사용하지 않도록 수정함. --[[사용자:Klutzy|klutzy]] ([[사용자토론:Klutzy|토론]]) 2009년 9월 27일 (일) 20:33 (KST) ****/ if (mw.config.get('wgCanonicalSpecialPageName') == 'Upload') { importScript('MediaWiki:Upload.js'); } /* 인터랙티브 지도. 영어 위키백과에서 가져옴. -- [[사용자:ChongDae]] 2010년 3월 28일 (일) 02:08 (KST) */ /** * WikiMiniAtlas * * Description: WikiMiniAtlas is a popup click and drag world map. * This script causes all of our coordinate links to display the WikiMiniAtlas popup button. * The script itself is located on meta because it is used by many projects. * See [[Meta:WikiMiniAtlas]] for more information. * Maintainers: [[User:Dschwen]] */ ( function () { var require_wikiminiatlas = false; var coord_filter = /geohack/; $( function () { $( 'a.external.text' ).each( function( key, link ) { if ( link.href && coord_filter.exec( link.href ) ) { require_wikiminiatlas = true; // break from loop return false; } } ); if ( $( 'div.kmldata' ).length ) { require_wikiminiatlas = true; } if ( require_wikiminiatlas ) { mw.loader.load( '//meta.wikimedia.org/w/index.php?title=MediaWiki:Wikiminiatlas.js&action=raw&ctype=text/javascript' ); } } ); } )(); /** * Fix for Windows XP Unicode font rendering */ if ( navigator.appVersion.search(/windows nt 5/i) !== -1 ) { mw.util.addCSS( '.IPA { font-family: "Lucida Sans Unicode", "Arial Unicode MS"; } ' + '.Unicode { font-family: "Arial Unicode MS", "Lucida Sans Unicode"; } ' ); } /** * 편집 안내 **************************************************** * * 생존 인물에 대한 편집 안내. 영어 위키백과에서 가져옴 - ChongDae * Maintainers: [[User:RockMFR]] */ function addEditIntro( name ) { $( '.mw-editsection, #ca-edit' ).find( 'a' ).each( function ( i, el ) { el.href = $( this ).attr( 'href' ) + '&editintro=' + name; } ); } if ( mw.config.get( 'wgNamespaceNumber' ) === 0 ) { $( function () { var cats = mw.config.get('wgCategories'); if ( !cats ) { return; } if ( $.inArray( '살아있는 사람', cats ) !== -1 || $.inArray( '생사 불명', cats ) !== -1 ) { addEditIntro( '틀:BLP_편집_안내' ); } } ); } /** * * * */ function wikilink1() { location.href='https://jwiki.kr/wiki/index.php/철통같은_믿음으로'; } /* End of mw.loader.using callback */ } ); $(document).ready(function () { /* ---------- helper for sub-pixel scroll height ---------- */ /* ---------- helper for sub-pixel scroll height (accurate & shift-free) ---------- */ function getExactScrollHeight(el) { /* 1 — snapshot the current inline width so the clone wraps exactly the same */ const liveRect = el.getBoundingClientRect(); // fractional width! const liveW = liveRect.width + "px"; /* 2 — make a deep clone and neutralise its layout impact */ const clone = el.cloneNode(true); Object.assign(clone.style, { position : "absolute", // out of normal flow left : "-9999px", // off-screen (but in the DOM) top : "0", width : liveW, // lock wrapping width height : "auto", overflow : "visible", visibility : "hidden", pointerEvents : "none", transition : "none" }); /* 3 — measure, then discard */ el.parentNode.appendChild(clone); // within same ancestor → exact CSS context const h = clone.getBoundingClientRect().height; // accurate, fractional OK clone.remove(); return h; // sub-pixel-precise } /* -------------------------------------------------------- */ $('.toggleBtn').click(function () { var $button = $(this); if ($button.data('animating')) return; $button.data('animating', true); var targetId = $button.data('target'); var growDiv = document.getElementById(targetId); var $growDiv = $('#' + targetId); const cs = window.getComputedStyle(growDiv); var oldHeight = growDiv.getBoundingClientRect().height; var paddingAndBorder = parseFloat(cs.paddingTop) + parseFloat(cs.paddingBottom); $growDiv.toggleClass('collapsed'); if (growDiv.clientHeight) { /* ---------- COLLAPSE ---------- */ setTimeout(() => growDiv.style.display = "none", 300); growDiv.style.height = 0; var heightDifference = 0 - oldHeight - paddingAndBorder; } else { /* ---------- EXPAND ---------- */ growDiv.style.display = "block"; const exactScrollHeight = getExactScrollHeight(growDiv); if ($growDiv.hasClass('textcollapsible')) { growDiv.style.height = (exactScrollHeight + 6) + "px"; } else { growDiv.style.height = (exactScrollHeight + 6.5) + "px"; } var heightDifference = exactScrollHeight - oldHeight - paddingAndBorder; } if ($growDiv.hasClass('textcollapsible') && !$growDiv.hasClass('collapsed')) { heightDifference += 6; } else if (!$growDiv.hasClass('textcollapsible') && !$growDiv.hasClass('collapsed')) { heightDifference += 6.5; } console.log(heightDifference); animateParentHeights(growDiv, heightDifference); setTimeout(() => $button.data('animating', false), 300); }); function animateParentHeights(element, difference) { var parent = element.parentElement.closest('.collapsible'); while (parent) { var intervalId = setInterval(() => { const p = element.parentElement.closest('.collapsible'); p.style.height = getExactScrollHeight(p) + 5 + 'px'; // float }, 30); setTimeout(() => { clearInterval(intervalId); const p = element.parentElement.closest('.collapsible'); p.style.animation = ''; p.style.height = getExactScrollHeight(p) + 5 + 'px'; // float }, 310); parent = parent.parentElement.closest('.collapsible'); } } }); 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('.live-recent-content'); if (existing) { const newDiv = document.createElement('div'); newDiv.className = 'live-recent-fake-content'; 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; width: 21.5rem !important; height:16.76rem !important; ` ); appendafterthis.insertAdjacentElement('afterend', newDiv); }; const list = document.querySelector('.live-recent-content'); if (!list) return; const link = document.createElement('a'); link.href = '/%ED%8A%B9%EC%88%98:%EC%B5%9C%EA%B7%BC%EB%B0%94%EB%80%9C'; link.innerText = '최근 변경'; link.style.display = 'block'; link.style.fontSize = '20px'; link.style.fontWeight = '500'; link.style.marginTop = '3px'; link.style.textDecoration = 'none'; link.style.textAlign = 'left'; link.style.color = 'var(--text)'; const link2 = document.createElement('a'); link2.href = '/%ED%8A%B9%EC%88%98:%EC%B5%9C%EA%B7%BC%EB%B0%94%EB%80%9C'; link2.innerText = '▶'; link2.style.display = 'block'; link2.style.fontSize = '14px'; link2.style.fontWeight = '500'; link2.style.marginTop = '3px'; link2.style.textDecoration = 'none'; link2.style.textAlign = 'right'; link2.style.opacity = '60%'; link2.style.color = 'var(--text)'; const containeroflinks = document.createElement('div'); containeroflinks.style.display = 'flex'; containeroflinks.style.justifyContent = 'space-between'; containeroflinks.style.alignItems = 'center'; containeroflinks.append(link); containeroflinks.append(link2); list.prepend(containeroflinks); // add to the top of the container const targetElements = document.querySelectorAll('.live-recent-content'); targetElements.forEach((el) => { el.insertAdjacentHTML( 'beforebegin', `<a href="https://www.postype.com/@whalvkr/membership"> <div class="live-recent-fake-content" style=" margin-bottom: 1rem; background: url(https://w.halv.kr/images/b/bd/후원처란.png) center no-repeat, light-dark(#fff,#1c1d1f) !important; height: 6rem; 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=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.8/dist/web/variable/pretendardvariable.min.css'; head.appendChild(link3); 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(); /* DO NOT ADD CODE BELOW THIS LINE */
미디어위키:Common.js
문서로 돌아갑니다.