MediaWiki:Common.js: Difference between revisions

From Church of God Knowledge Encyclopedia
Jump to navigation Jump to search
No edit summary
No edit summary
 
(160 intermediate revisions by the same user not shown)
Line 1: Line 1:
/* 이 자바스크립트 설정은 모든 문서, 모든 사용자에게 적용됩니다. */
if(!mw.config.get('wgUserId')){
var currentUrl = window.location.href;
var commJs = currentUrl.includes('Common.js');
var commCss = currentUrl.includes('Common.css');
var vectorJs = currentUrl.includes('Vector.js');
var vectorCss = currentUrl.includes('Vector.css');
if(commJs || commCss || vectorJs || vectorCss){
window.location.href = '/index.php';
}
// 도구 메뉴들 숨김(사이드바);
$pTb = document.getElementById('p-tb');
if ($pTb) $pTb.parentElement.removeChild($pTb);
// 문서의 역사롤 봅니다. (hidden 시킴)
var $lastModifiedBar = document.querySelector('.last-modified-bar');
if($lastModifiedBar) $lastModifiedBar.parentElement.removeChild($lastModifiedBar);


//Google Analytics
//파일중복 메세지 제거
var GoogleCdn = document.createElement('script');
var $duplicates = document.getElementById('mw-imagepage-section-duplicates');
GoogleCdn.src = 'https://www.googletagmanager.com/gtag/js?id=G-LTWMMR6YSB';
if($duplicates) $duplicates.parentElement.removeChild($duplicates);
document.body.appendChild(GoogleCdn);
}else{
window.dataLayer = window.dataLayer || [];
$searchBox = document.querySelector('.mw-htmlform-ooui-wrapper');
function gtag() {
if($searchBox) $searchBox.style.display = 'block';
    dataLayer.push(arguments);
}
}
gtag('js', new Date());
gtag('config', 'G-LTWMMR6YSB');


/* TOP 버튼 */
/* TOP 버튼 */
Line 60: Line 72:
     document.querySelector('.cog-commonpages').style.display = '';
     document.querySelector('.cog-commonpages').style.display = '';
}
}
 
var mouseX=0;
var mouseY=0;
/* 각주 팝업창 위치 보정 DOM */
/* 각주 팝업창 위치 보정 DOM */
document.body.addEventListener(
var observer = new MutationObserver(function (mutationList) {
    'mousemove',
    mutationList.forEach(function (mutation) {
    function (e) {
         mutation.addedNodes.forEach(function (node) {
        if (e.target.classList && e.target.classList.contains('rt-tooltip')) {
            if (node.classList && (node.classList.contains('mwe-popups')|| node.classList.contains('rt-tooltip'))) {
            requestAnimationFrame(function () {
                requestAnimationFrame(function () {
                var bodyLeft = document.body.getBoundingClientRect().left;
                    var bodyLeft = document.body.getBoundingClientRect().left;
                var left = parseInt(window.getComputedStyle(e.target).left);
                    var left = parseInt(window.getComputedStyle(node).left);
                e.target.style.left = e.paeX + 'px';
                    node.style.left = left - bodyLeft + 'px';
                e.target.style.top = e.pageY + 'px';
                });
            });
            }
         }
         });
    },
     });
    false
});
);
// 감시할 대상 설정
/*
observer.observe(document.body, {
document.body.addEventListener(
    childList: true,
    'NodeInserted',
     subtree: true,
    function (e) {
});
        if (e.target.classList && e.target.classList.contains('rt-tooltip')) {
            requestAnimationFrame(function () {
                var bodyLeft = document.body.getBoundingClientRect().left;
                var bodyTop = document.body.getBoundingClientRect().top;
                var left = parseInt(window.getComputedStyle(e.target).left);
var top = parseInt(window.getComputedStyle(e.target).top);
                e.target.style.left = left - bodyLeft + 'px';
});
         }
     },
     false
);
*/


 
/* 우클릭 방지 */
/* 우클릭 방지
if (mw.config.get("wgUserName") == null) {
window.oncontextmenu = function (e) {
  window.oncontextmenu = function (e) {
     return e.preventDefault();
     return e.preventDefault();
};
  };
window.onselectstart = function (e) {
  window.onselectstart = function (e) {
     return e.preventDefault();
     return e.preventDefault();
};
  };
*/
}
 
   
   
