Change some packages.

master
落雨楓 4 years ago
parent 920fbcb776
commit 469c253b09

@ -0,0 +1,11 @@
{
"plugins": ["@babel/syntax-dynamic-import"],
"presets": [
[
"@babel/preset-env",
{
"modules": false
}
]
]
}

@ -1,87 +1,102 @@
{ {
"name": "Isekai Discover Box", "name": "Isekai Discover Box",
"namemsg": "isekai-widgets", "namemsg": "isekai-widgets",
"author": "Hyperzlib", "author": "Hyperzlib",
"version": "1.0.2", "version": "1.0.2",
"url": "https://github.com/Isekai-Project/mediawiki-extension-IsekaiWidgets", "url": "https://github.com/Isekai-Project/mediawiki-extension-IsekaiWidgets",
"descriptionmsg": "isekai-widgets-desc", "descriptionmsg": "isekai-widgets-desc",
"license-name": "GPL-2.0-or-later", "license-name": "GPL-2.0-or-later",
"type": "parserhook", "type": "parserhook",
"MessagesDirs": { "MessagesDirs": {
"IsekaiWidgets": [ "IsekaiWidgets": [
"i18n" "i18n"
] ]
}, },
"AutoloadNamespaces": { "AutoloadNamespaces": {
"Isekai\\Widgets\\": "includes" "Isekai\\Widgets\\": "includes"
}, },
"Hooks": { "Hooks": {
"ParserFirstCallInit": "Isekai\\Widgets\\Widgets::onParserSetup" "ParserFirstCallInit": "Isekai\\Widgets\\Widgets::onParserSetup"
}, },
"ResourceModules": { "ResourceModules": {
"ext.isekai.createPage": { "ext.isekai.createPage": {
"scripts": [ "scripts": [
"createPage/ext.isekai.createPage.js", "createPage/ext.isekai.createPage.js",
"createPage/ext.isekai.createPage.base.js" "createPage/ext.isekai.createPage.base.js"
], ],
"styles": [ "styles": [
"createPage/ext.isekai.createPage.base.less" "createPage/ext.isekai.createPage.base.less"
], ],
"dependencies": [ "dependencies": [
"oojs-ui-core" "oojs-ui-core"
], ],
"targets": [ "targets": [
"desktop", "desktop",
"mobile" "mobile"
], ],
"messages": [ "messages": [
"isekai-createpage-page-title", "isekai-createpage-page-title",
"isekai-createpage-create-page-button", "isekai-createpage-create-page-button",
"isekai-createpage-page-exists", "isekai-createpage-page-exists",
"isekai-createpage-title-empty", "isekai-createpage-title-empty",
"isekai-createpage-redirecting" "isekai-createpage-redirecting"
] ]
}, },
"ext.isekai.discover": { "ext.isekai.discover": {
"scripts": [ "scripts": [
"discover/ext.isekai.discover.js", "discover/ext.isekai.discover.js",
"discover/ext.isekai.discover.base.js" "discover/ext.isekai.discover.base.js"
], ],
"styles": [ "styles": [
"discover/ext.isekai.discover.base.less" "discover/ext.isekai.discover.base.less"
], ],
"dependencies": [ "dependencies": [
"oojs", "oojs",
"oojs-ui-core", "oojs-ui-core",
"oojs-ui.styles.icons-interactions" "oojs-ui.styles.icons-interactions"
], ],
"targets": [ "targets": [
"desktop", "desktop",
"mobile" "mobile"
], ],
"messages": [ "messages": [
"isekai-discover-change-btn", "isekai-discover-change-btn",
"isekai-discover-readmore-btn", "isekai-discover-readmore-btn",
"isekai-discover-error-cannotload" "isekai-discover-error-cannotload"
] ]
}, },
"ext.isekai.tile": { "ext.isekai.previewCard": {
"scripts": [ "scripts": [
"tile/tile.js" "previewCard/ext.isekai.previewCard.js"
], ],
"styles": [ "styles": [
"tile/tile.css", "previewCard/ext.isekai.previewCard.less"
"tile/style.less" ],
], "targets": [
"targets": [ "desktop",
"desktop", "mobile"
"mobile" ],
] "messages": [
]
},
"ext.isekai.tile": {
"scripts": [
"tile/tile.js"
],
"styles": [
"tile/tile.css",
"tile/style.less"
],
"targets": [
"desktop",
"mobile"
]
} }
}, },
"ResourceFileModulePaths": { "ResourceFileModulePaths": {
"localBasePath": "modules", "localBasePath": "modules",
"remoteExtPath": "IsekaiWidgets/modules" "remoteExtPath": "IsekaiWidgets/modules"
}, },
"manifest_version": 1 "manifest_version": 1
} }

