You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
180 lines
5.3 KiB
JavaScript
180 lines
5.3 KiB
JavaScript
const Vue = require("vue");
|
|
|
|
class BasePageListLoader {
|
|
loadPageList() {
|
|
return Promise.reject(new Error('Not implemented'));
|
|
}
|
|
|
|
parseHTMLString(txt) {
|
|
try {
|
|
let parser = new DOMParser();
|
|
let xmlDoc = parser.parseFromString(txt, "text/html");
|
|
return xmlDoc;
|
|
} catch(e) {
|
|
console.error(e.message);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
loadPageContent(pageInfo) {
|
|
return new Promise((resolve, reject) => {
|
|
if (!pageInfo || !pageInfo.fullTitle) {
|
|
return reject(new Error('pageInfo.fullTitle is null'));
|
|
}
|
|
|
|
let url = mw.util.getUrl(pageInfo.fullTitle);
|
|
if (url.indexOf('?') >= 0) {
|
|
url += '&';
|
|
} else {
|
|
url += '?'
|
|
}
|
|
url += 'action=render';
|
|
$.get(url, (str) => {
|
|
let $dom = $(this.parseHTMLString(str));
|
|
let $content = $dom.find('.mw-parser-output');
|
|
if ($content.length > 0) {
|
|
//删除目录
|
|
$content.find('.toc').remove();
|
|
resolve($content.html());
|
|
}
|
|
}, 'html');
|
|
});
|
|
}
|
|
|
|
getPageUrl(pageInfo) {
|
|
return new Promise((resolve, reject) => {
|
|
if (!pageInfo || !pageInfo.fullTitle) {
|
|
return reject(new Error('pageInfo.fullTitle is null'));
|
|
}
|
|
|
|
let url = mw.util.getUrl(pageInfo.fullTitle);
|
|
resolve(url);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* 根据标题生成页面信息
|
|
* @param {string} title
|
|
* @returns
|
|
*/
|
|
makePageInfoFromTitle(title) {
|
|
let pageInfo = {
|
|
fullTitle: title,
|
|
title: title,
|
|
subTitle: null
|
|
};
|
|
if (title.indexOf('/') !== 0) {
|
|
let splitPos = title.lastIndexOf('/');
|
|
pageInfo.title = title.substring(splitPos + 1);
|
|
pageInfo.subTitle = title.substring(0, splitPos);
|
|
}
|
|
return pageInfo;
|
|
}
|
|
}
|
|
|
|
class PresetPageListLoader extends BasePageListLoader {
|
|
/**
|
|
* 从页面列表加载页面
|
|
* @param {string[]} pageList
|
|
*/
|
|
constructor(pageList) {
|
|
super();
|
|
|
|
this.pageList = pageList.map((pageTitle) => {
|
|
return this.makePageInfoFromTitle(pageTitle);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* 加载页面列表
|
|
* @returns {Promise<*>}
|
|
*/
|
|
loadPageList() {
|
|
return Promise.resolve(this.pageList);
|
|
}
|
|
}
|
|
|
|
class CategoryPageListLoader extends BasePageListLoader {
|
|
/**
|
|
* 从分类加载页面
|
|
* @param {string} category
|
|
*/
|
|
constructor(category) {
|
|
super();
|
|
|
|
this.category = category;
|
|
this.api = new mw.Api();
|
|
}
|
|
|
|
/**
|
|
* 加载页面列表
|
|
* @returns {Promise<*>}
|
|
*/
|
|
loadPageList() {
|
|
return new Promise((resolve, reject) => {
|
|
this.api.get({
|
|
action: 'query',
|
|
list: 'categorymembers',
|
|
cmtitle: this.category,
|
|
cmtype: 'page',
|
|
cmnamespace: 0,
|
|
cmlimit: 200,
|
|
cmsort: 'sortkey',
|
|
}).done((data) => {
|
|
if(data.query && data.query.categorymembers){
|
|
let pageList = data.query.categorymembers.map((pageInfo) => {
|
|
return this.makePageInfoFromTitle(pageInfo.title);
|
|
});
|
|
resolve(pageList);
|
|
} else if(data.error){
|
|
reject(new Error(data.error.info));
|
|
} else {
|
|
reject(new Error(mw.message('isekai-discover-error-cannotload').parse()));
|
|
}
|
|
}).fail((data) => {
|
|
reject(new Error(data.error.info));
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|
|
function htmlDecode(input) {
|
|
var doc = new DOMParser().parseFromString(input, "text/html");
|
|
return doc.documentElement.textContent;
|
|
}
|
|
|
|
let previewPageList = document.querySelectorAll('.isekai-preview-page-list-card');
|
|
if (previewPageList.length > 0) {
|
|
const App = require("./PreviewPageList.vue");
|
|
previewPageList.forEach((previewPageListDom) => {
|
|
try {
|
|
let props = {};
|
|
let dataset = previewPageListDom.dataset;
|
|
|
|
props.autoFocus = (dataset.autofocus == '1');
|
|
props.lazyLoad = (dataset.lazyload == '1');
|
|
|
|
switch (dataset.loader) {
|
|
case 'pages':
|
|
let pagesJsonEl = document.querySelector('script[type="application/json"][data-pages]');
|
|
let pageList = [];
|
|
if (pagesJsonEl) {
|
|
let jsonStr = htmlDecode(pagesJsonEl.innerText);
|
|
pageList = JSON.parse(jsonStr);
|
|
}
|
|
props.pageListLoader = new PresetPageListLoader(pageList);
|
|
break;
|
|
case 'category':
|
|
let category = dataset.category;
|
|
props.pageListLoader = new CategoryPageListLoader(category);
|
|
break;
|
|
default:
|
|
console.error('Unknown loader: ' + dataset.loader);
|
|
}
|
|
|
|
Vue.createMwApp(App, props).mount(previewPageListDom);
|
|
} catch (e) {
|
|
console.error(e);
|
|
}
|
|
});
|
|
} |