/* 존재하지 않는 문서 페이지의 '기록' 링크 삭제 */
/* 존재하지 않는 문서 페이지의 '기록' 링크 삭제 */
Line 278: Line 279:
     }
     }
}
}
//const bodyElem = document.querySelector('#bodyContent');
//bodyElem.classList.add("mw-body-content");


//const navigationElem = document.querySelector('.minerva-user-navigation');
//넘겨주기 문서를 숨깁니다.
//navigationElem.remove()
var redirectList = document.querySelectorAll('.mw-parser-output li.allpagesredirect')
for (var i=0; i < redirectList.length; i++){
redirectList[i].style.display = 'none';
}
 
// 이미지문서에서 commons 라이센스 관련 링크를 숨긴다.
var $sharedUploadNotice = document.querySelector('.sharedUploadNotice p');
if($sharedUploadNotice){
$sharedUploadNotice.parentElement.removeChild($sharedUploadNotice);
}
// origin file 영역 숨김.
var $fullMedia = document.querySelector('.fullMedia p');
if($fullMedia){
$fullMedia.parentElement.removeChild($fullMedia);
}
/* GA4: single ID + language tagging (MediaWiki 1.42.3) */
(function () {
// 중복 로드 방지
if (window.__GA4_LOADED__) return;
window.__GA4_LOADED__ = true;
var GA_ID = 'G-YGT3D2Q9QW';
 
// 언어 결정: 가장 신뢰도 높은 wgContentLanguage, 없으면 경로 프리픽스로 보완
var pathLang = (location.pathname.split('/')[1] || '').toLowerCase();
var lang = (mw.config && mw.config.get('wgContentLanguage'))
        || (['en','es','ko','vi','pt','ne'].includes(pathLang) ? pathLang : 'ko');
// <head>에 gtag 로더 삽입
var s = document.createElement('script');
s.async = true;
s.src = 'https://www.googletagmanager.com/gtag/js?id=' + encodeURIComponent(GA_ID);
document.head.appendChild(s);
window.dataLayer = window.dataLayer || [];
function gtag(){ dataLayer.push(arguments); }
window.gtag = gtag;
gtag('js', new Date());
 
// 🔹 자동 page_view 끄기
gtag('config', GA_ID, {
send_page_view: false
});
    // 사용자 속성
    gtag('set', 'user_properties', {
        site_language: lang,
        browser_language: navigator.language || navigator.userLanguage
    });
 
    // page_view 이벤트
gtag('event', 'page_view', {
    page_location: location.href,
    page_path: location.pathname + location.search,
    page_title: document.title,
    content_group: lang
});
 
})();
mw.loader.using(['jquery']).then(function () {
    // ----------------------------
    // 1. 인터랭 텍스트 한국어 병기
    // ----------------------------
    const langMap = {
        'ko': 'Korean',
        'en': 'English',
        'es': 'Spanish',
        'vi': 'Vietnamese',
        'ne': 'Nepali',
        'pt': 'Portuguese'
    };
//다른 언어 텍스트
const languageLabel = $('#p-lang h3 .vector-menu-heading-label').text().trim();
    // 인터위키 언어 목록 선택자
    const $items = $('.vector-menu-content-list .interlanguage-link a');
 
    $items.each(function () {
        const $a = $(this);
 
        const langCode = $a.attr('lang'); // en, es, vi, ne, pt …
        const autonym = $a.find('span').text(); // English, Español, Tiếng Việt …
        const koreanName = langMap[langCode];
 
        if (!koreanName) return; // 배열에 없는 언어는 스킵
 
        // 이미 한국어 형식이 적용된 경우 중복 적용 방지
        if (autonym.includes('(')) return;
 
        // 링크 텍스트 변경: "English" → "English (영어)"
        $a.find('span').text(`${autonym} (${koreanName})`);
    });
   
    // ----------------------------
    // 2. 변환된 인터랭을 헤더로 복사
    // ----------------------------
    const $interLangList = $('#p-lang .vector-menu-content-list');
    if ($interLangList.length === 0) return;
 
    var langDiv = document.getElementById('right-navigation');
    if (!langDiv) return;
 
    var navHTML =
        '<nav id="p-cactions" class="mw-portlet mw-portlet-cactions vector-menu-dropdown-noicon vector-menu vector-menu-dropdown" aria-labelledby="p-cactions-label" role="navigation">' +
            '<input type="checkbox" id="p-cactions-checkbox" role="button" aria-haspopup="true" class="vector-menu-checkbox" aria-labelledby="p-cactions-label">' +
            '<label id="p-cactions-label" class="vector-menu-heading">' +
                '<span class="select-language"></span>' +
                '<span class="vector-menu-heading-label">'+languageLabel+'</span>' +
            '</label>' +
            '<div class="vector-menu-content">' +
                '<ul class="vector-menu-content-list" id="header-lang-list"></ul>' +
            '</div>' +
        '</nav>';
 
    langDiv.insertAdjacentHTML('afterbegin', navHTML);
    const $headerList = $('#header-lang-list');
 
    // 변환된 인터랭 li 를 그대로 복사
    $interLangList.find('li.interlanguage-link').each(function () {
        const $a = $(this).find('a');
        const href = $a.attr('href');
        const title = $a.attr('title') || '';
        const text = $a.find('span').text();
 
        const newLi =
            '<li class="mw-list-item">' +
                '<a href="' + href + '" title="' + title + '">' +
                    '<span>' + text + '</span>' +
                '</a>' +
            '</li>';
 
        $headerList.append(newLi);
    });   
});