@ -4,7 +4,7 @@ namespace Isekai\Widgets;
class CreatePageWidget { class CreatePageWidget {
public static function getHtml(){ public static function getHtml(){
ob_start(); ob_start();
include(dirname(__DIR__) . '/modules/createPage/ext.isekai.createPageWidget.tpl'); include(dirname(__DIR__) . '/modules/createPage/ext.isekai.createPage.tpl');
$template = ob_get_clean(); $template = ob_get_clean();
return [$template, "markerType" => 'nowiki']; return [$template, "markerType" => 'nowiki'];
} }

@ -0,0 +1,27 @@
<?php
namespace Isekai\Widgets;
class PreviewCardWidget {
public static function getHtml($variables){
extract($variables);
ob_start();
include(dirname(__DIR__) . '/modules/previewCard/ext.isekai.previewCard.tpl');
$template = ob_get_clean();
return [$template, "markerType" => 'nowiki'];
}
public static function create($text, $params, $parser, $frame){
$parser->getOutput()->addModules('ext.isekai.previewCard');
$titleChunk = explode('/', $text);
$len = count($titleChunk);
$displayTitle = $titleChunk[$len - 1];
unset($titleChunk[$len - 1]);
$path = implode('/', $titleChunk);
return self::getHtml([
'title' => $text,
'displayTitle' => $displayTitle,
'path' => $path,
]);
}
}

@ -5,6 +5,7 @@ class Widgets {
public static function onParserSetup(&$parser){ public static function onParserSetup(&$parser){
$parser->setHook('createpage', CreatePageWidget::class . '::create'); $parser->setHook('createpage', CreatePageWidget::class . '::create');
$parser->setHook('discoverbox', DiscoverWidget::class . '::create'); $parser->setHook('discoverbox', DiscoverWidget::class . '::create');
$parser->setHook('previewcard', PreviewCardWidget::class . '::create');
$parser->setHook('tile', TileWidget::class . '::create'); $parser->setHook('tile', TileWidget::class . '::create');
$parser->setHook('tilegroup', TileGroupWidget::class . '::create'); $parser->setHook('tilegroup', TileGroupWidget::class . '::create');

@ -1,8 +1,8 @@
$(function(){ $(function(){
if($('.isekai-create-page-panel').length > 0){ if($('.isekai-create-page').length > 0){
var CreatePagePanel = isekai.CreatePagePanel; var CreatePageWidget = isekai.ui.CreatePageWidget;
$('.isekai-create-page-panel').each(function(){ $('.isekai-create-page').each(function(){
new CreatePagePanel($(this)); new CreatePageWidget($(this));
}); });
} }
}); });

@ -1,7 +1,7 @@
@height: 2.25em; @height: 2.25em;
@text-size: 0.95em; @text-size: 0.95em;
.create-page-panel { .isekai-create-page {
position: relative; position: relative;
display: flex; display: flex;
flex-direction: column; flex-direction: column;

@ -1 +1 @@
!function(e){var t={};function r(i){if(t[i])return t[i].exports;var a=t[i]={i:i,l:!1,exports:{}};return e[i].call(a.exports,a,a.exports,r),a.l=!0,a.exports}r.m=e,r.c=t,r.d=function(e,t,i){r.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:i})},r.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var i=Object.create(null);if(r.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var a in e)r.d(i,a,function(t){return e[t]}.bind(null,a));return i},r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,"a",t),t},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.p="",r(r.s=4)}([function(e,t){var r;r=function(){return this}();try{r=r||new Function("return this")()}catch(e){"object"==typeof window&&(r=window)}e.exports=r},,,,function(e,t,r){e.exports=r(5)},function(e,t,r){(function(e){e.isekai||(e.isekai={}),e.isekai.CreatePagePanel=class{constructor(e){this.baseDom=e,this.pageUrl=null,this.api=new mw.Api,this.hasError=!1,this.initDom()}initDom(){this.pageNameInput=new OO.ui.TextInputWidget({placeholder:mw.message("isekai-createpage-page-title").parse()}),this.pageNameInput.on("enter",this.createPage.bind(this)),this.pageNameInput.on("change",this.onPageNameChange.bind(this)),this.createButton=new OO.ui.ButtonWidget({label:mw.message("isekai-createpage-create-page-button").parse(),flags:["primary","progressive"]}),this.createButton.on("click",this.createPage.bind(this)),this.formGroup=new OO.ui.ActionFieldLayout(this.pageNameInput,this.createButton,{align:"top"}),this.baseDom.find(".card-body .card-content").append(this.formGroup.$element)}createPage(){let e=this.pageNameInput.getValue();this.hasError&&this.clearError(),e.trim().length>0?(this.createButton.setDisabled(!0),this.pageExists(e).then(t=>{if(t)this.createButton.setDisabled(!1),this.setError(mw.message("isekai-createpage-page-exists").parse());else{let t=mw.util.getUrl(e,{veaction:"edit"});this.formGroup.setSuccess([mw.message("isekai-createpage-redirecting").parse()]),location.href=t}})):this.setError(mw.message("isekai-createpage-title-empty").parse())}onPageNameChange(){this.hasError&&this.clearError();let e=this.pageNameInput.getValue();if(-1!==e.indexOf("")||-1!==e.indexOf("`")){let t=this.pageNameInput.getRange();e=e.replace(//g,":").replace(/`/g,"·"),this.pageNameInput.setValue(e),this.pageNameInput.selectRange(t.from,t.to)}}setError(e){this.formGroup.setErrors([e]),this.hasError=!0}clearError(){this.formGroup.setErrors([]),this.hasError=!1}pageExists(e){return new Promise((t,r)=>{this.api.get({action:"query",titles:e}).done(e=>{e.query&&e.query.pages?e.query.pages[-1]?t(!1):t(!0):t(!1)}).fail(r)})}setTitle(e){this.title.text(e)}}}).call(this,r(0))}]); (()=>{var e={153:e=>{e.exports=function(e,t){var a=e.split(".");"isekai"in window||(window.isekai={});for(var i=window.isekai,r=0;r<a.length-1;r++){var s=a[r];s in i||(i[s]={}),i=i[s]}i[a[r]]=t}}},t={};function a(i){var r=t[i];if(void 0!==r)return r.exports;var s=t[i]={exports:{}};return e[i](s,s.exports,a),s.exports}(()=>{function e(e,t){for(var a=0;a<t.length;a++){var i=t[a];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(e,i.key,i)}}a(153)("ui.CreatePageWidget",function(){function t(e){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,t),this.baseDom=e,this.pageUrl=null,this.api=new mw.Api,this.hasError=!1,this.initDom()}var a,i;return a=t,(i=[{key:"initDom",value:function(){this.pageNameInput=new OO.ui.TextInputWidget({placeholder:mw.message("isekai-createpage-page-title").parse()}),this.pageNameInput.on("enter",this.createPage.bind(this)),this.pageNameInput.on("change",this.onPageNameChange.bind(this)),this.createButton=new OO.ui.ButtonWidget({label:mw.message("isekai-createpage-create-page-button").parse(),flags:["primary","progressive"]}),this.createButton.on("click",this.createPage.bind(this)),this.formGroup=new OO.ui.ActionFieldLayout(this.pageNameInput,this.createButton,{align:"top"}),this.baseDom.find(".card-body .card-content").append(this.formGroup.$element)}},{key:"createPage",value:function(){var e=this,t=this.pageNameInput.getValue();this.hasError&&this.clearError(),t.trim().length>0?(this.createButton.setDisabled(!0),this.pageExists(t).then((function(a){if(a)e.createButton.setDisabled(!1),e.setError(mw.message("isekai-createpage-page-exists").parse());else{var i=mw.util.getUrl(t,{veaction:"edit"});e.formGroup.setSuccess([mw.message("isekai-createpage-redirecting").parse()]),location.href=i}}))):this.setError(mw.message("isekai-createpage-title-empty").parse())}},{key:"onPageNameChange",value:function(){this.hasError&&this.clearError();var e=this.pageNameInput.getValue();if(-1!==e.indexOf("")||-1!==e.indexOf("`")){var t=this.pageNameInput.getRange();e=e.replace(//g,":").replace(/`/g,"·"),this.pageNameInput.setValue(e),this.pageNameInput.selectRange(t.from,t.to)}}},{key:"setError",value:function(e){this.formGroup.setErrors([e]),this.hasError=!0}},{key:"clearError",value:function(){this.formGroup.setErrors([]),this.hasError=!1}},{key:"pageExists",value:function(e){var t=this;return new Promise((function(a,i){t.api.get({action:"query",titles:e}).done((function(e){e.query&&e.query.pages?e.query.pages[-1]?a(!1):a(!0):a(!1)})).fail(i)}))}},{key:"setTitle",value:function(e){this.title.text(e)}}])&&e(a.prototype,i),t}())})()})();

@ -1,4 +1,4 @@
<div class="isekai-create-page-panel create-page-panel"> <div class="isekai-create-page">
<div class="card-header"> <div class="card-header">
<span class="card-header-text"><?php echo wfMessage('isekai-createpage-create-page')->parse(); ?></span> <span class="card-header-text"><?php echo wfMessage('isekai-createpage-create-page')->parse(); ?></span>
</div> </div>

@ -1,9 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Webpack App</title>
</head>
<body>
<script type="text/javascript" src="ext.isekai.createPage.js"></script></body>
</html>

@ -1,18 +0,0 @@
.discover-row {
display: flex;
.discover-col {
width: 100%;
@media(min-width: 851px){
& {
width: 50%;
margin-left: 1em;
&:first-child {
margin-left: 0px;
}
}
}
}
}

@ -1,8 +1,8 @@
$(function(){ $(function(){
if($('.isekai-discover').length > 0){ if($('.isekai-discover').length > 0){
var Discover = isekai.Discover; var DiscoverWidget = isekai.ui.DiscoverWidget;
$('.isekai-discover').each(function(){ $('.isekai-discover').each(function(){
new Discover($(this)); new DiscoverWidget($(this));
}); });
} }
}); });

@ -1 +1 @@
!function(e){var t={};function n(r){if(t[r])return t[r].exports;var i=t[r]={i:r,l:!1,exports:{}};return e[r].call(i.exports,i,i.exports,n),i.l=!0,i.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var i in e)n.d(r,i,function(t){return e[t]}.bind(null,i));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=6)}({0:function(e,t){var n;n=function(){return this}();try{n=n||new Function("return this")()}catch(e){"object"==typeof window&&(n=window)}e.exports=n},6:function(e,t,n){(function(e){e.isekai||(e.isekai={}),e.isekai.Discover=class{constructor(e){this.baseDom=e,this.pageUrl=null,this.api=new mw.Api,this.initDom(),this.refreshPage()}initDom(){this.reloadButton=new OO.ui.ButtonWidget({icon:"reload",label:mw.message("isekai-discover-change-btn").parse()}),this.reloadButton.on("click",this.refreshPage.bind(this)),this.readMoreButton=new OO.ui.ButtonWidget({icon:"ellipsis",label:mw.message("isekai-discover-readmore-btn").parse(),flags:["primary","progressive"]}),this.readMoreButton.on("click",this.showMore.bind(this)),this.loadingBar=new OO.ui.ProgressBarWidget({progress:!1}),this.baseDom.find(".card-body .loading .spinner").append(this.loadingBar.$element),this.buttonGroup=new OO.ui.ButtonGroupWidget({items:[this.reloadButton,this.readMoreButton]}),this.baseDom.find(".card-header .card-header-buttons").append(this.buttonGroup.$element),this.loading=this.baseDom.find(".card-body .loading"),this.title=this.baseDom.find(".card-body .card-title"),this.contentContainer=this.baseDom.find(".card-body .card-content")}showMore(){this.pageUrl&&window.open(this.pageUrl)}refreshPage(){this.pageUrl=null,this.clearContent(),this.showLoading(),this.getRandomPage().then(e=>{this.loadPage(e)})}setTitle(e){this.title.text(e)}showLoading(){this.loading.show(),this.contentContainer.hide()}hideLoading(){this.loading.hide(),this.contentContainer.show()}clearContent(){this.contentContainer.children().remove()}setContent(e){this.hideLoading(),this.clearContent(),this.contentContainer.append(e)}showError(e){let t=new OO.ui.MessageWidget({type:"error",label:e});this.setContent(t.$element)}getRandomPage(){return new Promise((e,t)=>{this.api.get({action:"query",list:"random",rnlimit:1,rnnamespace:0}).done(t=>{if(t.query&&t.query.random&&t.query.random.length>0){let n=t.query.random[0].title;this.setTitle(n),e(n)}else t.error?this.showError(t.error.info):this.showError(mw.message("isekai-discover-error-cannotload").parse())})})}parseHTMLString(e){try{return(new DOMParser).parseFromString(e,"text/html")}catch(e){console.error(e.message)}return null}loadPage(e){let t=mw.util.getUrl(e);this.pageUrl=t,t.indexOf("?")>=0?t+="&":t+="?",t+="action=render",$.get(t,e=>{let t=$(this.parseHTMLString(e)).find(".mw-parser-output");t.length>0&&(t.find(".toc").remove(),this.setContent(t))},"html")}}}).call(this,n(0))}}); (()=>{var e={153:e=>{e.exports=function(e,t){var n=e.split(".");"isekai"in window||(window.isekai={});for(var i=window.isekai,r=0;r<n.length-1;r++){var o=n[r];o in i||(i[o]={}),i=i[o]}i[n[r]]=t}}},t={};function n(i){var r=t[i];if(void 0!==r)return r.exports;var o=t[i]={exports:{}};return e[i](o,o.exports,n),o.exports}(()=>{function e(e,t){for(var n=0;n<t.length;n++){var i=t[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(e,i.key,i)}}n(153)("ui.DiscoverWidget",function(){function t(e){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,t),this.baseDom=e,this.pageUrl=null,this.api=new mw.Api,this.initDom(),this.refreshPage()}var n,i;return n=t,(i=[{key:"initDom",value:function(){this.reloadButton=new OO.ui.ButtonWidget({icon:"reload",label:mw.message("isekai-discover-change-btn").parse()}),this.reloadButton.on("click",this.refreshPage.bind(this)),this.readMoreButton=new OO.ui.ButtonWidget({icon:"ellipsis",label:mw.message("isekai-discover-readmore-btn").parse(),flags:["primary","progressive"]}),this.readMoreButton.on("click",this.showMore.bind(this)),this.loadingBar=new OO.ui.ProgressBarWidget({progress:!1}),this.baseDom.find(".card-body .loading .spinner").append(this.loadingBar.$element),this.buttonGroup=new OO.ui.ButtonGroupWidget({items:[this.reloadButton,this.readMoreButton]}),this.baseDom.find(".card-header .card-header-buttons").append(this.buttonGroup.$element),this.loading=this.baseDom.find(".card-body .loading"),this.title=this.baseDom.find(".card-body .card-title"),this.contentContainer=this.baseDom.find(".card-body .card-content")}},{key:"showMore",value:function(){this.pageUrl&&window.open(this.pageUrl)}},{key:"refreshPage",value:function(){var e=this;this.pageUrl=null,this.clearContent(),this.showLoading(),this.getRandomPage().then((function(t){e.loadPage(t)}))}},{key:"setTitle",value:function(e){this.title.text(e)}},{key:"showLoading",value:function(){this.loading.show(),this.contentContainer.hide()}},{key:"hideLoading",value:function(){this.loading.hide(),this.contentContainer.show()}},{key:"clearContent",value:function(){this.contentContainer.children().remove()}},{key:"setContent",value:function(e){this.hideLoading(),this.clearContent(),this.contentContainer.append(e)}},{key:"showError",value:function(e){var t=new OO.ui.MessageWidget({type:"error",label:e});this.setContent(t.$element)}},{key:"getRandomPage",value:function(){var e=this;return new Promise((function(t,n){e.api.get({action:"query",list:"random",rnlimit:1,rnnamespace:0}).done((function(n){if(n.query&&n.query.random&&n.query.random.length>0){var i=n.query.random[0].title;e.setTitle(i),t(i)}else n.error?e.showError(n.error.info):e.showError(mw.message("isekai-discover-error-cannotload").parse())}))}))}},{key:"parseHTMLString",value:function(e){try{return(new DOMParser).parseFromString(e,"text/html")}catch(e){console.error(e.message)}return null}},{key:"loadPage",value:function(e){var t=this,n=mw.util.getUrl(e);this.pageUrl=n,n.indexOf("?")>=0?n+="&":n+="?",n+="action=render",$.get(n,(function(e){var n=$(t.parseHTMLString(e)).find(".mw-parser-output");n.length>0&&(n.find(".toc").remove(),t.setContent(n))}),"html")}}])&&e(n.prototype,i),t}())})()})();

@ -1,7 +1,7 @@
.discover-row { .isekai-row {
display: flex; display: flex;
.discover-col { .isekai-col {
width: 100%; width: 100%;
@media(min-width: 851px){ @media(min-width: 851px){

@ -0,0 +1,96 @@
$(function(){
var cardList = [];
$('.isekai-preview-card').each(function(){
//点击动画
var animating = false;
var mouseUp = false;
var cardElem = $(this);
cardElem.on('mousedown', function(){
cardElem.addClass('mousedown');
mouseUp = false;
animating = true;
setTimeout(() => {
if(mouseUp){
cardElem.removeClass('mousedown');
}
animating = false;
}, 150);
}).on('mouseup', function(){
if(animating){
mouseUp = true;
} else {
cardElem.removeClass('mousedown');
}
});
//获取页面列表
var pageTitle = cardElem.attr('data-title');
if(pageTitle){
cardList.push({
title: pageTitle,
element: cardElem,
});
}
});
//加载页面信息
var titleList = [];
var pageInfoList = {};
cardList.forEach((item) => {
var title = item.title;
if(titleList.indexOf(title) === -1){
titleList.push(title);
}
});
var api = new mw.Api();
function setPreviews(pageInfoList){
cardList.forEach((item) => {
var title = item.title;
var elem = item.element;
//移除加载动画
elem.find('.loading').remove();
//查找数据
if(title in pageInfoList){
var info = pageInfoList[title];
if(info.thumbnail){ //有缩略图
elem.addClass('card-media');
elem.find('.card-img').attr('src', info.thumbnail.source).show();
}
console.log(info);
elem.find('.card-content').text(info.extract);
} else {
elem.find('.card-content').text('页面不存在');
}
});
}
api.get({
action: 'query',
prop: ['info', 'extracts', 'pageimages', 'revisions', 'info'],
formatversion: 2,
redirects: true,
exintro: true,
exchars: 150,
explaintext: true,
piprop: 'thumbnail',
pithumbsize: 640,
pilicense: 'any',
rvprop: 'timestamp',
inprop: 'url',
titles: titleList,
smaxage: 300,
maxage: 300,
uselang: 'content',
}).done((data) => {
if(data.query && data.query.pages && data.query.pages.length > 0){
let pages = data.query.pages;
pages.forEach((page) => {
if(!page.missing){
pageInfoList[page.title] = page;
}
});
setPreviews(pageInfoList);
}
});
});

@ -0,0 +1,119 @@
@text-size: 1em;
.isekai-preview-card-wrapper {
padding: .5rem;
width: 100%;
@media (min-width: 768px) {
width: 50%;
}
@media (min-width: 992px) {
width: 33.3333%;
}
}
.isekai-preview-card {
word-wrap: break-word;
background-color: #fff;
background-clip: border-box;
box-shadow: 0 3px 1px -2px rgba(0, 0, 0, 0.2), 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 1px 5px 0 rgba(0, 0, 0, 0.12);
transform: scale(1);
transition: box-shadow 0.25s cubic-bezier(.4,0,.2,1), transform 0.15s cubic-bezier(.4,0,.2,1);
will-change: box-shadow, transform;
border-radius: 2px;
cursor: pointer;
.card-header {
margin-bottom: 0;
display: flex;
align-items: center;
position: relative;
.card-header-title {
padding: 1rem 1.2rem;
.card-header-title-text {
font-weight: bold;
font-size: 1.4rem;
line-height: 2.2rem;
}
.card-header-subtitle-text {
font-size: 0.8rem;
line-height: 1.6rem;
opacity: 0.7;
}
}
.card-header-buttons {
margin-left: auto;
}
}
.card-body {
flex: 1 1 auto;
.card-content {
padding: 0rem 1rem 1.5rem;
font-size: @text-size;
line-height: 1.6em;
}
.loading {
text-align: center;
padding: 2rem;
.loader {
animation: isekai-spin 1s infinite linear;
}
}
}
&.card-media {
.card-header {
.card-header-title {
position: absolute;
right: 0;
bottom: 0;
left: 0;
color: #fff;
background: rgba(0,0,0,.2);
padding: 1.4rem 1rem 1rem 1rem;
}
.card-img {
max-height: 15rem;
width: 100%;
height: auto;
object-fit: cover;
}
}
.card-body {
.card-content {
padding: 1rem 1rem 1.2rem;
}
}
}
&.mousedown {
transform: scale(0.98);
}
&:hover {
box-shadow: 0 5px 5px -3px rgba(0, 0, 0, 0.2), 0 8px 10px 1px rgba(0, 0, 0, 0.14), 0 3px 14px 2px rgba(0, 0, 0, 0.12);
}
}
@keyframes isekai-spin {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(359deg);
transform: rotate(359deg);
}
}

@ -0,0 +1,20 @@
<div class="isekai-preview-card-wrapper">
<div class="isekai-preview-card" data-title="<?php echo $title; ?>">
<div class="card-header">
<div class="card-header-title">
<div class="card-header-title-text"><?php echo $displayTitle; ?></div>
<div class="card-header-subtitle-text"><?php echo $path; ?></div>
</div>
<img class="card-img" style="display: none;">
</div>
<div class="card-body">
<div class="card-content">
<div class="loading">
<svg version="1.1" class="loader" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="40px" height="40px" viewBox="0 0 50 50" style="enable-background:new 0 0 50 50;" xml:space="preserve">
<path fill="#0088dd" d="M25.251,6.461c-10.318,0-18.683,8.365-18.683,18.683h4.068c0-8.071,6.543-14.615,14.615-14.615V6.461z"></path>
</svg>
</div>
</div>
</div>
</div>
</div>

3124
package-lock.json generated

File diff suppressed because it is too large Load Diff

@ -1,26 +1,30 @@
{ {
"name": "isekai-discover", "name": "isekai-widgets",
"version": "1.0.0", "version": "1.0.0",
"description": "My webpack project", "description": "Some custom widgets uses on Isekai Wiki",
"scripts": { "scripts": {
"build": "webpack", "build": "webpack --mode=production --node-env=production",
"start": "webpack-dev-server" "build:dev": "webpack --mode=development",
"build:prod": "webpack --mode=production --node-env=production",
"watch": "webpack --watch"
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "^7.7.2", "@babel/core": "^7.14.6",
"@babel/preset-env": "^7.7.1", "@babel/preset-env": "^7.14.5",
"babel-loader": "^8.0.6", "autoprefixer": "^10.2.6",
"babel-plugin-syntax-dynamic-import": "^6.18.0", "babel-loader": "^8.2.2",
"css-loader": "^3.2.0", "css-loader": "^5.2.6",
"html-webpack-plugin": "^3.2.0", "mini-css-extract-plugin": "^1.6.0",
"less": "^3.9.0", "postcss": "^8.3.5",
"less-loader": "^5.0.0", "postcss-loader": "^6.1.0",
"style-loader": "^1.0.0", "prettier": "^2.3.1",
"webpack": "^4.41.2", "sass": "^1.35.1",
"webpack-cli": "^3.3.10", "sass-loader": "^12.1.0",
"webpack-dev-server": "^3.9.0" "style-loader": "^2.0.0",
"webpack": "^5.39.0",
"webpack-cli": "^4.7.2"
}, },
"dependencies": { "dependencies": {
"scss-loader": "0.0.1" "masonry-layout": "^4.2.2"
} }
} }

@ -0,0 +1,5 @@
module.exports = {
// Add you postcss configuration here
// Learn more about it at https://github.com/webpack-contrib/postcss-loader#config-files
plugins: [["autoprefixer"]],
};

@ -1,108 +1,108 @@
class CreatePagePanel { const registerModule = require('../moduleRegister');
constructor(dom) {
this.baseDom = dom;
this.pageUrl = null;
this.api = new mw.Api();
this.hasError = false; class CreatePageWidget {
constructor(dom) {
this.baseDom = dom;
this.pageUrl = null;
this.api = new mw.Api();
this.initDom(); this.hasError = false;
}
initDom() { this.initDom();
this.pageNameInput = new OO.ui.TextInputWidget({ }
placeholder: mw.message('isekai-createpage-page-title').parse(),
});
this.pageNameInput.on('enter', this.createPage.bind(this));
this.pageNameInput.on('change', this.onPageNameChange.bind(this));
this.createButton = new OO.ui.ButtonWidget({ initDom() {
label: mw.message('isekai-createpage-create-page-button').parse(), this.pageNameInput = new OO.ui.TextInputWidget({
flags: [ placeholder: mw.message('isekai-createpage-page-title').parse(),
'primary', });
'progressive' this.pageNameInput.on('enter', this.createPage.bind(this));
] this.pageNameInput.on('change', this.onPageNameChange.bind(this));
});
this.createButton.on('click', this.createPage.bind(this));
this.formGroup = new OO.ui.ActionFieldLayout(this.pageNameInput, this.createButton, { this.createButton = new OO.ui.ButtonWidget({
align: 'top' label: mw.message('isekai-createpage-create-page-button').parse(),
}); flags: [
this.baseDom.find('.card-body .card-content').append(this.formGroup.$element); 'primary',
} 'progressive'
]
});
this.createButton.on('click', this.createPage.bind(this));
createPage() { this.formGroup = new OO.ui.ActionFieldLayout(this.pageNameInput, this.createButton, {
let title = this.pageNameInput.getValue(); align: 'top'
if (this.hasError) { });
this.clearError(); //清除errors this.baseDom.find('.card-body .card-content').append(this.formGroup.$element);
} }
if (title.trim().length > 0) {
this.createButton.setDisabled(true);
this.pageExists(title).then((exists) => {
if (exists) {
this.createButton.setDisabled(false);
this.setError(mw.message('isekai-createpage-page-exists').parse()); //提示页面已经存在
} else {
let targetUrl = mw.util.getUrl(title, { veaction: 'edit' });
this.formGroup.setSuccess([
mw.message('isekai-createpage-redirecting').parse()
]); //提示正在跳转
location.href = targetUrl;
}
});
} else {
this.setError(mw.message('isekai-createpage-title-empty').parse());
}
}
onPageNameChange() { createPage() {
if (this.hasError) { let title = this.pageNameInput.getValue();
this.clearError(); if (this.hasError) {
} this.clearError(); //清除errors
}
if (title.trim().length > 0) {
this.createButton.setDisabled(true);
this.pageExists(title).then((exists) => {
if (exists) {
this.createButton.setDisabled(false);
this.setError(mw.message('isekai-createpage-page-exists').parse()); //提示页面已经存在
} else {
let targetUrl = mw.util.getUrl(title, { veaction: 'edit' });
this.formGroup.setSuccess([
mw.message('isekai-createpage-redirecting').parse()
]); //提示正在跳转
location.href = targetUrl;
}
});
} else {
this.setError(mw.message('isekai-createpage-title-empty').parse());
}
}
let value = this.pageNameInput.getValue(); onPageNameChange() {
if (value.indexOf('') !== -1 || value.indexOf('`') !== -1) { if (this.hasError) {
let range = this.pageNameInput.getRange(); this.clearError();
value = value.replace(//g, ':').replace(/`/g, '·'); }
this.pageNameInput.setValue(value);
this.pageNameInput.selectRange(range.from, range.to);
}
}
setError(msg) { let value = this.pageNameInput.getValue();
this.formGroup.setErrors([msg]); //提示页面已经存在 if (value.indexOf('') !== -1 || value.indexOf('`') !== -1) {
this.hasError = true; let range = this.pageNameInput.getRange();
} value = value.replace(//g, ':').replace(/`/g, '·');
this.pageNameInput.setValue(value);
this.pageNameInput.selectRange(range.from, range.to);
}
}
clearError() { setError(msg) {
this.formGroup.setErrors([]); this.formGroup.setErrors([msg]); //提示页面已经存在
this.hasError = false; this.hasError = true;
} }
pageExists(title) { clearError() {
return new Promise((resolve, reject) => { this.formGroup.setErrors([]);
this.api.get({ this.hasError = false;
action: 'query', }
titles: title,
}).done((data) => {
if (data.query && data.query.pages) {
if (data.query.pages["-1"]) {
resolve(false);
} else {
resolve(true);
}
} else {
resolve(false);
}
}).fail(reject);
});
}
setTitle(title) { pageExists(title) {
this.title.text(title); return new Promise((resolve, reject) => {
} this.api.get({
} action: 'query',
if (!global.isekai) { titles: title,
global.isekai = {}; }).done((data) => {
if (data.query && data.query.pages) {
if (data.query.pages["-1"]) {
resolve(false);
} else {
resolve(true);
}
} else {
resolve(false);
}
}).fail(reject);
});
}
setTitle(title) {
this.title.text(title);
}
} }
global.isekai.CreatePagePanel = CreatePagePanel;
registerModule('ui.CreatePageWidget', CreatePageWidget);

@ -1,145 +1,145 @@
class Discover { const registerModule = require('../moduleRegister');
constructor(dom){
this.baseDom = dom; class DiscoverWidget {
this.pageUrl = null; constructor(dom){
this.api = new mw.Api(); this.baseDom = dom;
this.pageUrl = null;
this.initDom(); this.api = new mw.Api();
this.refreshPage();
} this.initDom();
this.refreshPage();
initDom(){ }
this.reloadButton = new OO.ui.ButtonWidget({
icon: 'reload', initDom(){
label: mw.message('isekai-discover-change-btn').parse(), this.reloadButton = new OO.ui.ButtonWidget({
}); icon: 'reload',
this.reloadButton.on('click', this.refreshPage.bind(this)); label: mw.message('isekai-discover-change-btn').parse(),
});
this.readMoreButton = new OO.ui.ButtonWidget({ this.reloadButton.on('click', this.refreshPage.bind(this));
icon: 'ellipsis',
label: mw.message('isekai-discover-readmore-btn').parse(), this.readMoreButton = new OO.ui.ButtonWidget({
flags: [ icon: 'ellipsis',
'primary', label: mw.message('isekai-discover-readmore-btn').parse(),
'progressive' flags: [
] 'primary',
}); 'progressive'
this.readMoreButton.on('click', this.showMore.bind(this)); ]
});
this.loadingBar = new OO.ui.ProgressBarWidget({ this.readMoreButton.on('click', this.showMore.bind(this));
progress: false,
}); this.loadingBar = new OO.ui.ProgressBarWidget({
this.baseDom.find('.card-body .loading .spinner').append(this.loadingBar.$element); progress: false,
});
this.buttonGroup = new OO.ui.ButtonGroupWidget({ this.baseDom.find('.card-body .loading .spinner').append(this.loadingBar.$element);
items: [this.reloadButton, this.readMoreButton]
}); this.buttonGroup = new OO.ui.ButtonGroupWidget({
this.baseDom.find('.card-header .card-header-buttons').append(this.buttonGroup.$element); items: [this.reloadButton, this.readMoreButton]
this.loading = this.baseDom.find('.card-body .loading'); });
this.title = this.baseDom.find('.card-body .card-title'); this.baseDom.find('.card-header .card-header-buttons').append(this.buttonGroup.$element);
this.contentContainer = this.baseDom.find('.card-body .card-content'); this.loading = this.baseDom.find('.card-body .loading');
} this.title = this.baseDom.find('.card-body .card-title');
this.contentContainer = this.baseDom.find('.card-body .card-content');
showMore(){ }
if(this.pageUrl){ //页面存在就跳转
window.open(this.pageUrl); showMore(){
} if(this.pageUrl){ //页面存在就跳转
} window.open(this.pageUrl);
}
refreshPage(){ }
this.pageUrl = null;
this.clearContent(); refreshPage(){
this.showLoading(); this.pageUrl = null;
this.getRandomPage().then((title) => { this.clearContent();
this.loadPage(title); this.showLoading();
}); this.getRandomPage().then((title) => {
} this.loadPage(title);
});
setTitle(title){ }
this.title.text(title);
} setTitle(title){
this.title.text(title);
showLoading(){ }
this.loading.show();
this.contentContainer.hide(); showLoading(){
} this.loading.show();
this.contentContainer.hide();
hideLoading(){ }
this.loading.hide();
this.contentContainer.show(); hideLoading(){
} this.loading.hide();
this.contentContainer.show();
clearContent(){ }
this.contentContainer.children().remove();
} clearContent(){
this.contentContainer.children().remove();
setContent(dom){ }
this.hideLoading();
this.clearContent(); setContent(dom){
this.contentContainer.append(dom); this.hideLoading();
} this.clearContent();
this.contentContainer.append(dom);
showError(msg){ }
let errorMsg = new OO.ui.MessageWidget( {
type: 'error', showError(msg){
label: msg, let errorMsg = new OO.ui.MessageWidget( {
}); type: 'error',
label: msg,
this.setContent(errorMsg.$element); });
}
this.setContent(errorMsg.$element);
getRandomPage(){ }
return new Promise((resolve, reject) => {
this.api.get({ getRandomPage(){
action: 'query', return new Promise((resolve, reject) => {
list: 'random', this.api.get({
rnlimit: 1, action: 'query',
rnnamespace: 0, list: 'random',
}).done((data) => { rnlimit: 1,
if(data.query && data.query.random && data.query.random.length > 0){ rnnamespace: 0,
let title = data.query.random[0].title; }).done((data) => {
this.setTitle(title); if(data.query && data.query.random && data.query.random.length > 0){
resolve(title); let title = data.query.random[0].title;
} else if(data.error){ this.setTitle(title);
this.showError(data.error.info); resolve(title);
} else { } else if(data.error){
this.showError(mw.message('isekai-discover-error-cannotload').parse()); this.showError(data.error.info);
} } else {
}); this.showError(mw.message('isekai-discover-error-cannotload').parse());
}); }
} });
});
parseHTMLString(txt) { }
try {
let parser = new DOMParser(); parseHTMLString(txt) {
let xmlDoc = parser.parseFromString(txt, "text/html"); try {
return xmlDoc; let parser = new DOMParser();
} catch(e) { let xmlDoc = parser.parseFromString(txt, "text/html");
console.error(e.message); return xmlDoc;
} } catch(e) {
return null; console.error(e.message);
} }
return null;
loadPage(title){ }
let url = mw.util.getUrl(title);
this.pageUrl = url; loadPage(title){
if(url.indexOf('?') >= 0){ let url = mw.util.getUrl(title);
url += '&'; this.pageUrl = url;
} else { if(url.indexOf('?') >= 0){
url += '?' url += '&';
} } else {
url += 'action=render'; url += '?'
$.get(url, (str) => { }
let dom = $(this.parseHTMLString(str)); url += 'action=render';
let content = dom.find('.mw-parser-output'); $.get(url, (str) => {
if(content.length > 0){ let dom = $(this.parseHTMLString(str));
//删除目录 let content = dom.find('.mw-parser-output');
content.find('.toc').remove(); if(content.length > 0){
this.setContent(content); //删除目录
} content.find('.toc').remove();
}, 'html'); this.setContent(content);
} }
} }, 'html');
if(!global.isekai){ }
global.isekai = {};
} }
global.isekai.Discover = Discover;
registerModule('ui.DiscoverWidget', DiscoverWidget);

@ -0,0 +1 @@
console.log("Hello World!");

@ -0,0 +1,19 @@
function register(namespace, func) {
let nsList = namespace.split('.');
if(!('isekai' in window)){
window.isekai = {};
}
let obj = window.isekai;
for(var i = 0; i < nsList.length - 1; i ++){
let ns = nsList[i];
if(!(ns in obj)){
obj[ns] = {};
}
obj = obj[ns];
}
obj[nsList[i]] = func;
}
module.exports = register;

@ -0,0 +1,27 @@
const registerModule = require('../moduleRegister');
class PreviewCardWidget {
constructor(dom) {
this.baseDom = dom;
this.pageName = null;
this.api = new mw.Api();
this.loaded = false;
this.initDom();
}
initDom() {
this.pageName = this.baseDom.attr('data-title');
this.title = this.baseDom.find('card-title');
}
load() {
if(this.loaded) return;
}
}
registerModule('ui.PreviewCardWidget', PreviewCardWidget);

@ -1,97 +1,54 @@
const path = require('path'); // Generated using webpack-cli https://github.com/webpack/webpack-cli
const webpack = require('webpack');
/*
* SplitChunksPlugin is enabled by default and replaced
* deprecated CommonsChunkPlugin. It automatically identifies modules which
* should be splitted of chunk by heuristics using module duplication count and
* module category (i. e. node_modules). And splits the chunks
*
* It is safe to remove "splitChunks" from the generated configuration
* and was added as an educational example.
*
* https://webpack.js.org/plugins/split-chunks-plugin/
*
*/
const HtmlWebpackPlugin = require('html-webpack-plugin'); const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
/* const isProduction = process.env.NODE_ENV == 'production';
* We've enabled HtmlWebpackPlugin for you! This generates a html const stylesHandler = MiniCssExtractPlugin.loader;
* page for you when you compile webpack, which will make you start
* developing and prototyping faster.
*
* https://github.com/jantimon/html-webpack-plugin
*
*/
module.exports = { const config = {
mode: 'production',
entry: { entry: {
'createPage': './src/createPage/ext.isekai.createPage.js', 'createPage': './src/createPage/ext.isekai.createPage.js',
'discover': './src/discover/ext.isekai.discover.js', 'discover': './src/discover/ext.isekai.discover.js'
}, },
output: {
output: {
filename: '[name]/ext.isekai.[name].js', filename: '[name]/ext.isekai.[name].js',
path: path.resolve(__dirname, 'modules') path: path.resolve(__dirname, 'modules')
}, },
plugins: [
plugins: [new webpack.ProgressPlugin(), new HtmlWebpackPlugin()], new MiniCssExtractPlugin(),
// Add your plugins here
module: { // Learn more about plugins from https://webpack.js.org/configuration/plugins/
rules: [ ],
{ module: {
test: /.(js|jsx)$/, rules: [
include: [path.resolve(__dirname, 'src')], {
loader: 'babel-loader', test: /\.(js|jsx)$/i,
loader: 'babel-loader',
options: { },
plugins: ['syntax-dynamic-import'], {
test: /\.s[ac]ss$/i,
presets: [ use: [stylesHandler, 'css-loader', 'postcss-loader', 'sass-loader'],
[ },
'@babel/preset-env', {
{ test: /\.css$/i,
modules: false use: [stylesHandler, 'css-loader', 'postcss-loader'],
} },
] {
] test: /\.(eot|svg|ttf|woff|woff2|png|jpg|gif)$/i,
} type: 'asset',
}, },
{
test: /.(scss)$/, // Add your rules for custom modules here
use: [{ // Learn more about loaders from https://webpack.js.org/loaders/
loader: 'css-loader', ],
}, },
{ };
loader: 'sass-loader',
}],
},
{
test: /.(less)$/,
loader: 'less-loader',
}
]
},
optimization: {
splitChunks: {
cacheGroups: {
vendors: {
priority: -10,
test: /[\\/]node_modules[\\/]/
}
},
chunks: 'async',
minChunks: 1,
minSize: 30000,
name: true
}
},
devServer: { module.exports = () => {
open: true if (isProduction) {
} config.mode = 'production';
} else {
config.mode = 'development';
}
return config;
}; };

Loading…
Cancel
Save