사용자:BANIP/낙서장: 두 판 사이의 차이
잔글편집 요약 없음 태그: 되돌려진 기여 시각 편집: 전환됨 |
잔글 (사이트 정상작동 원인확인) 태그: 되돌려진 기여 |
||
14번째 줄: | 14번째 줄: | ||
}, function(e){ | }, function(e){ | ||
reject(e); | reject(e); | ||
}); | }); | ||
}); | }); |
2023년 7월 8일 (토) 01:33 판
// 프리로딩 가능한 링크 최고 갯수 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); }); }); })
})