Latest revision as of 09:54, 26 November 2025

if(!mw.config.get('wgUserId')){
	var currentUrl = window.location.href;
	var commJs = currentUrl.includes('Common.js');
	var commCss = currentUrl.includes('Common.css');
	var vectorJs = currentUrl.includes('Vector.js');
	var vectorCss = currentUrl.includes('Vector.css'); 
	if(commJs || commCss || vectorJs || vectorCss){
		window.location.href = '/index.php';
	}
	// 도구 메뉴들 숨김(사이드바);
	$pTb = document.getElementById('p-tb');
	if ($pTb) $pTb.parentElement.removeChild($pTb);	
	
	// 문서의 역사롤 봅니다. (hidden 시킴)
	var $lastModifiedBar = document.querySelector('.last-modified-bar');
	if($lastModifiedBar) $lastModifiedBar.parentElement.removeChild($lastModifiedBar);

	//파일중복 메세지 제거
	var $duplicates = document.getElementById('mw-imagepage-section-duplicates');
	if($duplicates) $duplicates.parentElement.removeChild($duplicates);		
}else{
	$searchBox = document.querySelector('.mw-htmlform-ooui-wrapper');
	if($searchBox) $searchBox.style.display = 'block';
}

/* TOP 버튼 */
var topButton = document.createElement('div');
topButton.id = 'top-button';

document.body.appendChild(topButton);
window.addEventListener('scroll', function (e) {
    if (window.scrollY > 300) {
        topButton.classList.add('active');
    } else {
        topButton.classList.remove('active');
    }
});
topButton.addEventListener('click', function (e) {
    try {
        window.scrollTo({
            top: 0,
            left: 0,
            behavior: 'smooth',
        });
    } catch (e) {
        window.scrollTo(0, 0);
    }
});
/* 대문 섹션 토글 */
if (mw.config.get('wgPageName') == '대문' || mw.config.get('wgPageName') == '대문테스트') {
    var titles = document.querySelectorAll('.cog-box-title');
    for (var i = 0; i < titles.length; i++) {
        titles[i].addEventListener('click', function (e) {
            if (e.currentTarget.classList.contains('open')) {
                e.currentTarget.classList.remove('open');
            } else {
                e.currentTarget.classList.add('open');
            }
        });
    }
}

