리브레 위키를 비롯한 미디어위키 기반의 위키에서는 사용자 환경설정에서 특정한 기능을 제공하는 사용자 고유의 자바스크립트를 삽입하는 기능을 지원하고 있습니다. 이 문서는 이러한 자바스크립트를 사용하는 방법과 그 예제에 대해 올리는 곳입니다.
사용 방법[원본 편집]
특:내사용자문서/common.js에 자신이 원하는 기능을 제공하는 자바스크립트 코드를 넣으면 사용할 수 있습니다.
특정 스킨에만 적용되게 사용자 자바스크립트를 적용할 수도 있습니다. "사용자:(계정 필요)/(스킨 식별자, 기본 스킨의 경우 liberty).js" 문서에 코드를 작성하면 됩니다.
이미 있는 스크립트 파일을 사용하실 때에는 mw.loader.load('//(자바스크립트의 주소)');
를 입력해주시면 됩니다. 단, 미디어위키 문서를 불러오실 때는 ?action=raw&ctype=text/javascript
를 주소 뒤에 붙여주셔야 작동합니다.
미디어위키 내부 인터페이스[원본 편집]


미디어위키는 기본적인 DOM 자바스크립트와 JQuery 문법을 기본적으로 제공합니다. 그 외에도 미디어위키에서는 문서 자체의 정보를 긁어올 수 있는 mw 오브젝트를 포함해서 여러 오브젝트를 지원하고 있습니다.
예시 - mw.config.get('(속성)')을 통해 지금 읽고 있는 문서의 정보를 긁어오실 수 있습니다. 속성 관련 표
속성 | 설명 |
---|---|
skin | 현재 사용하고 있는 스킨 이름을 확인할 수 있습니다. |
wgArticlePath | 현재 위키의 문서 경로명을 확인할 수 있습니다. 리브레 위키에서는 "wiki/$1"형식으로 출력됩니다. |
wgNamespaceIds | 현재 위키가 사용하고 있는 이름공간의 명칭과 번호를 오브젝트 형식으로 확인할 수 있습니다. |
속성 | 설명 |
---|---|
wgAction | 현재 미디어위키 문서에서 사용하는 동작을 확인합니다. 문서를 볼 때는 'view', 문서를 편집할 때는 'edit'이 출력됩니다. |
wgArticleId | 현재 페이지의 id값을 출력합니다. |
wgCategories | 현재 문서의 분류 목록을 출력합니다. |
wgNamespaceNumber | 현재 문서의 이름공간 번호를 출력합니다. |
wgPageName | 이름공간 포함한 전체 문서명을 출력합니다. |
wgRestrictionEdit | 편집이 제한된 문서의 경우 편집 가능한 권한을 출력합니다. |
wgRestrictionMove | 이동이 제한된 문서의 경우 이동 가능한 권한을 출력합니다. |
wgRevisionId | 현재 문서의 최신판 ID를 출력합니다. |
wgTitle | 이름공간을 제외한 문서명을 출력합니다. |
속성 | 설명 |
---|---|
wgUserEditCount | 편집횟수를 기록합니다. |
wgUserGroups | 사용자가 소속된 그룹을 보여줍니다. |
wgUserName | 사용자 계정명을 출력합니다. |
유용한 외부 자바스크립트[원본 편집]
외부 스크립트를 가져다 쓸 수 있습니다. 다만, 외부에서 자바스크립트를 불러오는 것은 해당 내용이 변경되었을 때 부정적인 영향[1]을 받으실 수 있기 때문에 주의하실 필요가 있습니다.
주석[2]을 이용하면 향후 유지보수가 편해질 수 있습니다.
더 많은 정보는 Wikipedia:Wikipedia:User scripts를 참조하시면 됩니다.
위키백과 공식 소도구[원본 편집]
리브레 위키에서는 특수:환경설정의 옵션으로 설정되어 있지 않지만 리브레 위키에서 호환이 가능한 스크립트 모음입니다. 리버티 스킨 기준으로 해당 기능의 호환성이 확인된 만큼 그냥 아래 스크립트를 특수:내사용자문서/common.js에 붙여넣으시면 됩니다.
//키보드 단축키 비활성화 mw.loader.load('//ko.wikipedia.org/w/index.php?title=Mediawiki:Gadget-removeAccessKeys.js&action=raw&type=text/javascript'); //대문 열면 커서 놓기 mw.loader.load('//ko.wikipedia.org/w/index.php?title=Mediawiki:Gadget-searchFocus.js&action=raw&type=text/javascript'); //토론 문서에서 서명 누락시 경고 메시지 띄우기 mw.loader.load('//ko.wikipedia.org/w/index.php?title=Mediawiki:Gadget-noSignAlert.js&action=raw&type=text/javascript'); //사용자 도구 모음에 UTC 시각 추가 - Vector, Timeless 스킨에서만 호환. mw.loader.load( '//www.mediawiki.org/w/index.php?title=MediaWiki:Gadget-UTCLiveClock.js&action=raw&ctype=text/javascript' ); //사용자 도구 모음에 현지 시각 추가 - Vector, Timeless 스킨에서만 호환 mw.loader.load( '//www.mediawiki.org/w/index.php?title=MediaWiki:Gadget-LocalLiveClock.js&action=raw&ctype=text/javascript' ); // 특수:기여 문서에 IP주소 CIDR로 검색 기능 추가 mw.loader.load( '//en.wikipedia.org/w/index.php?title=MediaWiki:Gadget-contribsrange.js&action=raw&ctype=text/javascript' );
위키백과 이용자 소도구[원본 편집]
/* 토론 문서에서 편집 시에 서명하지 않을 경우 경고 메시지를 출력하는 스크립트입니다. 한위백 IRTC1015님이 작성 */ mw.loader.load('//ko.wikipedia.org/w/index.php?title=User:IRTC1015/qSig.js&action=raw&ctype=text/javascript'); // 되돌리기 컨펌 박스 mw.loader.load('//en.wikipedia.org/w/index.php?title=User:MusikAnimal/confirmationRollback.js&action=raw&ctype=text/javascript'); // 로컬 파일 설명 안 보고 바로 공용으로 넘기기(영어 위키백과, 위키데이터에서 퍼옴) mw.loader.load('//en.wikipedia.org/w/index.php?title=MediaWiki:Gadget-imagelinks.js&action=raw&ctype=text/javascript');
예제[원본 편집]
코드가 상당히 길기에 {{숨김 시작}} 틀을 이용해서 내용을 숨겨주시기 바랍니다. 사용하실 때에는 상자 안에 있는 코드 전체를 복사한 뒤에 사용자 자바스크립트에 붙여넣기 하시면 적용이 됩니다.
문서 위/아래 버튼[원본 편집]
화면 왼쪽 아래에 맨 위로 올리거나 맨 아래로 내리는 버튼을 삽입할 수 있습니다.
{{숨김 시작}}이나 {{숨기기}} 등의 기능을 사용할 경우 숨긴 내용을 풀 경우 맨 아래로 내리는 기능이 올바르게 작동하지 않을 수 있습니다.
/* 이 스크립트는 Minecraft Wiki의 Majr의 goToTop.js를 (http://minecraftwiki.net/wiki/User:Majr/goToTop.js/) 리브레 위키의 사용자 Utolee90이 재가공해서 만들었습니다. */ /* 위로 올라가는 버튼을 만듭니다. */ $( function() { 'use strict'; $( 'body' ).append( '<span id="to-top">▲ 위</span>' ); var $topButton = $( '#to-top' ); $topButton.css( { 'font-size' : '14pt', 'background-color' : '#0077ff', 'color': '#FFF', 'position': 'fixed', 'bottom': '-30px', 'left': '4px', 'cursor': 'pointer', 'transition': 'bottom 0.5s', '-webkit-transition': 'bottom 0.5s', 'user-select': 'none', '-webkit-user-select': 'none', '-moz-user-select': 'none', '-ms-user-select': 'none' } ).click( function() { $( 'html, body' ).animate( { scrollTop: 0 }, 'slow' ); } ); /* 위에서 100픽셀 이내에 있으면 위 버튼을 숨깁니다. */ $( window ).scroll( function() { if ( $( window ).scrollTop() > 100 ) { $topButton.css( 'bottom', '4px' ); } else { $topButton.css( 'bottom', '-30px' ); } } ); } ); /* 아래 버튼을 만듭니다. */ $( function() { 'use strict'; $( 'body' ).append( '<span id="to-bottom">▼아래</span>' ); var $bottomButton = $( '#to-bottom' ); var height=document.body.scrollHeight; var hminus=height-window.innerHeight-"100"; $bottomButton.css( { 'font-size':'14pt', 'background-color':'#0077ff', 'color': '#FFF', 'position': 'fixed', 'bottom': '-30px', 'left': '42pt', 'cursor': 'pointer', 'transition': 'bottom 0.5s', '-webkit-transition': 'bottom 0.5s', 'user-select': 'none', '-webkit-user-select': 'none', '-moz-user-select': 'none', '-ms-user-select': 'none' } ).click( function() { $( 'html, body' ).animate( { scrollTop:height}, 'slow' ); } ); /*아래에서 100픽셀 이내이면 아래 버튼을 숨깁니다. */ $( window ).scroll( function() { if ( $( window ).scrollTop () <hminus ) { $bottomButton.css( 'bottom', '4px' ); } else { $bottomButton.css( 'bottom', '-30px' ); } } ); } );
Vector 스킨에서 우측 최근 바뀐 문서 보여주는 상자 만들기[원본 편집]
특수:내사용자문서/vector.js에 아래 코드를 삽입할 경우 Vector(벡터) 스킨을 사용할 때 Liberty 스킨의 최근 바뀐 문서를 한눈에 보여주는 상자를 삽입하실 수 있습니다.참조. Liberty 스킨의 최근 바뀜 상자를 만들어주는 live-recent.js 코드를 이용해서 재구성했습니다.
특수:내사용자문서/vector.js에 직접 아래 소스를 복사하거나 아니면 아래 코드를 특수:내사용자문서/vector.js에 붙여넣으시면 됩니다. 그러면 벡터 스킨을 기본 스킨으로 지정할 경우 최근에 편집한 문서를 보여주는 상자를 띄울 수 있습니다.
mw.loader.load('https://librewiki.net/index.php?title=사용자:Utolee90/recentchange.js&action=raw&ctype=text/javascript');
// 1280픽셀 이상에서만 상자가 나타나게 설정함.
var mediaViewContent = window.matchMedia('(min-width: 1280px)')
//최근 바뀜 목록 보이기 - 출처 : https://github.com/librewiki/liberty-skin/blob/master/js/live-recent.js
if (mediaViewContent.matches) {
$( function () {
$('body').append('<div id="libre-recent-vector"></div>'); // 최근 바뀜 상자
$('#libre-recent-vector').append('<div id="libre-recent-tabs"></div>'); // 최근 바뀜 상자 탭 버튼
$('#libre-recent-vector').append('<div id="recent-list-div"></div>'); // 최근 바뀜 상자 내용
$('#libre-recent-tabs').append('<div id="recent-text" class="selected">최근 문서</div>'); // 최근 문서 버튼
$('#libre-recent-tabs').append('<div id="recent-talk">최근 토론</div>'); // 최근 토론 버튼
$('#recent-list-div').append('<div class="live-recent-content"></div>'); // 최근 바뀜 내용
$('#recent-list-div').append('<div class="recent-more" title="최근 바뀜 문서">최근 바뀜 더 보기</div>'); // 더 알아보기
$('.live-recent-content').append('<ul id="live-recent-list" class="live-recent-list docupage"></div>'); // 리스트
var listNum = 10; // 목록 갯수
// 목록 갯수에 따라 오브젝트 추가
for (var j = 0; j<listNum; j++) {
$('#live-recent-list').append('<li class="recent-item-background"><span class="recent-item">'+j.toString()+'</span></li>');
$('.recent-item-background')[j].style.background= j%2 ==0 ? '#eee' : '#c1d8e1';
}
//기초 css 지정
$('#libre-recent-vector').css({"position":"fixed","top":"15%","right":"10px"});
$('#libre-recent-tabs').css({"display":"flex", "padding":"3px", "border":"1px solid grey", "background":"#ddf"});
$('#recent-text').css({"padding":"3px", "flex":"1", "background":"#417ff3", "color":"white", "font-weight":"bold", "cursor":"pointer", "textAlign":"center"});
$('#recent-talk').css({"padding":"3px", "flex":"1", "background":"white", "font-weight":"bold", "cursor":"pointer", "textAlign":"center"});
$('#recent-list-div').css({"width":"180px", "top":"auto", "right":"10px"});
$('.live-recent-list.docupage').css({"display":"block", "list-style-type": "none", "padding": "0", "margin": "0"});
$('.live-recent-content').css({"border":"1px solid grey", 'background':'#eee', 'fontSize':'0.8em'});
$('.live-recent-list.docupage>li').css({"border-collapse":"collapse"});
$('.recent-more').css({"border":"1px solid grey", "background":"#c1d8e1", "color":"#417ff3", "textAlign":"center", "cursor":"pointer", "fontWeight":"bold"}); // 더 보기 버튼
$('.recent-more').click(function(){window.location.href='//librewiki.net/wiki/특수:최근바뀜';});
//가로폭이 좁으면 content 내용 좁히기.
'use strict';
var articleNamespaces, talkNamespaces, isArticleTab, limit; //변수 지정
articleNamespaces = '0|4|10|12|14|1600|1602'; // 문서 페이지 네임스페이스 번호 지정 가능
talkNamespaces = '1|5|7|9|11|13|15|829|1601|1603|2600'; //토론 페이지 네임스페이스 번호 지정가능
isArticleTab = true; //문서 탭이 초기일 때
limit = $( '#live-recent-list' )[ 0 ].childElementCount; // id가 live-recent-list인 ul의 자식 원소인 li 갯수만큼 추출
function timeFormat( time ) { //시간 출력형태 결정
var aDayAgo, hour, minute, second;
aDayAgo = new Date();
aDayAgo.setDate( aDayAgo.getDate() - 1 ); //하루 전의 같은 시간 표시
if ( time < aDayAgo ) { //만일 하루전보다 시간이 지날 경우
return ( time.getFullYear() ) + '/' + ( time.getMonth() + 1 ) + '/' + time.getDate();
} //시간 대신 날짜로 표시
hour = time.getHours();
minute = time.getMinutes();
second = time.getSeconds();
if ( hour < 10 ) { //10보다 작으면 강제로 십의 자리에 0을 끼운다.
hour = '0' + hour;
}
if ( minute < 10 ) {
minute = '0' + minute;
}
if ( second < 10 ) {
second = '0' + second;
}
return hour + ':' + minute + ':' + second;
}
function refreshLiveRecent() {
var getParameter;
if ( !$( '#live-recent-list' ).length || $( '#live-recent-list' ).is( ':hidden' ) ) {
return; //길이가 정의 불가능이거나 내용이 숨겨져 있을 경우 내용을 출력 안 함.
}
getParameter = { //쿼리 지정할 수 있습니다.
action: 'query',
list: 'recentchanges',
rcprop: 'title|timestamp', //긁어오는 정보 - 제목, 편집시간
rcshow: '!bot|!redirect', //봇 편집, 넘겨주기는 제외
rctype: 'edit|new', //편집, 새문서
rclimit: limit, //긁어오는 문서 숫자 - limit으로 지정
format: 'json', //json으로 api 긁어오기
rcnamespace: isArticleTab ? articleNamespaces : talkNamespaces, //보여줄 이름공간 지정
rctoponly: true
};
var api = new mw.Api();
api.get( getParameter )
.then( function ( data ) {
var recentChanges, html, time, line, text;
recentChanges = data.query.recentchanges;
for (var j= 0; j<limit; j++) {
$('.recent-item-background')[j].innerHTML = '';
if (j < recentChanges.length) {
var item = recentChanges[j];
var time = new Date( item.timestamp );
var newA = document.createElement('a'); // 하이퍼링크 텍스트
newA.setAttribute('href', mw.util.getUrl(item.title));
newA.setAttribute('title', item.title);
newA.classList.add('recent-item');
var titletext = item.title.length > 13 ? item.title.slice(0,13)+'..' : item.title;
newA.innerText = '[' + timeFormat( time ) + '] ' + titletext;
// 새문서일 때
if (item.type == 'new') {
newA.style.color = '#d45';
newA.setAttribute('title', item.title+ " (NEW)");
// newA.innerHTML += ' <span class="new">' + mw.msg( 'liberty-feed-new' ) + ' </span>'; 미작동되기에 일단 지우기
}
$('.recent-item-background')[j].appendChild(newA);
}
}
})
.catch( function () {} );
}
//isArticleTab 바꿔주기
//클릭 시 표시되는 내용 지정
var rtext=$('#recent-text');
var rtalk=$('#recent-talk');
rtext.click(function(){rtext.css({"background":"#417ff3", "color":"white"});
rtalk.css({"background":"white", "color":"black"});
isArticleTab = true;
refreshLiveRecent();
}); //최근문서 배경색 파랗게, 최근문서 내용 보이고 최근토론 내용 숨김
rtalk.click(function(){rtext.css({"background":"white", "color":"black"});
rtalk.css({"background":"#417ff3", "color":"white"});
isArticleTab = false;
refreshLiveRecent(); } ); //최근토론 배경색 파랗게, 최근문서 내용 숨기고 최근토론 내용 보임
setInterval( refreshLiveRecent, 5 * 60 * 1000 );
refreshLiveRecent();
} );
}
편집 요약창 아래 편집요약 상용구 입력 버튼 추가[원본 편집]
/* 한국어 위키백과 미디어위키:Gadget-editsummary.js 호출. 사용자:Utolee90/Addbutton.js 참조 */
function esEditSummary() {
if (typeof esEditSummaries === 'undefined') return;
var wgAction = mw.config.get('wgAction');
if (wgAction == 'edit' || wgAction == 'submit') {
var wpSummary = document.getElementById('wpSummary');
if (!wpSummary || (wpSummary.form.wpSection && wpSummary.form.wpSection.value == 'new')) return;
wpSummaryButtons = document.createElement('span');
wpSummaryButtons.id = 'esSummaryButtons';
wpSummary.parentNode.insertBefore(wpSummaryButtons, wpSummary.nextSibling);
for (var i = 0; i < esEditSummaries.length; i++) esAppendButton(i);
}
}
function esAppendButton(id) { // 버튼 추가하는 함수
var btn = document.createElement('esSummaryButton');
btn.appendChild(document.createTextNode(esEditSummaries[id][0]));
btn.title = esEditSummaries[id][2];
btn.onclick = function() {esInsertSummary(esEditSummaries[id][1], esEditSummaries[id][3], esEditSummaries[id][4])};
wpSummaryButtons.appendChild(btn);
}
function esInsertSummary(text, isMinor, clear) {
var wpSummary = document.getElementById('wpSummary');
if (isMinor !== undefined) { $('#wpMinoredit').prop('checked', isMinor, clear); }
if (clear == 1) {
wpSummary.value = text;
return;
}
if (wpSummary.value.indexOf(text) != -1) return ;
if (wpSummary.value.match(/[^,; \/]$/)) wpSummary.value += ',';
if (wpSummary.value.match(/[^ ]$/)) wpSummary.value += ' ';
wpSummary.value += text;
}
jQuery( document ).ready(esEditSummary);
esEditSummaries = new Array(
/*
new Array('버튼 이름', '입력될 편집 요약', '툴팁으로 뜨는 설명(생략 가능)', '사소한 편집 여부(0/1 혹은 true/false, 생략 가능)', '상용구 넣기 전에 요약 지우기(0/1 혹은 true/false, 생략 가능)')
위와 같은 형식으로 새로운 버튼을 추가할 수 있습니다.
마지막 줄을 제외한 줄 끝에 쉼표가 들어가 있는지 확인해 주세요.
*/
// 예시 -
new Array('오타','오타 수정','문서에서 오타를 정정함', 0, 1)
);
사용자 활동 상태를 알려주는 스크립트[원본 편집]
아래의 코드 혹은
mw.loader.load('//librewiki.net/index.php?title=사용자:Utolee90/status.js&action=raw&ctype=text/javascript');
를 특수:내사용자문서/common.js에 입력하시면 div 태그 안에 사용자 문서의 주인의 편집상태를 확인할 수 있습니다.
// 소스 원본 : 사용자:Utolee90/status.js
// 사용 방법 : 다음 소스코드를 "특수:내사용자문서/common.js" 에 복사하시면 사용자 문서의 주인의 현재 편집 상태 또는 차단 여부를 확인하실 수 있습니다.
// mw.loader.load('//librewiki.net/index.php?title=사용자:Utolee90/status.js&action=raw&ctype=text/javascript');
let username = mw.config.get('wgTitle').split("/")[0];
var params = {
action: 'query',
list: ['blocks','recentchanges'] ,
utf8 : 1,
bkusers : username,
bklimit: '1',
rclimit: '1',
rcuser: username,
format: 'json'
},
api = new mw.Api(); // api 얻기
api.get( params ).done( function ( data ) {
var bk = data.query.blocks; // 차단 목록 확인
var rc = data.query.recentchanges; //최근 바뀜 목록 확인
if (mw.config.get('wgNamespaceNumber') == 2) {
if (bk.length != 0) { // 차단 목록이 존재할 때...
var bkt = (bk[0].expiry == 'infinity')? 'infinity' :new Date(bk[0].expiry);
var bktstring = (bkt == 'infinity')? '무기한': (bkt.getFullYear()+'년 '+(bkt.getMonth()+1)+'월 '+(bkt.getDate())+'일')
$('#mw-content-text').prepend('<div id="user-status-infos"><img src="https://upload.wikimedia.org/wikipedia/commons/thumb/4/42/Stop_x_nuvola.svg/40px-Stop_x_nuvola.svg.png" width=40 /> <span class="status-text">차단된 사용자 </span> <small>차단기한 : '+bktstring+'</div>');
}
else if (rc.length == 0){ // 최근 바뀜 폭록이 없을 때
$('#mw-content-text').prepend('<div id="user-status-infos"><img src="https://image.librewiki.net/f/f9/Ledibug2.png" width=40 /> <span class="status-text">3개월간 활동하지 않는 사용자.</span></div>');
}
else {
var x = rc[0].timestamp; // 마지막 편집 시간 확인
var at = new Date(x); //시간 데이터 추출
var now = new Date().getTime(); //현재시간 getTime
if (now-at.getTime() <=3600*1000){ // 마지막 편집이 최근 1시간 이후.
$('#mw-content-text').prepend('<div id="user-status-infos"><img src="https://image.librewiki.net/4/47/Ledibug-Louis-Fact.png" width=40 /> <span class="status-text">편집중 </span> <small>마지막 편집 시간 :'+' '+at.getHours()+'시 '+at.getMinutes()+'분</small></div>');
}
else if(now-at.getTime()<=24*3600*1000) { // 마지막 편집이 최근 24시간 이전
$('#mw-content-text').prepend('<div id="user-status-infos"><img src="https://image.librewiki.net/8/8b/Ledibug-Lucy-False.png" width=40 /> <span class="status-text">휴식중 </span><small>마지막 편집 시간 :'+at.getHours()+'시 '+at.getMinutes()+'분</small></div>');
}
else {
$('#mw-content-text').prepend('<div id="user-status-infos"><img src="https://image.librewiki.net/8/8b/Ledibug-Lucy-False.png" width=40 /> <span class="status-text">휴식중 </span> <small>마지막 편집 날짜 : '+(at.getMonth()+1)+'월 '+(at.getDate())+'일</small></div>');
}
}
}
}
);
민감한 내용 경고를 주는 스크립트[원본 편집]
어린이가 있는 집의 전자기기나 가족이 쓰는 컴퓨터 등에서 쓰면 좋습니다.
if (mw.config.get('wgCategories')[mw.config.get('wgCategories').indexOf("애드센스 제외 문서")] == "애드센스 제외 문서" && mw.config.get('wgNamespaceNumber') ==0 )
{
alert('이 문서에는 사회풍속상 민감한 내용이 있습니다. 읽을 때 주의하시기 바랍니다.');
}
편잡창 위에 최종 편집자 정보 띄우는 스크립트[원본 편집]
아래 숨겨진 코드 혹은
//최종 편집 상태 나타내기
mw.loader.load('//librewiki.net/index.php?title=사용자:Utolee90/lastedit.js&action=raw&ctype=text/javascript');
코드를 특수:내사용자문서/common.js에 붙이면 편집창 오른쪽 위에 최종 편집자와 최종 편집시간, 변화 내용을 확인할 수 있습니다.
// 사용자:Utolee90/lastedit.js에서 가져옴
// 사용 방법 : 자산의 사용자 자바스크립트 문서에 주석기호 '//'를 빼고 아래 문구를 입력하시면 사용가능합니다.
// mw.loader.load('//librewiki.net/index.php?title=사용자:Utolee90/lastedit.js&action=raw&ctype=text/javascript');
var a_title = mw.config.get('wgPageName');
var params_1 = {
action: 'query',
prop: 'revisions',
utf8 : 1,
titles : a_title,
rvlimit : 1,
format: 'json'
},
api_1 = new mw.Api(); // api 얻기
api_1.get( params_1 ).done( function ( data ) {
const addZero = (i) => { // 0함수 추가
if (parseInt(i) < 10) {
i = "0" + i;
}
return i+"";
};
if (mw.config.get('wgAction') === 'view' && mw.config.get('wgNamespaceNumber') > -1) {
const rv_data = data.query.pages; // 리비전 확인
const page_id = parseInt(Object.keys(rv_data)[0]); // PageID 형식으로 출력.
let $status_info = $('<div id="document-status-infos"></div>');
$('#mw-content-text').prepend($status_info);
const rv_status = rv_data[page_id]['revisions'][0]; // 최근 리비전 상태 출력
const rv_last_edit = new Date(rv_status.timestamp); // 마지막 변경 시점.
const day_char_list = ['일','월','화','수','목','금','토'];
const rv_year = (rv_last_edit.getFullYear())+'년 ';
const rv_month = (rv_last_edit.getMonth()+1)+'월 ';
const rv_date = (rv_last_edit.getDate())+'일 (';
const rv_day = day_char_list[parseInt(rv_last_edit.getDay())];
const rv_hour = ') '+addZero(rv_last_edit.getHours());
const rv_minute =':'+addZero(rv_last_edit.getMinutes());
const rv_last_time = rv_year+rv_month+rv_date+rv_day+rv_hour+rv_minute; // 날짜 문자열 표시
rv_last_link_text = 'https://librewiki.net/index.php?title='+a_title+'&diff=prev&oldid='+rv_status.revid;
$status_info.html('<small>'+rv_status.user+'에 의해 '+rv_last_time+'에 <a href="'+rv_last_link_text+'"> 마지막으로 편집됨</small>').css({'text-align':'right'});
}
}
);
커스텀 문자입력셋[원본 편집]
편집창 아래에 문자 입력셋을 만들어줍니다. 사용할 때에는 아래 스크립트를 특수:내사용자문서/common.js에 저장하거나 자신의 사용자 문서에 적절한 하위 문서를 만든 뒤 특수:내사용자문서/common.js에 아래와 같은 코드를 입력하시면 됩니다.
// 편집창 아래 커스텀 문자입력셋
mw.loader.load('//librewiki.net/index.php?title=(스크립트 저장한 파일명)&action=raw&ctype=text/javascript');
syntaxhighlight 태그 간섭에 의해 문서가 깨지는 것을 방지하기 위해 스크립트 내부의 </syntaxhighlight> 태그의 / 앞부분에 \ 기호를 첨가해서 대체했습니다. 실제 사용하실 때에는 / 앞에 \ 기호를 지우시면 됩니다.
/**
* 원본 [[mw:User:Alex Smotrov/edittools.js]], 수정본 리브레 위키 이용자 Cerulean, Utolee90
*
* Configuration (to be set from [[Special:MyPage/common.js]]):
* window.charinsertCustom – Object. Merged into the default charinsert list. For example, setting
* this to { Symbols: '‽' } will add the interrobang to the end of the Symbols section.
* window.editToolsRecall – Boolean. Set true to create a recall switch.
* window.charinsertDontMove – Boolean. Set true to leave the box in its default position, rather
* than moving it above the edit summary.
* window.updateEditTools() – Function. Call after updating window.charinsertCustom to regenerate the
* EditTools window.
*/
/* global jQuery, mw, charinsertCustom */
/*window.updateEditTools = function () {
};*/
jQuery( document ).ready( function ( $ ) {
var $currentFocused, editTools;
function getSelectedSection() {
var selectedSection = mw.storage.get( editTools.storageKey )
|| mw.storage.session.get( editTools.storageKey );
return selectedSection;
}
function saveSelectedSection( newIndex ) {
mw.storage.set( editTools.storageKey, newIndex )
|| mw.storage.session.set( editTools.storageKey, newIndex );
}
editTools = {
// 각 심볼은 '카테고리 이름' : '문자셋 이름', 형태로 작성합니다. 자바스크립트 오브젝트 형식으로 처리하므로 반드시 카테고리 이름, 문자셋 이름 앞뒤로 따옴표를 추가하고, 맨 뒤에는 반점(,)으로 구분하셔야 합니다.
// 카테고리를 구별할 때에는 문자셋 이름 부분에 (카테고리명): 기호를 추가합니다.
// 심볼을 구분할 때에는 띄어쓰기를 이용하며, 같은 심볼 안에서 공백을 입력할 때에는 온점 .을 이용합니다. 단 =기호 이후에는 .을 입력하면 온점이 입력되는 현상이 있어 공백을 삽입할 때 _기호를 사용합니다.
// 버튼 형태로 심볼을 분리할 때에는 _기호를 사용하면 됩니다.
// + 기호를 입력하면 심볼을 입력할 때 커서가 위치하는 지점을 지정할 수 있습니다.
// 줄넘김을 표현할 때에는 \n을 삽입합니다. 반드시 뒤에 공백을 띄워줘야 제대로 작동합니다.
// 정규표현식으로 처리하므로 중괄호 여는 기호 {나 대괄호 여는 기호 [를 입력하기 위해서는 앞에 \ 기호를 써서 \{, \[라고 사용해야 합니다. 닫을 때에는 알아서 처리하므로 \ 기호를 삽입할 필요는 없습니다.
// 예시 : 다른 뜻 틀 삽입 => \{\{다른.뜻|+}}
// 기호 앞에 ␥ (U+2425 SYMBOL FOR DELETE FORM TWO)이 붙어있으면 메인 이름공간(0번)에서는 표시되지 않습니다.
// 이 오브젝트 안에 '카테고리 이름' : '문자셋 이름' 형태로 작성하면 됩니다.
charinsert: {
'기본': '괄호: (+) [+] {+} 〔+〕 〈+〉 【+】 \n 위키텍스트: \{{크기||+}} [\[+]] {\{+}} <!--.+.--> /*.+.*/ [\[분류:+]] [\[파일:+]] <del>+</del> <br /> {\{-}} {\{각주}} <ref>+</ref> {\{lang||+}} {\{llang||+}} __TOC__ {\{PAGENAME}} {\{삭제|+}} {\{유튜브|+}} {\{퍼온문서|문서=+|판=_|일부=_}} {\{번역된.문서|en|+||}} {\{string|+}} {\{배지|+}}',
'틀' : '{\{\{+}}} {\{\{+|}}} <onlyinclude>+</onlyinclude> <includeonly>+</includeonly> <noinclude>+</noinclude> {\{풀기:+}} \n 파서함수: {\{#expr:+}} {\{#if:+}} {\{#ifeq:+}} {\{#iferror:+}} {\{#ifexist:+}} {\{#switch:+}} {\{#time:+}} {\{#titlepart:+}} {\{#invoke:+|}}',
'HTML 태그': '<div>+</div> <div.id="".class="">+</div> <span>+</span> <span.id="".class="">+</span> <code>+</code> <pre>+</pre> <syntaxhighlight.lang="console">\n+\n<\/syntaxhighlight> <ref.name="+"_/>',
'기호': '~ | ¡¿†‡↔↑↓•¶#∞ 〈+〉 《+》 ‘+’ “+” ‹+› «+» ¤₳฿₵¢₡₢$₫₯€₠₣ƒ₴₭₤ℳ₥₦№₧₰£៛₨₪৳₮₩¥ ♠♣♥♦ ♭♯♮ ©®™ ◌',
'로마자': 'A a Á á À à  â Ä ä Ǎ ǎ Ă ă Ā ā à ã Å å Ą ą Æ æ Ǣ ǣ B b C c Ć ć Ċ ċ Ĉ ĉ Č č Ç ç D d Ď ď Đ đ Ḍ ḍ Ð ð E e É é È è Ė ė Ê ê Ë ë Ě ě Ĕ ĕ Ē ē Ẽ ẽ Ę ę Ẹ ẹ Ɛ ɛ Ǝ ǝ Ə ə F f G g Ġ ġ Ĝ ĝ Ğ ğ Ģ ģ H h Ĥ ĥ Ħ ħ Ḥ ḥ I i İ ı Í í Ì ì Î î Ï ï Ǐ ǐ Ĭ ĭ Ī ī Ĩ ĩ Į į Ị ị J j Ĵ ĵ K k Ķ ķ L l Ĺ ĺ Ŀ ŀ Ľ ľ Ļ ļ Ł ł Ḷ ḷ Ḹ ḹ M m Ṃ ṃ N n Ń ń Ň ň Ñ ñ Ņ ņ Ṇ ṇ Ŋ ŋ O o Ó ó Ò ò Ô ô Ö ö Ǒ ǒ Ŏ ŏ Ō ō Õ õ Ǫ ǫ Ọ ọ Ő ő Ø ø Œ œ Ɔ ɔ P p Q q R r Ŕ ŕ Ř ř Ŗ ŗ Ṛ ṛ Ṝ ṝ S s Ś ś Ŝ ŝ Š š Ş ş Ș ș Ṣ ṣ ß T t Ť ť Ţ ţ Ț ț Ṭ ṭ Þ þ U u Ú ú Ù ù Û û Ü ü Ǔ ǔ Ŭ ŭ Ū ū Ũ ũ Ů ů Ų ų Ụ ụ Ű ű Ǘ ǘ Ǜ ǜ Ǚ ǚ Ǖ ǖ V v W w Ŵ ŵ X x Y y Ý ý Ŷ ŷ Ÿ ÿ Ỹ ỹ Ȳ ȳ Z z Ź ź Ż ż Ž ž ß Ð ð Þ þ Ŋ ŋ Ə ə',
'그리스 문자': 'ΆάΈέΉήΊίΌόΎύΏώ ΑαΒβΓγΔδ ΕεΖζΗηΘθ ΙιΚκΛλΜμ ΝνΞξΟοΠπ ΡρΣσςΤτΥυ ΦφΧχΨψΩω Ϝϝυ̯ι̯ ᾼᾳᾴᾺὰᾲᾶᾷἈἀᾈᾀἉἁᾉᾁἌἄᾌᾄἊἂᾊᾂἎἆᾎᾆἍἅᾍᾅἋἃᾋᾃἏἇᾏᾇ ῈὲἘἐἙἑἜἔἚἒἝἕἛἓ ῌῃῄῊὴῂῆῇἨἠᾘᾐἩἡᾙᾑἬἤᾜᾔἪἢᾚᾒἮἦᾞᾖἭἥᾝᾕἫἣᾛᾓἯἧᾟᾗ ῚὶῖἸἰἹἱἼἴἺἲἾἶἽἵἻἳἿἷΪϊΐῒῗ ῸὸὈὀὉὁὌὄὊὂὍὅὋὃ ῤῬῥ ῪὺῦὐὙὑὔὒὖὝὕὛὓὟὗΫϋΰῢῧ ῼῳῴῺὼῲῶῷὨὠᾨᾠὩὡᾩᾡὬὤᾬᾤὪὢᾪᾢὮὦᾮᾦὭὥᾭᾥὫὣᾫᾣὯὧᾯᾧ ᾹᾱᾸᾰῙῑῘῐῩῡῨῠ {{lang|el|+}} {{lang|grc|+}}',
'키릴 문자': 'АаБбВвГг ҐґЃѓДдЂђ ЕеЁёЄєЖж ЗзЅѕИиІі ЇїЙйЈјКк ЌќЛлЉљМм НнЊњОоПп РрСсТтЋћ УуЎўФфХх ЦцЧчЏџШш ЩщЪъЫыЬь ЭэЮюЯя ӘәӨөҒғҖҗ ҚқҜҝҢңҮү ҰұҲҳҸҹҺһ ҔҕӢӣӮӯҘҙ ҠҡҤҥҪҫӐӑ ӒӓӔӕӖӗӰӱ ӲӳӸӹӀ ҞҟҦҧҨҩҬҭ ҴҵҶҷҼҽҾҿ ӁӂӃӄӇӈӋӌ ӚӛӜӝӞӟӠӡ ӤӥӦӧӪӫӴӵ ́',
'IPA (영어)': 'ˈ ˌ ŋ ɡ tʃ dʒ ʃ ʒ θ ð ʔ ɑː ɒ æ aɪ aʊ ɛ eɪ ɪ iː ɔː ɔɪ oʊ ʊ uː ʌ ɜr ə ər ᵻ ᵿ ɒ̃ æ̃ {\{angle.bracket|+}} {\{IPA|+}} {\{IPA.링크|+}}',
'IPA': '닿소리: ɱɳɲŋɴ : t̪ d̪ ʈɖɟɡɢʡʔ : ɸβθð ʃʒʂʐɕʑ çʝɣχʁ ħʕʜʢɦɧ : ʋɹɻɥɰʍ : ʙⱱɾɽʀ ɺ ɫɬɮɭʎʟ : ɓɗᶑʄɠʛ ʘǀǃǂǁ \n 홀소리: ɪʏɨʉɯʊ : øɘɵɤ ə ɚ ɛœɜɝɞʌɔ : æɶɐɑɒ \n Spacing_diacritics: ˈˌːˑʼˀˤᵝᵊᶢˠʰʱʲˡⁿᵑʷᶣ˞‿˕˔ \n Combining_diacritics: ̚ ̪ ̺ ̻ ̼ ̬ ̊ ̥ ̞ ̝ ̘ ̙ ̽ ̟ ̠ ̈ ̤ ̹ ̜ ̍ ̩ ̆ ̯ ̃ ̰ ͡ ͜ \n 성조: ̋ ́ ̄ ̀ ̏ ̌ ̂ ᷄ ᷅ ᷇ ᷆ ᷈ ᷉ ˥˦˧˨˩ꜛꜜ : ↗↘‖ \n extIPA: ͈ ͉ ͎ ̣ ̫ ͊ ᷽ ͇ : ˭ᵻᵿ {\{angle.bracket|+}} {\{IPA|+}} {\{IPA.링크|+}}',
'수학·논리학': '− × ÷ ⋅ ° ∗ ∘ ± ∓ ≤ ≥ ≠ ≡ ≅ ≜ ≝ ≐ ≃ ≈ ⊕ ⊗ ⇐ ⇔ ⇒ ∞ ← ↔ → ≪ ≫ ∝ √ ∤ ≀ ◅ ▻ ⋉ ⋊ ⋈ ∴ ∵ ↦ ¬ ∧ ∨ ⊻ ∀ ∃ ∈ ∉ ∋ ⊆ ⊈ ⊊ ⊂ ⊄ ⊇ ⊉ ⊋ ⊃ ⊅ ∪ ∩ ∑ ∏ ∐ ′ ∫ ∬ ∭ ∮ ∇ ∂ ∆ ∅ ℂ ℍ ℕ ℙ ℚ ℝ ℤ ℵ ⌊ ⌋ ⌈ ⌉ ⊤ ⊥ ⊢ ⊣ ⊧ □ ∠ ⟨ ⟩ <math>+</math> \{\{첨자|위=+|아래=}} '
},
// 문자열 나누는 기호
charinsertDivider: "\240",
storageKey: 'edittoolscharsubset',
createEditTools: function ( placeholder ) {
var sel, id;
var box = document.createElement( 'div' );
var prevSubset = 0, curSubset = 0;
box.id = 'editpage-specialchars';
box.className = "nopopups";
// 문자 선택시 나타나는 제목 이름
box.title = '편집 창에 입력할 글자 혹은 태그를 클릭하세요';
// append user-defined sets
if ( window.charinsertCustom ) {
for ( id in charinsertCustom ) {
if ( !editTools.charinsert[id] ) {
editTools.charinsert[id] = '';
}
}
}
// 문자셋 드랍다운 메뉴를 만듭니다.
sel = document.createElement( 'select' );
for ( id in editTools.charinsert ) {
sel.options[sel.options.length] = new Option( id, id );
}
sel.selectedIndex = 0;
sel.style.marginRight = '.3em';
// 입력상자 타이틀
sel.title = 'Choose character subset';
sel.onchange = sel.onkeyup = selectSubset;
box.appendChild( sel );
// create "recall" switch
if ( window.editToolsRecall ) {
var recall = document.createElement( 'span' );
recall.appendChild( document.createTextNode( '↕' ) ); // ↔
recall.onclick = function() {
sel.selectedIndex = prevSubset;
selectSubset();
};
recall.style.cssFloat = 'left';
recall.style.marginRight = '5px';
recall.style.cursor = 'pointer';
box.appendChild( recall );
}
if ( getSelectedSection() ) {
sel.selectedIndex = getSelectedSection();
}
placeholder.parentNode.replaceChild( box, placeholder );
selectSubset();
return;
function selectSubset() {
// remember previous (for "recall" button)
prevSubset = curSubset;
curSubset = sel.selectedIndex;
//save into web storage for persistence
saveSelectedSection( curSubset );
//hide other subsets
var pp = box.getElementsByTagName( 'p' ) ;
for ( var i = 0; i < pp.length; i++ ) {
pp[i].style.display = 'none';
}
//show/create current subset
var id = sel.options[curSubset].value;
var p = document.getElementById( id );
if ( !p ) {
p = document.createElement( 'p' );
p.className = 'nowraplinks';
p.id = id;
if ( id == 'Arabic' || id == 'Hebrew' ) {
p.style.fontSize = '120%';
p.dir = 'rtl';
}
var tokens = editTools.charinsert[id];
if ( window.charinsertCustom && charinsertCustom[id] ) {
if ( tokens.length > 0 ) {
tokens += ' ';
}
tokens += charinsertCustom[id];
}
editTools.createTokens( p, tokens );
box.appendChild( p );
}
p.style.display = 'inline';
}
},
createTokens: function ( paragraph, str ) {
var tokens = str.split( ' ' ), token, i, n;
for ( i = 0; i < tokens.length; i++ ) {
token = tokens[i];
n = token.indexOf( '+' );
if ( token.charAt( 0 ) === '␥' ) {
if ( token.length > 1 && mw.config.get( 'wgNamespaceNumber' ) === 0 ) {
continue;
} else {
token = token.substring( 1 );
}
}
if ( token === '' || token === '_' ) {
addText( editTools.charinsertDivider + ' ' );
} else if ( token === '\n' ) {
paragraph.appendChild( document.createElement( 'br' ) );
} else if ( token === '___' ) {
paragraph.appendChild( document.createElement( 'hr' ) );
} else if ( token.charAt( token.length-1 ) === ':' ) { // : at the end means just text
addBold( token );
} else if ( n === 0 ) { // +<tag> -> <tag>+</tag>
addLink( token.substring( 1 ), '</' + token.substring( 2 ), token.substring( 1 ) );
} else if ( n > 0 ) { // <tag>+</tag>
addLink( token.substring( 0, n ), token.substring( n+1 ) );
} else if ( token.length > 2 && token.charCodeAt( 0 ) > 127 ) { // a string of insertable characters
for ( var j = 0; j < token.length; j++ ) {
addLink( token.charAt( j ), '' );
}
} else {
addLink( token, '' );
}
}
return;
function addLink( tagOpen, tagClose, name ) {
var handler;
var dle = tagOpen.indexOf( '\x10' );
var a = document.createElement( 'a' );
if ( dle > 0 ) {
var path = tagOpen.substring( dle + 1 ).split( '.' );
tagOpen = tagOpen.substring( 0, dle );
handler = window;
for ( var i = 0; i < path.length; i++ ) {
handler = handler[path[i]];
}
$( a ).on( 'click', handler );
} else {
tagOpen = tagOpen.replace( /\./g,' ' );
tagClose = tagClose ? tagClose.replace( /_/g,' ' ) : '';
$( a ).on( 'click', {
tagOpen: tagOpen,
sampleText: '',
tagClose: tagClose
}, insertTags );
}
name = name || tagOpen + tagClose;
name = name.replace( /\\n/g,'' );
a.appendChild( document.createTextNode( name ) );
a.href = '';
paragraph.appendChild( a );
addText( ' ' );
}
function addBold( text ) {
var b = document.createElement( 'b' );
b.appendChild( document.createTextNode( text.replace( /_/g,' ' ) ) );
paragraph.appendChild( b );
addText( ' ' );
}
function addText( txt ) {
paragraph.appendChild( document.createTextNode( txt ) );
}
function insertTags( e ) {
e.preventDefault();
if ( $currentFocused && $currentFocused.length && !$currentFocused.prop( 'readonly' ) ) {
$currentFocused.textSelection(
'encapsulateSelection', {
pre: e.data.tagOpen,
peri: e.data.sampleText,
post: e.data.tagClose
}
);
}
}
},
setup: function () {
var placeholder;
if ( $( '#editpage-specialchars' ).length ) {
placeholder = $( '#editpage-specialchars' )[0];
} else {
placeholder = $( '<div id="editpage-specialchars"> </div>' ).prependTo( '.mw-editTools' )[0];
}
if ( !placeholder ) {
return;
}
if ( !window.charinsertDontMove ) {
$( '.editOptions' ).before( placeholder );
}
// Find the element that is focused
$currentFocused = $( '#wpTextbox1' );
// Apply to dynamically created textboxes as well as normal ones
$( document ).on( 'focus', 'textarea, input:text', function () {
$currentFocused = $( this );
} );
// Used to determine where to insert tags
editTools.createEditTools( placeholder );
window.updateEditTools = function () {
editTools.createEditTools( $( '#editpage-specialchars' )[0] );
};
}
}; // end editTools
editTools.setup();
} );
이 소스에 디자인을 추가하려면 다음과 같은 소스를 특수:내사용자문서/common.css에 추가하시면 됩니다.
/* 참조: 사용자:Cerulean/EditTools.css */
/* 사용자 소스 추가 영역 */
div#editpage-specialchars {
display: block;
padding: .5em 1em;
}
/* 선택상자, 버튼 공통 디자인 */
#editpage-specialchars a, #editpage-specialchars select {
border: 1px solid #ddd;
background-color: #f9f9f9;
padding: 4px 8px;
border-radius: 20px;
}
/* 버튼 디자인 */
#editpage-specialchars a {
display: inline-block;
margin-top: 4px;
}
/* 선택상자 디자인 */
#editpage-specialchars select {
width:100%;
margin-right: 0.3em;
appearance: none;
}
리버티 스킨용 브레드크럼[원본 편집]
원래 Libre 스킨용으로 제작된 브레드크럼(최근 읽은 문서 목록)은(참조: 미디어위키:Gadget-BreadCrumb.js) 리버티 스킨용으로 지원하지 않습니다. 따라서 리버티 스킨용으로 브레드크럼을 사용하기 위해서는 특수:내사용자문서/liberty.js에 아래와 같은 소스를 입력하시면 됩니다. 사이트 공지 상자 아래, 상단 광고 위에 목록이 삽입됩니다. 참고로 원 소스와는 다르게 최근 10개 문서만 저장하며, 중복으로 문서명이 나타나지 않습니다.
// 리버티 스킨용 브레드크럼
mw.loader.load('//librewiki.net/index.php?title=사용자:Utolee90/BreadCrumb.js&action=raw&ctype=text/javascript');
원 소스를 활용하고 싶으시면 아래 소스를 이용하시면 됩니다.
/*
* written By. LiteHell and modified by Utolee90
* Warning : This script uses localStorage of your browser so BREADCUMB WILL BE DELETED IF YOU CLEAR STORAGE DATA FROM YOUR BROWSER.
*/
if (mw.config.exists("wgIsArticle") && mw.config.exists("wgPageName") && mw.config.exists("wgArticlePath")) {
var conf = mw.config.get(["wgIsArticle", "wgPageName", "wgArticlePath"]);
if (conf.wgIsArticle) {
var itemName = "pageBreadcumbs";
function initStorageIfRequired() {
if (localStorage.getItem(itemName) == null)
localStorage.setItem(itemName, "[]");
}
function setStorage(value) {
initStorageIfRequired();
localStorage.setItem(itemName, JSON.stringify(value.slice(-20)));
}
function getStorage() {
initStorageIfRequired();
return JSON.parse(localStorage.getItem(itemName));
}
function makeBreadBar(arr, active) {
var ol = document.createElement("ol");
ol.className = "breadcrumb";
ol.style.display = "inline-block"; // 내용에 따라 높이 자동조절할 수 있게 속성 부여
ol.innerHTML = '<li id="cleanBreads"><a href="javascript:(function(){})();" style="color: red;"><span class="fa fa-trash"></span></a></li>';
ol.querySelector('li#cleanBreads > a').addEventListener("click", function() {
if (confirm("진짜로 빵가루를 전부다 청소할까요?")) {
localStorage.setItem(itemName, "[]");
alert('강제 새로고침하면 지워져 있을겁니다. :)');
}
});
// 최근 10개만 역순으로 제작. 중복이 있으면 제외
var limitCnt = 10;
var newArr = [];
var j = 0;
while (newArr.length < Math.min(limitCnt, arr.length) && j<=arr.length-1) {
if (newArr.indexOf(arr[arr.length-1-j]) ==-1) {
newArr.push(arr[arr.length-1-j]);
}
j++;
}
for (var i = 0; i < newArr.length; i++) {
var now = newArr[i];
var li = document.createElement("li");
if (now == active) {
li.className = "active";
li.textContent = now;
} else {
var anchor = document.createElement("a");
anchor.href = conf.wgArticlePath.replace('$1', now);
anchor.title = now;
anchor.textContent = now;
li.appendChild(anchor);
}
ol.appendChild(li);
}
return ol;
}
var articles = getStorage();
if(articles.length == 0 || (articles.length != 0 && articles[articles.length - 1] != conf.wgPageName)) articles.push(conf.wgPageName);
setStorage(articles, conf.wgPageName);
var breadbar = makeBreadBar(articles, conf.wgPageName);
var headerAds = document.querySelector(".header-ads");
headerAds.parentNode.insertBefore(breadbar, headerAds); // 광고 위에 삽입하기
}
}
리버티 스킨용 사용자 정의 내비게이션 바[원본 편집]
리버티 스킨에서 기존의 아이콘을 제거하거나 새로운 아이콘을 추가할 수 있습니다. 아래 스크립트는 드롭다운 메뉴나 내비게이션 바의 링크만 추가할 수 있으며, 드롭다운 메뉴 자체를 추가하는 기능은 추후 작성할 예정입니다.
이 스크립트는 현재 고정된 URL만 정의할 수 있습니다. 랜덤 한자 문서처럼 URL이 랜덤으로 변동하는 것을 지원하려면 스크립트를 별도로 작성하셔야 합니다. 사:하늘/custom-navbar.js 파일을 참조하시면 됩니다.
이 스크립트를 실행시키기 위해서는 JSON 파일이 필요합니다. 우선 특수:내사용자문서/custom-navbar-data.json 파일을 아래와 같은 형식으로 작성합니다. JSON 파일이기에 주석은 사용할 수 없다는 점에 유의해주세요.
{
"explanation" : {
"addList 양식" : "[(font-awesome 아이콘 클래스명), (표시될 링크 이름), (링크 주소), (링크 타이틀-title) ]",
"dropList" : "기존에 있는 삭제할 링크 목록",
"addList" : "추가할 메뉴 목록",
"addDropdown": "추가할 드랍다운 메뉴 목록 (현재 미지원)"
},
"dropList": ["map", "menuWatch"],
"addList": {
"user" : [
["fa-star", " 공작실 ", "/wiki/사용자:Utolee90/공작실", "내 작업물"],
["fa-font", " 영한사전 ", "/wiki/시리즈:모두의 영한사전", ""]
],
"board": [
["fa-globe", " 큰숲백과 ", "https://bigforest.miraheze.org/", "큰숲백과"]
],
"tools": [],
"help": [
["fa-code", "사용자 JS", "/wiki/도움말:사용자 자바스크립트", "사용자 자바스크립트 도움말"],
["fa-code", "사용자 CSS", "/wiki/도움말:사용자 CSS", "사용자 CSS 도움말"]
],
"new": [
["fa-file", "큰숲백과 문서", "/wiki/큰숲백과", "큰숲백과 문서"]
]
},
"addDropdown": {
"head": [],
"navList": []
}
}
다음에 아래 코드를 특수:내사용자문서/liberty.js에 집어넣으면 작동이 완료됩니다.
/* 리버티 스킨 네비게이션 사용자 아이콘 */
mw.loader.load('//librewiki.net/index.php?title=사용자:Utolee90/custom-navbar.js&action=raw&ctype=text/javascript');
아래는 이 스크립트의 원본입니다.
// 원본 : 사용자:하늘/custom-navbar.js, 수정 : 사용자:Utolee90
// custom-navbar-data 불러오기 -> navBarData 형식으로 값이 호출됨.
var dataPageName = "User:" + mw.config.get().wgUserName + "/custom-navbar-data.json"; // custom-navbar-data 파일이름
// json 파일 RAW 데이터를 얻기 위해서 필요
function getRaw(title) {
var raw;
$.ajax({
async: false,
url: location.origin + mw.util.getUrl(title || mw.title, { action: 'raw' }),
success: function (data) { raw = data; }
});
return raw;
}
// 아이템 추가
var libreNavLogin = {};
// json 파일 파싱
libreNavLogin.navBarData = JSON.parse(getRaw(dataPageName));
// 제거할 메뉴 : 메뉴 타이틀명
libreNavLogin.titleMap2 = {
"RC": "위키의 최근 바뀐 목록 [alt-shift-r]", // 최근 바뀜 메뉴
"random": "무작위로 선택된 문서 불러오기 [alt-shift-x]", // 임의 문서 메뉴
"map": "https://maps.librewiki.net/", // 리브레 맵스 메뉴
"board": "게시판", // 게시판 메뉴(드롭다운)
"wikiBoard": "https://bbs.librewiki.net/", // 위키 게시판(하위 링크)
"freeBoard": "https://bbs.librewiki.net/freeboard", //자유 게시판(하위 링크)
"tools": "도구", // 도구(드롭다운)
"special": "특수:특수문서", // 특수문서(하위링크)
"upload": "특수:올리기", // 업로드(하위 링크)
"help": "도움말", // 도움말(드롭다운)
"summary": "리브레_위키:도움말", // 위키 도움말(하위 링크)
"syntax": "도움말:위키_문법", // 위키 문법(하위 링크)
"Tex": "도움말:TeX_문법", // TeX 문법(하위 링크)
"menuMy": "내 사용자 문서 [alt-shift-.]", // 내 사용자 문서
"menuEcho": "당신의 알림", // 알림 (사용자 메뉴)
"menuContribution": "내 기여 목록 [alt-shift-y]", // 내 기여 목록
"menuTalk": "내 토론 문서 [alt-shift-n]", // 내 토론 문서
"menuWatch": "주시문서에 대한 바뀜 목록 [alt-shift-l]", // 주시문서 목록
"menuSettings": "사용자 환경 설정", // 환경 설정
};
// 아이템 생성 방법
libreNavLogin.createItem = function(icon, title, url, desc, isMenu=false) {
var a = document.createElement('a'); // 링크 추가
var iconHTML = document.createElement('span'); // icon 추가
iconHTML.className = "fa "+icon;
iconHTML.style.color = isMenu? 'inherit' :'#373a3c'; // 색상 변경
iconHTML.style.fontSize = isMenu? 'inherit' : '0.9em'; // 사이즈 변경
iconHTML.style.padding = '0.2em 0'; // 아이콘 여백 조정
a.className = isMenu? "nav-link" : "dropdown-item",
a.href = url,
a.innerHTML = isMenu? '<span class="hide-title">'+title+'</span>':title,
a.title = desc;
// icon이 빈 값이 아닐 때 아이콘 추가
if (icon != '' && icon !=undefined) {
a.prepend(iconHTML);
}
return a;
};
// 신규 아이콘 추가 함수
libreNavLogin.addMenuItem = function(icon, name, url, desc, part) {
var node = this.createItem(icon, name, url, desc, part === 'new'); // 아이템 생성
switch(part) {
case 'user' : { // 사용자 메뉴
document.getElementsByClassName('dropdown-divider')[0].before(node);
break;
}
case 'board': { // 게시판
document.querySelector('.navbar-fixed-top a.nav-link[title="게시판"]').nextElementSibling.appendChild(node)
break;
}
case 'tools': { // 도구
document.querySelector('.navbar-fixed-top a.nav-link[title="도구"]').nextElementSibling.appendChild(node)
break;
}
case 'help': { // 도움말
document.querySelector('.navbar-fixed-top a.nav-link[title="도움말"]').nextElementSibling.appendChild(node)
break;
}
case 'new': { // 신규 메뉴
var menuLi = document.createElement('li');
menuLi.classList.add('nav-item');
menuLi.appendChild(node);
document.querySelector('.navbar-fixed-top ul.navbar-nav').appendChild(menuLi);
break;
}
case 'dropdown': { // 신규 드롭다운. 지원 예정.
}
}
};
// 기존 아이콘 제거 함수
libreNavLogin.removeItem = function(name) {
var Selector = '.navbar-fixed-top a[title="' + name + '"]'; // 타이틀 이름을 가진 링크. 사이드이펙트 방지를 위해 navbar-fixed-top 속성 추가.
document.querySelector(Selector).remove();
};
// 아이템 설정.
libreNavLogin.setNavItems = function() {
// 메뉴 추가 - navBarData.addList 오브젝트 사용
for (typical in this.navBarData.addList) {
for (const item of this.navBarData.addList[typical]) {
this.addMenuItem(item[0], item[1], item[2], item[3], typical);
}
}
// 기존에 있는 메뉴 제거하는 과정
for (const key in this.titleMap2) { // titleMap2에서 key값 추출
if (this.navBarData.dropList.indexOf(key)>-1) {
this.removeItem(this.titleMap2[key]);
}
}
// 메뉴 앞의 알림버튼 지우기 여부
if (this.navBarData.dropList.indexOf('echo')>-1) {
document.querySelector('#pt-notifications-notice').remove();
}
// 로그아웃 버튼 지우기 여부
if(this.navBarData.dropList.indexOf('logout')>-1) {
document.querySelector('.hide-logout.logout-btn').remove();
}
};
// 아이템 세팅 완료
libreNavLogin.setNavItems();
다크 모드에서 글씨 색을 바꾸는 스크립트 추가[원본 편집]
자바스크립트를 이용해서 태그 안에 특정한 클래스가 있을 때 클래스를 인식해서 다크모드에서 글자 색을 변환할 수 있습니다. 즉각적으로 반응하는 방식이 아닌 페이지 로딩 후 약간의 딜레이를 준 뒤에 바꾸는 방식이라는 점에 유의해주세요.
아래 소스를 특수:내사용자문서/liberty.js에 입력하시면 사용하실 수 있습니다.
// 다크 모드일 때 특정 클래스 안의 글자에 한해 다크모드에서 색상 전환시키는 코드. setTimeOut을 주는 이유는 바로 liberty-dark 속성이 서버에서 바뀌지 않기 때문이다.
setTimeout(function(){
if (mw.user.options.values['liberty-dark'] === 'dark' || window.matchMedia("(prefers-color-scheme:dark)").matches) {
mw.loader.load('//librewiki.net/index.php?title=사용자:Utolee90/dark-mode-color.js&action=raw&ctype=text/javascript');
}}, 500);
이 스크립트에 다음과 같은 방식으로 태그에 클래스명을 주면 다크 모드에서 색상이 변경됩니다. 색상명은 색상코드 6자리(FF0000 등) 또는 색상 이름(red 혹은 rgb(255,0,0) 등)으로 지정하면 됩니다.
클래스명 | 효과 설명 |
---|---|
class="dark-mode-color-(색상명)" | 글자 색상 변경 |
class="dark-mode-bgcolor-(색상명)" | 글자 배경 색상 변경 |
class="dark-mode-border-(색상명)" | 태그 테두리 색상 변경 |
아래는 이 스크립트의 원본입니다.
/* 특정 클래스이름을 된 오브젝트 - 다크 모드일 때 색상 바꾸기*/
var darkModeObjects = $("span[class*='dark-mode-']")
for (var i=0; i<darkModeObjects.length; i++) {
var classListObj = darkModeObjects[i].classList.value.split(" ");
for (var j=0; j<classListObj.length; j++) {
// 클래스명이 dark-mode-color-6자리색 또는 dark-mode-color-색상명(영어이름 또는 rgb(*,*,*) 등) -> 다크모드일 때 글씨 색 바꾸기
if (classListObj[j].indexOf('dark-mode-color-') ===0) {
var colorName = classListObj[j].slice(16);
colorName = /([0-9A-Fa-f]{6}|[0-9A-Fa-f]{3})/.test(colorName)?"#"+colorName:colorName;
darkModeObjects[i].style.color= colorName;
}
// 클래스명이 dark-mode-bgcolor-6자리색 또는 dark-mode-bgcolor-색상명 -> 다크모드일 때 배경 색 바꾸기
if (classListObj[j].indexOf('dark-mode-bgcolor-') ===0 ) {
var bgColorName = classListObj[j].slice(18);
bgColorName = /([0-9A-Fa-f]{6}|[0-9A-Fa-f]{3})/.test(bgColorName)?"#"+bgColorName:bgColorName;
darkModeObjects[i].style.background= bgColorName;
}
if (classListObj[j].indexOf('dark-mode-backgroundcolor-') ===0 ) {
var bgColorName = classListObj[j].slice(27);
bgColorName = /([0-9A-Fa-f]{6}|[0-9A-Fa-f]{3})/.test(bgColorName)?"#"+bgColorName:bgColorName;
darkModeObjects[i].style.background= bgColorName;
}
// 클래스명이 dark-mode-border-6자리색 또는 dark-mode-border-색상명 -> 다크모드일 때 경계선 색 바꾸기
if (classListObj[j].indexOf('dark-mode-border-') ===0 ) {
var borderColorName = classListObj[j].slice(17);
borderColorName = /([0-9A-Fa-f]{6}|[0-9A-Fa-f]{3})/.test(borderColorName)?"#"+borderColorName:borderColorName;
darkModeObjects[i].style.borderColor= borderColorName;
}
if (classListObj[j].indexOf('dark-mode-bordercolor-') ===0 ) {
var borderColorName = classListObj[j].slice(22);
borderColorName = /([0-9A-Fa-f]{6}|[0-9A-Fa-f]{3})/.test(borderColorName)?"#"+borderColorName:borderColorName;
darkModeObjects[i].style.borderColor= borderColorName;
}
}
}
각주
기초 사용법 | |
---|---|
위키 문법 | |
특수 기능 |