사용자:BANIP/낙서장: 두 판 사이의 차이

리버티게임, 모두가 만들어가는 자유로운 게임
잔글 (사이트 정상작동 원인확인)
태그: 되돌려진 기여
잔글 (문서를 비움)
태그: 비우기 수동 되돌리기
1번째 줄: 1번째 줄:


// 프리로딩 가능한 링크 최고 갯수
var previewLimit = 5
var getParsedDocumentPromise = (function(link){
    var mwApi = new mw.Api();
    return function(pagename){
        return new Promise(function(resolve, reject){
            mwApi .get({
                action: 'parse',
                page: pagename,
                formatversion: 2
            }).then(function(data){
                resolve(data.parse.displaytitle, data.parse.text);
            }, function(e){
                reject(e);
            });
                       
        });
    }
})();
var setLoading = function(boolean){
    // 이미 로딩 완료된 작업의 경우 로딩창을 표시하지 않기 위해
    // 로딩창 표시 작업시 예약 플래그를 설정하고 약간의 텀을 두기
    // 로딩창 삭제 작업시 표시작업이 예약되어있으면 같이 삭제
}
// 선행로딩된 페이지들
var documentPromiseMap = {};
var namespace = $("#firstHeading > span.mw-page-title-namespace").val() || ""
// 해당 링크의 action, title, oldid 파라미터가 없는 링크만 가져오기
var targetLinks = $("#mw-content-text a").not(".external").filter(function() {
    return !this.href.match(/action=|title=|oldid=/);
}).toArray().map(function(el) {
    var [_, namespace, docname] = decodeURI(el.href).match(/[a-z]+\:\/\/[a-z\.]+\/[a-z\.]+\/([^\:]+)\:?(.*)/);
    if (docname === "") [namespace, docname] = [docname, namespace];
    [namespace, docname];
   
    return {
        el,
        link: el.href,
        title: el.title,
        namespace, docname
    }
})
// 동일한 네임스페이스만 이동되게 필터링
.filter(({namespace:thisNamespace}) => thisNamespace === namespace )
// 필터된게 previewLimit 갯수 이상이면 동작 x, 프로미스맵에 클릭 시 로딩 필요함을 명시
if(targetLinks.length > previewLimit){
    targetLinks.forEach(({link}) => documentPromiseMap[link] ||= null);
} else {
    // 필터링된게 프로미스맵에 없는 경우 사전 프리로딩 프로미스 추가
    targetLinks.forEach(({link, docname, namespace}) => {
        var pagename = docname === "" ? namespace : `${namespace}:${docname}`;
        documentPromiseMap[link] ||= getParsedDocumentPromise(pagename)
    });
}
// 가져온 링크로 전체 작업
targetLinks.forEach(function(this){
    var $link = $(this);
    // a링크 href를 #로 변경, 클릭 시 이벤트 바인딩
    var href = $link.attr("href");
    var documentPromise = documentPromiseMap[href];
    $link
        .attr("href", "#")
        .click(function(){
            // 프리로드 불필요한 경우(네임스페이스가 다를때, 편집/리비전확인 링크일때) url 영구이동
            if(documentPromise === undefined){
                return location.href = href;
            }
            // 프리로드되지 않은 이동 가능한 링크면 로딩창 표시 후 해당 페이지 로딩
            if(documentPromise === null){
                documentPromise = getParsedDocumentPromise(href);
            }
            // 프로미스가 아직 안끝났으면 로딩창 표시
            setLoading(true);
            // 링크 프로미스에 문제가 있을 시 다시 내용 확인, 성공시 문서 프로미스에 저장, 오류시 에러메세지
            documentPromise.then(function(title, text){
                // 프리로드 프로미스가 정상적으로 불러왔을 경우
                // Promise.race1
                    // 문서내용 페이드 아웃,
                    // 프로미스 내용으로 교체
                    // 문서내용 페이드 인
                // Promise.race2
                    // 사전로딩된 내용에서 프리로드 분석 재실행
            }).error(function(e){
                // 에러 발생 시 실패한 페이지 다시 프로미스에 저장 시도
                documentPromiseMap[href] = null;
                documentPromise = null;
                // 에러메세지 표시
                toast('페이지 로딩에 실패했습니다. 다시 시도해주세요.');
            }).finally(function(){
                // 로딩창 삭제
                setLoading(false);
            });
        });
    })
})

2023년 7월 8일 (토) 21:10 판