/*모든 문서 */
if (mw.config.get('wgPageName').toLowerCase() == 'list_of_all_documents') {
    var list = document.querySelectorAll('.mw-allpages-body li');
    for (var i = 0; i < list.length; i++) {
        var title = list[i].querySelector('a').title;
        if (title.indexOf(':') != -1) {
            list[i].parentNode.removeChild(list[i]);
        }
    }
    document.querySelector('.cog-commonpages').style.display = '';
}
var mouseX=0;
var mouseY=0;
/* 각주 팝업창 위치 보정 DOM */
var observer = new MutationObserver(function (mutationList) {
    mutationList.forEach(function (mutation) {
        mutation.addedNodes.forEach(function (node) {
            if (node.classList && (node.classList.contains('mwe-popups')|| node.classList.contains('rt-tooltip'))) {
                requestAnimationFrame(function () {
                    var bodyLeft = document.body.getBoundingClientRect().left;
                    var left = parseInt(window.getComputedStyle(node).left);
                    node.style.left = left - bodyLeft + 'px';
                });
            }
        });
    });
});
// 감시할 대상 설정
observer.observe(document.body, {
    childList: true,
    subtree: true,
});

/* 우클릭 방지  */
if (mw.config.get("wgUserName") == null) {
  window.oncontextmenu = function (e) {
    return e.preventDefault();
  };
  window.onselectstart = function (e) {
    return e.preventDefault();
  };
}

 
/* 존재하지 않는 문서 페이지의 '기록' 링크 삭제 */
if (mw.config.get('wgUserId') == null && document.querySelector('.plainlinks a')) {
    document.querySelector('.plainlinks a').removeAttribute('href');
    document.querySelector('.plainlinks a').classList.add('disable');
}

// 대문 공유 버튼
var sharebox = document.querySelector('.wikishare_toolbox');
if (sharebox) {
    sharebox.classList.add('a2a_kit_size_20');
    sharebox.classList.add('a2a_kit');
    var shares = ['Facebook', 'Twitter', 'Email', 'Line', 'Kakao', 'SMS'];
    for (var i in shares) {
        var elem = document.querySelector('[title="Share on ' + shares[i] + '"] a');
        elem.href = '';
        elem.classList.add('a2a_button_' + shares[i].toLowerCase());
    }
    document.querySelector('[title="Share on KakaoTalk"] a').href = '#';
    document.querySelector('[title="Share on KakaoTalk"] a').removeAttribute('target');

    var share_cdn = document.createElement('script');
    share_cdn.src = 'https://static.addtoany.com/menu/page.js';
    var kakao_cdn = document.createElement('script');
    kakao_cdn.src = 'https://developers.kakao.com/sdk/js/kakao.min.js';
    document.body.appendChild(share_cdn);
    document.body.appendChild(kakao_cdn);

    // 페이지 로딩 이후 초기화해야할 내용 정의
    initScript();
    function initScript() {
        var retry = false;

        // 카카오 링크 초기화
        if (window.initKakaoLink != true) {
            var $kakao = document.querySelector('[title="Share on KakaoTalk"]');
            if (window.Kakao && $kakao) {
                // 사용할 앱의 JavaScript 키를 설정해 주세요.
                Kakao.init('214de4d25d41a7b837b7bbeb75631c90');
                $kakao.children[0].style.display = 'inline';
                $kakao.onclick = sendScrap; // 카카오 Link 공유 API 사용
                window.initKakaoLink = true;
            } else retry = true;
        }

        // 링크 복사 초기화
        if (window.initCopyLink != true) {
            var $copy = document.querySelector('.wikishare_button_Copy');
            if ($copy) {
                $copy.style.display = 'inline';
                $copy.addEventListener('click', function (e) {
                    copyStringToClipboard(decodeURI(location.href));
                    alert('Saved the link to the clipboard.');
                    e.preventDefault();
                });
                window.initCopyLink = true;
            } else retry = true;
        }

        // 애널리틱스
        if (window.initWcs != true) {
            if (window.wcs) {
                wcs_do();
                window.initWcs = true;
            } else retry = true;
        }

        if (retry) setTimeout(initScript, 300);
    }
}

// 문자열을 클립보드에 저장
function copyStringToClipboard(str) {
    var el = document.createElement('textarea');
    el.value = str;
    el.setAttribute('readonly', '');
    el.style = { position: 'absolute', left: '-9999px' };
    document.body.appendChild(el);
    el.select();
    document.execCommand('copy');
    document.body.removeChild(el);
}

