사용자:BANIP/낙서장: 두 판 사이의 차이
잔글편집 요약 없음 태그: 되돌려진 기여 |
잔글편집 요약 없음 태그: 되돌려진 기여 시각 편집: 전환됨 |
||
1번째 줄: | 1번째 줄: | ||
// 프리로딩 가능한 링크 최고 갯수 | |||
var previewLimit = 5 | 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 documentPromiseMap = {}; | ||
var namespace = $("#firstHeading > span.mw-page-title-namespace").val() || "" | |||
var namespace = $("#firstHeading > span.mw-page-title-namespace").val() | |||
// 해당 링크의 action, title, oldid 파라미터가 없는 링크만 가져오기 | // 해당 링크의 action, title, oldid 파라미터가 없는 링크만 가져오기 | ||
targetLinks = $("#mw-content-text a").not(".external").filter(function() { | var targetLinks = $("#mw-content-text a").not(".external").filter(function() { | ||
return !this.href.match(/action=|title=|oldid=/); | return !this.href.match(/action=|title=|oldid=/); | ||
}).toArray().map(function(el) { | }).toArray().map(function(el) { | ||
24번째 줄: | 49번째 줄: | ||
.filter(({namespace:thisNamespace}) => thisNamespace === namespace ) | .filter(({namespace:thisNamespace}) => thisNamespace === namespace ) | ||
// 필터된게 previewLimit 갯수 이상이면 동작 x, 프로미스맵에 클릭 시 로딩 필요함을 명시 | // 필터된게 previewLimit 갯수 이상이면 동작 x, 프로미스맵에 클릭 시 로딩 필요함을 명시 | ||
// 필터링된게 프로미스맵에 없는 경우 사전 프리로딩 프로미스 추가 | if(targetLinks.length > previewLimit){ | ||
// a링크 href를 #로 변경, 클릭 시 이벤트 바인딩 | targetLinks.forEach(({link}) => documentPromiseMap[link] ||= null); | ||
} else { | |||
// 프리로드 불필요한 경우(네임스페이스가 다를때, 편집/리비전확인 링크일때) url 영구이동 | // 필터링된게 프로미스맵에 없는 경우 사전 프리로딩 프로미스 추가 | ||
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월 6일 (목) 23:15 판
// 프리로딩 가능한 링크 최고 갯수 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); }); }); })
})