function sendScrap() {
    // 카카오 Link 공유 API 사용
    Kakao.Link.sendScrap({
        requestUrl: location.href,
        templateId: 91817,
        templateArgs: {
            TITLE: og('title', 'Church of God Knowledge Encyclopedia'),
            DESC: og('description'),
            THUMB: thumb(),
            PAGE: path(),
        },
    });
    function og(name, defaultVal) {
        var $meta = document.querySelector('meta[property="og:' + name + '"]');
        if ($meta) return $meta.getAttribute('content');
        else return defaultVal ? defaultVal : '';
    }
    function thumb() {
        var img = og('image');
        if (!img) {
            var $img = document.querySelector('img[src]');
            if ($img) {
                img = $img.src;
            }
        }
        if (img.indexOf('http') != 0) img = location.origin + (img[0] == '/' ? img : '/' + img);
        return img;
    }
    function path() {
        if (location.pathname[0] == '/') return location.pathname.substring(1) + location.search;
        else return location.pathname + location.search;
    }
}

// 앨범 레이아웃 보정
updateAllAlbum();
window.addEventListener('load', updateAllAlbum);
window.addEventListener('resize', updateAllAlbum);
function updateAllAlbum() {
    var $albums = document.querySelectorAll('.custom-album');
    for (var i = 0; i < $albums.length; i++) {
        updateAlbum($albums[i]);
    }
}
function updateAlbum($elem) {
    var lineMax = 3;
    for (var i = 0; i < $elem.classList.length; i++) {
        if ($elem.classList[i].indexOf('line-max-') == 0) {
            lineMax = Number($elem.classList[i].replace('line-max-', ''));
        }
    }

    var totalWidth = $elem.clientWidth;

    if ($elem.children.length > 0) {
        for (var i = $elem.children.length - 1; i >= 0; i--) {
            if (!$elem.children[i].classList.contains('albumitem')) {
                $elem.children[i].remove();
                continue;
            }
            $elem.children[i].style.width = '';
            $elem.children[i].style.height = '';
        }

        if (window.innerWidth < 720) return;

        var lineTotalRatio = [];
        for (var i = 0; i < $elem.children.length; i++) {
            var lineIdx = Math.floor(i / lineMax);
            var $img = $elem.children[i].querySelector('img');

            if (!$img || $img.naturalWidth == 0) continue;

            if (lineTotalRatio[lineIdx] == undefined) {
                lineTotalRatio[lineIdx] = 0;
            }

            lineTotalRatio[lineIdx] += $img.naturalWidth / $img.naturalHeight;
        }

        for (var i = 0; i < $elem.children.length; i++) {
            var totalRatio = lineTotalRatio[Math.floor(i / lineMax)];
            var $img = $elem.children[i].querySelector('img');

            if (!$img || $img.naturalWidth == 0) continue;

            var ratio = $img.naturalWidth / $img.naturalHeight;
            var width = (ratio / totalRatio) * (totalWidth - 6 * lineMax) + 6;
            $elem.children[i].style.width = (width / totalWidth) * 100 + '%';
        }
    }
}

//넘겨주기 문서를 숨깁니다.
var redirectList = document.querySelectorAll('.mw-parser-output li.allpagesredirect')
for (var i=0; i < redirectList.length; i++){
	redirectList[i].style.display = 'none';
}

// 이미지문서에서 commons 라이센스 관련 링크를 숨긴다.
var $sharedUploadNotice = document.querySelector('.sharedUploadNotice p');
if($sharedUploadNotice){
	$sharedUploadNotice.parentElement.removeChild($sharedUploadNotice);
}
// origin file 영역 숨김.
var $fullMedia = document.querySelector('.fullMedia p');
if($fullMedia){
	$fullMedia.parentElement.removeChild($fullMedia);
}
/* GA4: single ID + language tagging (MediaWiki 1.42.3) */
(function () {
	// 중복 로드 방지
	if (window.__GA4_LOADED__) return;
	window.__GA4_LOADED__ = true;
	
	var GA_ID = 'G-YGT3D2Q9QW'; 

	// 언어 결정: 가장 신뢰도 높은 wgContentLanguage, 없으면 경로 프리픽스로 보완
	var pathLang = (location.pathname.split('/')[1] || '').toLowerCase(); 
	var lang = (mw.config && mw.config.get('wgContentLanguage')) 
	         || (['en','es','ko','vi','pt','ne'].includes(pathLang) ? pathLang : 'ko');
	// <head>에 gtag 로더 삽입
	var s = document.createElement('script');
	s.async = true;
	s.src = 'https://www.googletagmanager.com/gtag/js?id=' + encodeURIComponent(GA_ID);
	document.head.appendChild(s);
	
	window.dataLayer = window.dataLayer || [];
	function gtag(){ dataLayer.push(arguments); }
	window.gtag = gtag;
	
	gtag('js', new Date());

	// 🔹 자동 page_view 끄기
	gtag('config', GA_ID, {
		send_page_view: false
	});
	
    // 사용자 속성
    gtag('set', 'user_properties', {
        site_language: lang,
        browser_language: navigator.language || navigator.userLanguage
    });

    // page_view 이벤트
	gtag('event', 'page_view', {
	    page_location: location.href,
	    page_path: location.pathname + location.search,
	    page_title: document.title,
	    content_group: lang
	});

})();
mw.loader.using(['jquery']).then(function () {
    // ----------------------------
    // 1. 인터랭 텍스트 한국어 병기
    // ----------------------------
    const langMap = {
        'ko': 'Korean',
        'en': 'English',
        'es': 'Spanish',
        'vi': 'Vietnamese',
        'ne': 'Nepali',
        'pt': 'Portuguese'
    };
	//다른 언어 텍스트
	const languageLabel = $('#p-lang h3 .vector-menu-heading-label').text().trim();
    // 인터위키 언어 목록 선택자
    const $items = $('.vector-menu-content-list .interlanguage-link a');

    $items.each(function () {
        const $a = $(this);

        const langCode = $a.attr('lang'); // en, es, vi, ne, pt …
        const autonym = $a.find('span').text(); // English, Español, Tiếng Việt …
        const koreanName = langMap[langCode];

        if (!koreanName) return; // 배열에 없는 언어는 스킵

        // 이미 한국어 형식이 적용된 경우 중복 적용 방지
        if (autonym.includes('(')) return;

        // 링크 텍스트 변경: "English" → "English (영어)"
        $a.find('span').text(`${autonym} (${koreanName})`);
    });
    
    // ----------------------------
    // 2. 변환된 인터랭을 헤더로 복사
    // ----------------------------
    const $interLangList = $('#p-lang .vector-menu-content-list');
    if ($interLangList.length === 0) return;

    var langDiv = document.getElementById('right-navigation');
    if (!langDiv) return;

    var navHTML =
        '<nav id="p-cactions" class="mw-portlet mw-portlet-cactions vector-menu-dropdown-noicon vector-menu vector-menu-dropdown" aria-labelledby="p-cactions-label" role="navigation">' +
            '<input type="checkbox" id="p-cactions-checkbox" role="button" aria-haspopup="true" class="vector-menu-checkbox" aria-labelledby="p-cactions-label">' +
            '<label id="p-cactions-label" class="vector-menu-heading">' +
                '<span class="select-language"></span>' +
                '<span class="vector-menu-heading-label">'+languageLabel+'</span>' +
            '</label>' +
            '<div class="vector-menu-content">' +
                '<ul class="vector-menu-content-list" id="header-lang-list"></ul>' +
            '</div>' +
        '</nav>';

    langDiv.insertAdjacentHTML('afterbegin', navHTML);
    const $headerList = $('#header-lang-list');

    // 변환된 인터랭 li 를 그대로 복사
    $interLangList.find('li.interlanguage-link').each(function () {
        const $a = $(this).find('a');
        const href = $a.attr('href');
        const title = $a.attr('title') || '';
        const text = $a.find('span').text();

        const newLi =
            '<li class="mw-list-item">' +
                '<a href="' + href + '" title="' + title + '">' +
                    '<span>' + text + '</span>' +
                '</a>' +
            '</li>';

        $headerList.append(newLi);
    });    
});