Create Project

master
落雨楓 4 years ago
commit d4d6f11f3c

1
.gitignore vendored

@ -0,0 +1 @@
node_modules/

@ -0,0 +1,49 @@
# Isekai Create Page widget
## Useage
```
<createpage />
```
## Screenshots
![Screenshot](https://imgur.com/IcVNDwW.png)
![Screenshot](https://imgur.com/FAkh3gK.png)
# 异世界百科 磁贴
## 截图
![Screenshot](https://i.imgur.com/RM51jak.png)
## 用法
### 磁贴容器
用来把多个磁贴拼成一块的
```html
<tilegroup>
<tile></tile>
</tilegroup>
```
参数
| 参数名 | 参数值 | 介绍 |
| ------ | ----- | ---- |
| size | xs-12 sm-12 md-12 lg-12 xl-12 xxl-12 | 控制不同屏幕上的显示宽度和bootstrap的col差不多最宽为12 |
| title | * | 这一组磁贴的标题 |
### 磁贴
显示一个矩形的磁贴
```html
<tile>title</tile>
```
参数
| 参数名 | 参数值 | 介绍 |
| ------ | ----- | ---- |
| size | app,small,medium,wide,large | 控制磁贴大小 |
| icon | fa fa-fw fa-map | 磁贴的图标可以是文件路径或者css类 |
| 内容 | title | 磁贴的标题 |
| badge | 1 | 磁贴左上角显示的数字(未读消息) |
| color | #ccc | 磁贴的颜色 |
| href | [[首页]] | 指向链接,支持使用 ```[[]]``` 表示文章链接 |
| grid | 1 2 | grid位置格式为 ```<colum> <row>``` |

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

@ -0,0 +1,18 @@
{
"isekai-widgets": "Isekai Widgets",
"isekai-widgets-desc": "Some custom widgets used on Isekai Wiki",
"isekai-createpage-page-title": "Title for new page",
"isekai-createpage-create-page": "Create page",
"isekai-createpage-create-page-button": "Create",
"isekai-createpage-page-exists": "A page with the same name already exists. Please use another name.",
"isekai-createpage-title-empty": "Please input title.",
"isekai-createpage-redirecting": "Redirecting, please wait...",
"isekai-discover-langcode": "en",
"isekai-discover-randompage": "Random Page",
"isekai-discover-loading": "Loading...",
"isekai-discover-change-btn": "Another",
"isekai-discover-readmore-btn": "Detail",
"isekai-discover-error-cannotload": "Cannot load page from server."
}

@ -0,0 +1,17 @@
{
"isekai-widgets-desc": "異世界ウィキで使用するカスタムウィジェットたち",
"isekai-createpage-page-title": "新しいページの名",
"isekai-createpage-create-page": "ページを新規作成",
"isekai-createpage-create-page-button": "作成",
"isekai-createpage-page-exists": "同じタイトルのページが既に存在します。変更してください。",
"isekai-createpage-title-empty": "おタイトルを入力してください",
"isekai-createpage-redirecting": "ジャンプしてお待ちください...",
"isekai-discover-langcode": "ja",
"isekai-discover-randompage": "おまかせ表示",
"isekai-discover-loading": "読み込み中...",
"isekai-discover-change-btn": "変える",
"isekai-discover-readmore-btn": "開く",
"isekai-discover-error-cannotload": "サーバからのページを読み取りに失敗しま。"
}

@ -0,0 +1,18 @@
{
"isekai-widgets": "异世界百科 小部件",
"isekai-widgets-desc": "在异世界百科上使用的一些小部件",
"isekai-createpage-page-title": "页面标题",
"isekai-createpage-create-page": "新建页面",
"isekai-createpage-create-page-button": "创建",
"isekai-createpage-page-exists": "已有相同名字的页面存在,换一个名字吧。",
"isekai-createpage-title-empty": "请填写标题",
"isekai-createpage-redirecting": "正在跳转,请稍后……",
"isekai-discover-langcode": "zh",
"isekai-discover-randompage": "随机页面",
"isekai-discover-loading": "加载中……",
"isekai-discover-change-btn": "换一个",
"isekai-discover-readmore-btn": "查看",
"isekai-discover-error-cannotload": "无法从服务器加载数据"
}

@ -0,0 +1,18 @@
{
"isekai-widgets": "異世界百科 小部件",
"isekai-widgets-desc": "在異世界百科上使用的一些小部件",
"isekai-createpage-page-title": "頁面標題",
"isekai-createpage-create-page": "建立頁面",
"isekai-createpage-create-page-button": "創建",
"isekai-createpage-page-exists": "已有相同名字的頁面存在,換一個名字吧。",
"isekai-createpage-title-empty": "请填写标题",
"isekai-createpage-redirecting": "正在跳轉,請稍後……",
"isekai-discover-langcode": "zh",
"isekai-discover-randompage": "隨機頁面",
"isekai-discover-loading": "讀取中……",
"isekai-discover-change-btn": "換一個",
"isekai-discover-readmore-btn": "詳情",
"isekai-discover-error-cannotload": "無法從伺服器讀取數據"
}

@ -0,0 +1,17 @@
<?php
namespace Isekai\Widgets;
class CreatePageWidget {
public static function getHtml(){
ob_start();
include(dirname(__DIR__) . '/modules/createPage/ext.isekai.createPageWidget.tpl');
$template = ob_get_clean();
return [$template, "markerType" => 'nowiki'];
}
public static function create($text, $params, $parser, $frame){
$parser->getOutput()->addModules('ext.isekai.createPage');
return self::getHtml();
}
}

@ -0,0 +1,17 @@
<?php
namespace Isekai\Widgets;
class DiscoverWidget {
public static function getHtml(){
ob_start();
include(dirname(__DIR__) . '/modules/discover/ext.isekai.discover.tpl');
$template = ob_get_clean();
return [$template, "markerType" => 'nowiki'];
}
public static function create($text, $params, \Parser $parser, $frame){
$parser->getOutput()->addModules('ext.isekai.discover');
return self::getHtml();
}
}

@ -0,0 +1,94 @@
<?php
namespace Isekai\Widgets;
use Html;
class TileGroupWidget {
private $content = '';
private $size = [];
private $title = false;
private $attributes = [];
private $classes = [];
private $styles = [];
public function __construct($args){
$this->parseArgs($args);
}
public static function create(string $text, array $args, \Parser $parser, \PPFrame $frame){
$content = $parser->recursiveTagParse($text, $frame);
$args['content'] = $content;
$tileGroup = new TileGroupWidget($args);
return [$tileGroup->getHtml(), "markerType" => 'nowiki'];
}
private function parseArgs($args){
$allowedArgs = ['content', 'size', 'title', 'class', 'style'];
if(isset($args['content'])){
$this->content = $args['content'];
}
if(isset($args['size'])){
$this->size = explode(' ', str_replace('size-', '', $args['size']));
}
if(isset($args['title'])){
$this->title = $args['title'];
}
if(isset($args['class'])){
$this->classes = explode(' ', $args['class']);
}
if(isset($args['style'])){
$this->classes = explode(' ', $args['style']);
}
foreach($args as $name => $arg){
if(!in_array($name, $allowedArgs) && substr($name, 0, 2) !== 'on'){
$this->attributes[$name] = $arg;
}
}
}
private function getSizeArgs(array &$element){
if(!empty($this->size)){
$sizeAttr = [];
foreach($this->size as $size){
$sizeAttr[] = 'size-' . $size;
}
$element['class'] = array_merge($element['class'], $sizeAttr);
}
}
private function getTitleArgs(array &$element){
if($this->title){
$element['data-group-title'] = $this->title;
}
}
public function getHtml(){
$element = array_merge($this->attributes, [
'class' => array_merge($this->classes, ['tiles-grid', 'tiles-group']),
'style' => $this->styles,
]);
$this->getSizeArgs($element);
$this->getTitleArgs($element);
if(!empty($element['class'])){
$element['class'] = implode(' ', $element['class']);
} else {
unset($element['class']);
}
if(!empty($element['style'])){
$element['style'] = implode('; ', $element['style']) . ';';
} else {
unset($element['style']);
}
return Html::rawElement('div', $element, $this->content);
}
}

@ -0,0 +1,181 @@
<?php
namespace Isekai\Widgets;
use Html;
use Title;
class TileWidget {
private $size = 'medium';
private $icon = false;
private $title = '';
private $href = '';
private $badge = false;
private $color = false;
private $images = [];
private $grid = false;
private $attributes = [];
public function __construct($args){
$this->parseArgs($args);
}
public static function create(string $text, array $args, \Parser $parser, \PPFrame $frame){
$parser->getOutput()->addModules('ext.isekai.tile');
if($text){
$args['title'] = $text;
}
$tile = new TileWidget($args);
return [$tile->toHtml(), 'markerType' => 'nowiki'];
}
private function parseArgs($args){
$allowedArgs = ['size', 'icon', 'title', 'badge', 'color', 'href', 'grid'];
foreach($args as $name => $arg){
if(in_array($name, $allowedArgs)){
$this->$name = $arg;
} elseif(substr($name, 0, 2) !== 'on'){
$this->attributes[$name] = $arg;
}
}
}
private function getSizeArgs(array &$element, array &$content){
$element['data-size'] = $this->size;
$element['class'][] = 'tile-' . $this->size;
}
private function getColorArgs(array &$element, array &$content){
if($this->color){
if(substr($this->color, 0, 1) == '#' || substr($this->color, 0, 3) == 'rgb'){
$element['style'][] = 'background-color: ' . $this->color;
} else {
$color = str_replace($this->color, 'bg-', '');
$element['class'][] = 'bg-' . $color;
}
}
}
private function getTitleArgs(array &$element, array &$content){
if(!empty($this->title)){
$content[] = Html::element('span', [
'class' => ['branding-bar'],
], $this->title);
$element['data-title'] = $this->title;
}
}
private function getHrefArgs(array &$element, array &$content){
if(substr($this->href, 0, 2) == '[[' && substr($this->href, -2, 2) == ']]'){ //内部链接
$titleText = substr($this->href, 2, strlen($this->href) - 4);
$title = Title::newFromText($titleText);
$href = $title->getLocalURL();
} else {
$href = $this->href;
}
$element['href'] = $href;
}
private function getIconArgs(array &$element, array &$content){
if($this->icon){
if(is_string($this->icon)){
if(preg_match('/\.[a-zA-Z0-9]{3,4}$/', $this->icon)){
//图片图标
$iconSrc = $this->icon;
$type = 'image';
} else {
$iconSrc = explode(' ', $this->icon);
$type = 'class';
}
} else {
$type = 'class';
$iconSrc = $this->icon;
}
if($type == 'class'){
$content[] = Html::element('span', [
'class' => array_merge($iconSrc, ['icon']),
]);
} elseif($type == 'image'){
$content[] = Html::element('img', [
'src' => $iconSrc,
'class' => ['icon'],
]);
}
}
}
private function getBadgeArgs(array &$element, array &$content){
if($this->badge){
$content[] = Html::element('span', [
'class' => ['badge-bottom'],
], strval($this->badge));
}
}
private function getImagesArgs(array &$element, array &$content){
if(!empty($this->images)){
$element['data-effect'] = 'image-set';
foreach($this->images as $image){
$content[] = Html::element('img', [
'src' => $image,
]);
}
}
}
private function getGridArgs(array &$element, array &$content){
if($this->grid){
$grid = explode(' ', $this->grid);
$element['class'][] = 'col-' . $grid[0];
if(count($grid) > 1){
$element['class'][] = 'row-' . $grid[1];
}
}
}
public function toHtml(){
$element = array_merge($this->attributes, [
'data-role' => 'tile',
]);
$content = [];
if(isset($element['class'])){
$element['class'] = explode(' ', $element['class']);
} else {
$element['class'] = [];
}
if(isset($element['style'])){
$element['style'] = explode(' ', $element['style']);
} else {
$element['style'] = [];
}
$this->getSizeArgs($element, $content);
$this->getColorArgs($element, $content);
$this->getIconArgs($element, $content);
$this->getTitleArgs($element, $content);
$this->getHrefArgs($element, $content);
$this->getBadgeArgs($element, $content);
$this->getImagesArgs($element, $content);
$this->getGridArgs($element, $content);
$content = implode('', $content);
if(!empty($element['class'])){
$element['class'] = implode(' ', $element['class']);
} else {
unset($element['class']);
}
if(!empty($element['style'])){
$element['style'] = implode('; ', $element['style']) . ';';
} else {
unset($element['style']);
}
return Html::rawElement('a', $element, $content);
}
}

@ -0,0 +1,13 @@
<?php
namespace Isekai\Widgets;
class Widgets {
public static function onParserSetup(&$parser){
$parser->setHook('createpage', CreatePageWidget::class . '::create');
$parser->setHook('discoverbox', DiscoverWidget::class . '::create');
$parser->setHook('tile', TileWidget::class . '::create');
$parser->setHook('tilegroup', TileGroupWidget::class . '::create');
return true;
}
}

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

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

@ -0,0 +1,67 @@
@height: 2.25em;
@text-size: 0.95em;
.create-page-panel {
position: relative;
display: flex;
flex-direction: column;
min-width: 0;
word-wrap: break-word;
background-color: #fff;
background-clip: border-box;
border: 1px solid rgba(0,0,0,.125);
border-radius: .25rem;
.card-header {
padding: .75rem 1.25rem;
margin-bottom: 0;
background-color: rgba(0,0,0,.03);
border-bottom: 1px solid rgba(0,0,0,.125);
display: flex;
align-items: center;
&:first-child {
border-radius: calc(.25rem - 1px) calc(.25rem - 1px) 0 0;
}
.card-header-text {
font-size: 1.25em;
}
@media(max-width: 360px){
.card-header-text {
font-size: 1em;
}
}
}
.card-title {
margin: 1em 0 0.75em 1em;
}
.card-body {
flex: 1 1 auto;
padding: 0.25em;
font-size: 1.25em;
.card-content {
overflow-y: auto;
padding: 1em 0.5em;
margin: 0 0.4em;
min-height: @height;
font-size: @text-size;
.oo-ui-fieldLayout-header {
display: none;
}
.oo-ui-fieldLayout-messages {
margin: 0.5em 0 0 0.5em;
}
.oo-ui-actionFieldLayout.oo-ui-fieldLayout-align-top {
max-width: none;
}
}
}
}

@ -0,0 +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))}]);

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

@ -0,0 +1,9 @@
<!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>

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

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

@ -0,0 +1,146 @@
@height: 20em;
@text-size: 0.85em;
.discover-card {
position: relative;
display: flex;
flex-direction: column;
min-width: 0;
word-wrap: break-word;
background-color: #fff;
background-clip: border-box;
border: 1px solid rgba(0,0,0,.125);
border-radius: .25rem;
.card-header {
padding: .75rem 1.25rem;
margin-bottom: 0;
background-color: rgba(0,0,0,.03);
border-bottom: 1px solid rgba(0,0,0,.125);
display: flex;
align-items: center;
&:first-child {
border-radius: calc(.25rem - 1px) calc(.25rem - 1px) 0 0;
}
.card-header-text {
font-size: 1.25em;
}
.card-header-buttons {
margin-left: auto;
}
}
.card-title {
margin: 1em 0 0.75em 1em;
}
.card-body {
flex: 1 1 auto;
padding: 0.25em;
font-size: 1.25em;
.loading {
width: 100%;
height: @height;
font-size: @text-size;
margin-top: 1px;
display: flex;
.spinner {
margin: auto;
padding: 2em;
width: 100%;
}
}
.card-content {
height: @height;
overflow-y: auto;
border-top: 1px solid #ccc;
padding: 0 0.6em;
margin: 0 0.4em;
font-size: @text-size;
}
}
&.discover-card-zh {
.card-header {
@media(max-width: 410px){
.card-header-buttons {
font-size: 0.9em;
}
}
@media(max-width: 380px){
.card-header-buttons {
font-size: 0.8em;
}
}
@media(max-width: 360px){
.card-header-text {
font-size: 1em;
}
}
@media(max-width: 350px){
.card-header-text {
font-size: 1.25em;
}
.card-header-buttons {
margin-left: 0;
margin-top: 0.8em;
font-size: 1em;
}
& {
flex-direction: column;
}
}
}
}
&.discover-card-en {
.card-header {
@media(max-width: 500px){
.card-header-text {
font-size: 1em;
}
.card-header-buttons {
font-size: 0.8em;
}
}
@media(max-width: 430px){
.card-header-text {
font-size: 1.25em;
}
.card-header-buttons {
margin-left: 0;
margin-top: 0.8em;
font-size: 1em;
}
& {
flex-direction: column;
}
}
@media(max-width: 350px){
.card-header-text {
font-size: 1em;
}
.card-header-buttons {
font-size: 0.8em;
}
}
}
}
}

@ -0,0 +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))}});

@ -0,0 +1,104 @@
@height: 20em;
@text-size: 0.85em;
.discover-card {
position: relative;
display: flex;
flex-direction: column;
min-width: 0;
word-wrap: break-word;
background-color: #fff;
background-clip: border-box;
border: 1px solid rgba(0,0,0,.125);
border-radius: .25rem;
.card-header {
padding: .75rem 1.25rem;
margin-bottom: 0;
background-color: rgba(0,0,0,.03);
border-bottom: 1px solid rgba(0,0,0,.125);
display: flex;
align-items: center;
&:first-child {
border-radius: calc(.25rem - 1px) calc(.25rem - 1px) 0 0;
}
.card-header-text {
font-size: 1.25em;
}
.card-header-buttons {
margin-left: auto;
}
@media(max-width: 500px){
.card-header-text {
font-size: 1em;
}
.card-header-buttons {
font-size: 0.8em;
}
}
@media(max-width: 430px){
.card-header-text {
font-size: 1.25em;
}
.card-header-buttons {
margin-left: 0;
margin-top: 0.8em;
font-size: 1em;
}
& {
flex-direction: column;
}
}
@media(max-width: 350px){
.card-header-text {
font-size: 1em;
}
.card-header-buttons {
font-size: 0.8em;
}
}
}
.card-title {
margin: 1em 0 0.75em 1em;
}
.card-body {
flex: 1 1 auto;
padding: 0.25em;
font-size: 1.25em;
.loading {
width: 100%;
height: @height;
font-size: @text-size;
margin-top: 1px;
display: flex;
.spinner {
margin: auto;
padding: 2em;
width: 100%;
}
}
.card-content {
height: @height;
overflow-y: auto;
border-top: 1px solid #ccc;
padding: 0 0.6em;
margin: 0 0.4em;
font-size: @text-size;
}
}
}

@ -0,0 +1,13 @@
<div class="isekai-discover discover-card discover-card-<?php echo wfMessage('isekai-discover-langcode')->parse(); ?>">
<div class="card-header">
<span class="card-header-text" data-msg="isekai-discover-randompage"><?php echo wfMessage('isekai-discover-randompage')->parse(); ?></span>
<span class="card-header-buttons"></span>
</div>
<div class="card-body">
<div class="card-title" data-msg="isekai-discover-loading"><?php echo wfMessage('isekai-discover-loading')->parse(); ?></div>
<div class="loading">
<div class="spinner"></div>
</div>
<div class="card-content" style="display: none;"></div>
</div>
</div>

@ -0,0 +1,21 @@
a {
&.tile-small,
&.tile-medium,
&.tile-wide,
&.tile-large,
&.tile-app {
color: #fff;
}
}
.tiles-group {
margin: 5px 0;
}
.tiles-group::before {
font-size: 1.2em;
}
.tiles-group[data-group-title] {
margin-top: 3em;
}

File diff suppressed because it is too large Load Diff

@ -0,0 +1,841 @@
/* global Colors */
var TileDefaultConfig = {
tileDeferred: 0,
size: "medium",
cover: "",
coverPosition: "center",
effect: "",
effectInterval: 3000,
effectDuration: 500,
target: null,
canTransform: true,
onClick: () => {},
onTileCreate: () => {},
};
var METRO_THROWS = true;
var GRID_GAP = 5;
if(typeof isekai == 'undefined'){
var isekai = {};
}
isekai.tile = {};
isekai.tile.setup = function (options) {
TileDefaultConfig = jQuery.extend({}, TileDefaultConfig, options);
};
isekai.tile.init = function () {
};
(function($){
var Utils = {
isValue: function(val){
return val !== undefined && val !== null && val !== "";
},
isUrl: function (val) {
/* eslint-disable-next-line */
return /^(\.\/|\.\.\/|ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@\-\/]))?/.test(val);
},
isTag: function(val){
/* eslint-disable-next-line */
return /^<\/?[\w\s="/.':;#-\/\?]+>/gi.test(val);
},
isType: function(o, t){
if (!Utils.isValue(o)) {
return false;
}
if (typeof o === t) {
return o;
}
if (Utils.isTag(o) || Utils.isUrl(o)) {
return false;
}
if (typeof window[o] === t) {
return window[o];
}
if (typeof o === 'string' && o.indexOf(".") === -1) {
return false;
}
if (typeof o === 'string' && o.indexOf("/") !== -1) {
return false;
}
if (typeof o === 'string' && o.indexOf(" ") !== -1) {
return false;
}
if (typeof o === 'string' && o.indexOf("(") !== -1) {
return false;
}
if (typeof o === 'string' && o.indexOf("[") !== -1) {
return false;
}
if (typeof o === "number" && t.toLowerCase() !== "number") {
return false;
}
var ns = o.split(".");
var i, context = window;
for(i = 0; i < ns.length; i++) {
context = context[ns[i]];
}
return typeof context === t ? context : false;
},
isFunc: function(f){
return Utils.isType(f, 'function');
},
/**
*
* @param {TouchEvent|Event|MouseEvent} e
* @returns {{x: (*), y: (*)}}
*/
pageXY: function(e){
return {
x: e.changedTouches ? e.changedTouches[0].pageX : e.pageX,
y: e.changedTouches ? e.changedTouches[0].pageY : e.pageY
};
},
isRightMouse: function(e){
return "which" in e ? e.which === 3 : "button" in e ? e.button === 2 : undefined;
},
func: function(f){
/* jshint -W054 */
return new Function("a", f);
},
exec: function(f, args, context){
var result;
if (f === undefined || f === null) {return false;}
var func = Utils.isFunc(f);
if (func === false) {
func = Utils.func(f);
}
try {
result = func.apply(context, args);
} catch (err) {
result = null;
if (METRO_THROWS === true) {
throw err;
}
}
return result;
},
};
var FrameAnimation = {
duration: 100,
func: "linear",
switch: function(current, next){
current.hide();
next.css({top: 0, left: 0}).show();
},
slideUp: function(current, next, duration, func){
var h = current.parent().outerHeight(true);
if (duration === undefined) {duration = this.duration;}
if (func === undefined) {func = this.func;}
current
.css("z-index", 1)
.animate({
draw: {
top: -h,
opacity: 0
},
dur: duration,
ease: func
});
next
.css({
top: h,
left: 0,
zIndex: 2
})
.animate({
draw: {
top: 0,
opacity: 1
},
dur: duration,
ease: func
});
},
slideDown: function(current, next, duration, func){
var h = current.parent().outerHeight(true);
if (duration === undefined) {duration = this.duration;}
if (func === undefined) {func = this.func;}
current
.css("z-index", 1)
.animate({
draw: {
top: h,
opacity: 0
},
dur: duration,
ease: func
});
next
.css({
left: 0,
top: -h,
zIndex: 2
})
.animate({
draw: {
top: 0,
opacity: 1
},
dur: duration,
ease: func
});
},
slideLeft: function(current, next, duration, func){
var w = current.parent().outerWidth(true);
if (duration === undefined) {duration = this.duration;}
if (func === undefined) {func = this.func;}
current
.css("z-index", 1)
.animate({
draw: {
left: -w,
opacity: 0
},
dur: duration,
ease: func
});
next
.css({
left: w,
zIndex: 2
})
.animate({
draw: {
left: 0,
opacity: 1
},
dur: duration,
ease: func
});
},
slideRight: function(current, next, duration, func){
var w = current.parent().outerWidth(true);
if (duration === undefined) {duration = this.duration;}
if (func === undefined) {func = this.func;}
current
.css("z-index", 1)
.animate({
draw: {
left: w,
opacity: 0
},
dur: duration,
ease: func
});
next
.css({
left: -w,
zIndex: 2
})
.animate({
draw: {
left: 0,
opacity: 1
},
dur: duration,
ease: func
});
},
fade: function(current, next, duration){
if (duration === undefined) {duration = this.duration;}
current
.animate({
draw: {
opacity: 0
},
dur: duration
});
next
.css({
top: 0,
left: 0,
opacity: 0
})
.animate({
draw: {
opacity: 1
},
dur: duration
});
}
};
var Colors = {
PALETTES: {
ALL: "colorList",
METRO: "colorListMetro",
STANDARD: "colorListStandard"
},
colorListMetro: {
lime: '#a4c400',
green: '#60a917',
emerald: '#008a00',
blue: '#00AFF0',
teal: '#00aba9',
cyan: '#1ba1e2',
cobalt: '#0050ef',
indigo: '#6a00ff',
violet: '#aa00ff',
pink: '#dc4fad',
magenta: '#d80073',
crimson: '#a20025',
red: '#CE352C',
orange: '#fa6800',
amber: '#f0a30a',
yellow: '#fff000',
brown: '#825a2c',
olive: '#6d8764',
steel: '#647687',
mauve: '#76608a',
taupe: '#87794e'
},
colorListStandard: {
aliceBlue: "#f0f8ff",
antiqueWhite: "#faebd7",
aqua: "#00ffff",
aquamarine: "#7fffd4",
azure: "#f0ffff",
beige: "#f5f5dc",
bisque: "#ffe4c4",
black: "#000000",
blanchedAlmond: "#ffebcd",
blue: "#0000ff",
blueViolet: "#8a2be2",
brown: "#a52a2a",
burlyWood: "#deb887",
cadetBlue: "#5f9ea0",
chartreuse: "#7fff00",
chocolate: "#d2691e",
coral: "#ff7f50",
cornflowerBlue: "#6495ed",
cornsilk: "#fff8dc",
crimson: "#dc143c",
cyan: "#00ffff",
darkBlue: "#00008b",
darkCyan: "#008b8b",
darkGoldenRod: "#b8860b",
darkGray: "#a9a9a9",
darkGreen: "#006400",
darkKhaki: "#bdb76b",
darkMagenta: "#8b008b",
darkOliveGreen: "#556b2f",
darkOrange: "#ff8c00",
darkOrchid: "#9932cc",
darkRed: "#8b0000",
darkSalmon: "#e9967a",
darkSeaGreen: "#8fbc8f",
darkSlateBlue: "#483d8b",
darkSlateGray: "#2f4f4f",
darkTurquoise: "#00ced1",
darkViolet: "#9400d3",
deepPink: "#ff1493",
deepSkyBlue: "#00bfff",
dimGray: "#696969",
dodgerBlue: "#1e90ff",
fireBrick: "#b22222",
floralWhite: "#fffaf0",
forestGreen: "#228b22",
fuchsia: "#ff00ff",
gainsboro: "#DCDCDC",
ghostWhite: "#F8F8FF",
gold: "#ffd700",
goldenRod: "#daa520",
gray: "#808080",
green: "#008000",
greenYellow: "#adff2f",
honeyDew: "#f0fff0",
hotPink: "#ff69b4",
indianRed: "#cd5c5c",
indigo: "#4b0082",
ivory: "#fffff0",
khaki: "#f0e68c",
lavender: "#e6e6fa",
lavenderBlush: "#fff0f5",
lawnGreen: "#7cfc00",
lemonChiffon: "#fffacd",
lightBlue: "#add8e6",
lightCoral: "#f08080",
lightCyan: "#e0ffff",
lightGoldenRodYellow: "#fafad2",
lightGray: "#d3d3d3",
lightGreen: "#90ee90",
lightPink: "#ffb6c1",
lightSalmon: "#ffa07a",
lightSeaGreen: "#20b2aa",
lightSkyBlue: "#87cefa",
lightSlateGray: "#778899",
lightSteelBlue: "#b0c4de",
lightYellow: "#ffffe0",
lime: "#00ff00",
limeGreen: "#32dc32",
linen: "#faf0e6",
magenta: "#ff00ff",
maroon: "#800000",
mediumAquaMarine: "#66cdaa",
mediumBlue: "#0000cd",
mediumOrchid: "#ba55d3",
mediumPurple: "#9370db",
mediumSeaGreen: "#3cb371",
mediumSlateBlue: "#7b68ee",
mediumSpringGreen: "#00fa9a",
mediumTurquoise: "#48d1cc",
mediumVioletRed: "#c71585",
midnightBlue: "#191970",
mintCream: "#f5fffa",
mistyRose: "#ffe4e1",
moccasin: "#ffe4b5",
navajoWhite: "#ffdead",
navy: "#000080",
oldLace: "#fdd5e6",
olive: "#808000",
oliveDrab: "#6b8e23",
orange: "#ffa500",
orangeRed: "#ff4500",
orchid: "#da70d6",
paleGoldenRod: "#eee8aa",
paleGreen: "#98fb98",
paleTurquoise: "#afeeee",
paleVioletRed: "#db7093",
papayaWhip: "#ffefd5",
peachPuff: "#ffdab9",
peru: "#cd853f",
pink: "#ffc0cb",
plum: "#dda0dd",
powderBlue: "#b0e0e6",
purple: "#800080",
rebeccaPurple: "#663399",
red: "#ff0000",
rosyBrown: "#bc8f8f",
royalBlue: "#4169e1",
saddleBrown: "#8b4513",
salmon: "#fa8072",
sandyBrown: "#f4a460",
seaGreen: "#2e8b57",
seaShell: "#fff5ee",
sienna: "#a0522d",
silver: "#c0c0c0",
slyBlue: "#87ceeb",
slateBlue: "#6a5acd",
slateGray: "#708090",
snow: "#fffafa",
springGreen: "#00ff7f",
steelBlue: "#4682b4",
tan: "#d2b48c",
teal: "#008080",
thistle: "#d8bfd8",
tomato: "#ff6347",
turquoise: "#40e0d0",
violet: "#ee82ee",
wheat: "#f5deb3",
white: "#ffffff",
whiteSmoke: "#f5f5f5",
yellow: "#ffff00",
yellowGreen: "#9acd32"
},
colorList: {},
colors: function(palette){
var c = [];
palette = palette || this.PALETTES.ALL;
$.each(this[palette], function(){
c.push(this);
});
return c;
},
}
function Tile(options, element){
this.init = function(options, element) {
this.effectInterval = false;
this.images = [];
this.slides = [];
this.currentSlide = -1;
this.options = $.extend({}, TileDefaultConfig, options);
this.element = element;
this.hasIcon = false;
this.hasBranding = false;
this._fixSizeCallback = this.resize.bind(this);
this._create();
};
this._create = function(){
this._createTile();
this._createEvents();
this.element.trigger("tilecreate");
};
this._createTile = function(){
function switchImage(el, img_src, i){
$.setTimeout(function(){
el.fadeOut(500, function(){
el.css("background-image", "url(" + img_src + ")");
el.fadeIn();
});
}, i * 300);
}
var that = this, element = this.element, o = this.options;
var slides = element.find(".slide");
var slides2 = element.find(".slide-front, .slide-back");
element.addClass("tile-" + o.size);
if(element.find('.icon').length > 0){
this.hasIcon = true;
}
if(element.find('.branding-bar')){
this.hasBranding = true;
}
if (o.effect.indexOf("hover-") > -1) {
element.addClass("effect-" + o.effect);
$.each(slides2, function(){
var slide = $(this);
if (slide.data("cover") !== undefined) {
that._setCover(slide, slide.data("cover"), slide.data("cover-position"));
}
})
}
if (o.effect.indexOf("animate-") > -1 && slides.length > 1) {
$.each(slides, function(i){
var slide = $(this);
that.slides.push(this);
if (slide.data("cover") !== undefined) {
this._setCover(slide, slide.data("cover"), slide.data("cover-position"));
}
if (i > 0) {
if (["animate-slide-up", "animate-slide-down"].indexOf(o.effect) > -1) slide.css("top", "100%");
if (["animate-slide-left", "animate-slide-right"].indexOf(o.effect) > -1) slide.css("left", "100%");
if (["animate-fade"].indexOf(o.effect) > -1) slide.css("opacity", 0);
}
});
this.currentSlide = 0;
this._runEffects();
}
if (o.cover !== "") {
this._setCover(element, o.cover);
}
if (o.effect === "image-set") {
element.addClass("image-set");
$.each(element.children("img"), function(){
that.images.push(this);
$(this).remove();
});
var temp = this.images.slice();
for(var i = 0; i < 5; i++) {
var rnd_index = $.random(0, temp.length - 1);
var div = $("<div>").addClass("img -js-img-"+i).css("background-image", "url("+temp[rnd_index].src+")");
element.prepend(div);
temp.splice(rnd_index, 1);
}
var a = [0, 1, 4, 3, 2];
$.setInterval(function(){
var temp = that.images.slice();
var colors = Colors.colors(Colors.PALETTES.ALL), bg;
bg = colors[$.random(0, colors.length - 1)];
element.css("background-color", bg);
for(var i = 0; i < a.length; i++) {
var rnd_index = $.random(0, temp.length - 1);
var div = element.find(".-js-img-"+a[i]);
switchImage(div, temp[rnd_index].src, i);
temp.splice(rnd_index, 1);
}
a = a.reverse();
}, 5000);
}
};
this._runEffects = function(){
var o = this.options;
if (this.effectInterval === false) this.effectInterval = $.setInterval(function(){
var current, next;
current = $(this.slides[this.currentSlide]);
this.currentSlide++;
if (this.currentSlide === this.slides.length) {
this.currentSlide = 0;
}
next = this.slides[this.currentSlide];
if (o.effect === "animate-slide-up") FrameAnimation.slideUp($(current), $(next), o.effectDuration);
if (o.effect === "animate-slide-down") FrameAnimation.slideDown($(current), $(next), o.effectDuration);
if (o.effect === "animate-slide-left") FrameAnimation.slideLeft($(current), $(next), o.effectDuration);
if (o.effect === "animate-slide-right") FrameAnimation.slideRight($(current), $(next), o.effectDuration);
if (o.effect === "animate-fade") FrameAnimation.fade($(current), $(next), o.effectDuration);
}, o.effectInterval);
};
this._stopEffects = function(){
$.clearInterval(this.effectInterval);
this.effectInterval = false;
};
this.resize = function(){
var ratio = 1;
var padding = 0;
var grid = this.element.parent('.tiles-grid');
var gridWidth = 0;
if(grid.length > 0){
gridWidth = grid.width();
}
if(this.options.size == 'wide'){
ratio = 0.5;
}
//修正长宽比
var height = this.element.width() * ratio - padding;
//this.element.height(height);
if(this.hasIcon){
var fontSize = height * 0.33;
var iconDom = this.element.find('.icon');
iconDom.css('font-size', fontSize + 'px');
if(this.hasBranding){ //计算与标签的重叠
var iconBottom = (height + fontSize) / 2;
var brandingTop = height - this.element.find('.branding-bar').outerHeight();
var overlap = iconBottom - brandingTop + (height * 0.1);
if(overlap > 0){
iconDom.css('padding-bottom', overlap + 'px');
}
}
}
}
this._setCover = function(to, src, pos){
if (!Utils.isValue(pos)) {
pos = this.options.coverPosition;
}
to.css({
backgroundImage: "url("+src+")",
backgroundSize: "cover",
backgroundRepeat: "no-repeat",
backgroundPosition: pos
});
};
this._createEvents = function(){
var element = this.element, o = this.options;
element.on('mousedown touchstart', function(e){
var tile = $(this);
var dim = {w: element.width(), h: element.height()};
var X = Utils.pageXY(e).x - tile.offset().left,
Y = Utils.pageXY(e).y - tile.offset().top;
var side;
if (Utils.isRightMouse(e) === false) {
if (X < dim.w * 1 / 3 && (Y < dim.h * 1 / 2 || Y > dim.h * 1 / 2)) {
side = 'left';
} else if (X > dim.w * 2 / 3 && (Y < dim.h * 1 / 2 || Y > dim.h * 1 / 2)) {
side = 'right';
} else if (X > dim.w * 1 / 3 && X < dim.w * 2 / 3 && Y > dim.h / 2) {
side = 'bottom';
} else {
side = "top";
}
if (o.canTransform === true) tile.addClass("transform-" + side);
if (o.target !== null) {
setTimeout(function(){
document.location.href = o.target;
}, 100);
}
Utils.exec(o.onClick, [side], element[0]);
element.trigger("click", {
side: side
});
}
});
element.on('mouseup touchend mouseleave', function(){
$(this)
.removeClass("transform-left")
.removeClass("transform-right")
.removeClass("transform-top")
.removeClass("transform-bottom");
});
$(window).on('resize', this._fixSizeCallback);
$(this._fixSizeCallback);
};
this.destroy = function(){
var element = this.element;
element.off('mousedown touchstart');
element.off('mouseup touchend mouseleave');
$(window).off('resize', this._fixSizeCallback);
this._stopEffects();
};
this.init(options, element);
};
function getElementOptions(element){
var options = {};
$.each(element[0].attributes, function (index, attribute){
if(attribute.name.startsWith('data-')){
options[attribute.name.substr(5)] = attribute.value;
}
});
return options;
}
$.fn.extend({
tile: function(action, ...args){
var result;
this.each(function(){
var element = $(this);
if(element.attr('data-role') !== 'tile'){
throw new Error('This element isn\'t a tile element');
}
var tileObj = element.data('tile');
if(action == 'init'){
if(tileObj){
throw new Error('Tile already inited.');
}
var options = args[0] || {};
options = $.extend({}, options, getElementOptions(element));
tileObj = new Tile(options, element);
element.data('tile', tileObj);
} else {
if(!tileObj){
throw new Error('Tile not inited.');
}
if(!tileObj[action]){
throw new Error('Method: ' + action + ' not exists.');
}
result = tileObj[action].apply(tileObj, ...args);
}
});
if(result == undefined){
return this;
} else {
return result;
}
}
});
function resizeGrid(){
$('.tiles-grid').each(function(){
var dom = $(this);
var width = dom.width();
var gridSize = width / 4 - GRID_GAP;
dom.css({
gridTemplateColumns: 'repeat(4, ' + gridSize + 'px)',
gridAutoRows: gridSize + 'px',
});
});
}
$('*[data-role="tile"]').tile('init');
$(window).resize(resizeGrid);
$(resizeGrid);
function onCollapseDivChange(mutationsList){
mutationsList.forEach((item) => {
if(item.type == 'attributes' && item.attributeName == 'class'){
$('*[data-role="tile"]').tile('resize');
resizeGrid();
}
});
}
if($('body').hasClass('skin-minerva')){
$('#mw-content-text .collapsible-block').each(function(){
var dom = $(this);
if(dom.find('*[data-role="tile"]').length > 0){ //存在tile监听这个dom
var observer = new MutationObserver(onCollapseDivChange);
observer.observe(dom[0], {
attributes: true,
});
}
});
}
})(jQuery);

@ -0,0 +1,26 @@
{
"name": "isekai-discover",
"version": "1.0.0",
"description": "My webpack project",
"scripts": {
"build": "webpack",
"start": "webpack-dev-server"
},
"devDependencies": {
"@babel/core": "^7.7.2",
"@babel/preset-env": "^7.7.1",
"babel-loader": "^8.0.6",
"babel-plugin-syntax-dynamic-import": "^6.18.0",
"css-loader": "^3.2.0",
"html-webpack-plugin": "^3.2.0",
"less": "^3.9.0",
"less-loader": "^5.0.0",
"style-loader": "^1.0.0",
"webpack": "^4.41.2",
"webpack-cli": "^3.3.10",
"webpack-dev-server": "^3.9.0"
},
"dependencies": {
"scss-loader": "0.0.1"
}
}

@ -0,0 +1,108 @@
class CreatePagePanel {
constructor(dom) {
this.baseDom = dom;
this.pageUrl = null;
this.api = new mw.Api();
this.hasError = false;
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 title = this.pageNameInput.getValue();
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());
}
}
onPageNameChange() {
if (this.hasError) {
this.clearError();
}
let value = this.pageNameInput.getValue();
if (value.indexOf('') !== -1 || value.indexOf('`') !== -1) {
let range = this.pageNameInput.getRange();
value = value.replace(//g, ':').replace(/`/g, '·');
this.pageNameInput.setValue(value);
this.pageNameInput.selectRange(range.from, range.to);
}
}
setError(msg) {
this.formGroup.setErrors([msg]); //提示页面已经存在
this.hasError = true;
}
clearError() {
this.formGroup.setErrors([]);
this.hasError = false;
}
pageExists(title) {
return new Promise((resolve, reject) => {
this.api.get({
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) {
this.title.text(title);
}
}
if (!global.isekai) {
global.isekai = {};
}
global.isekai.CreatePagePanel = CreatePagePanel;

@ -0,0 +1,145 @@
class Discover {
constructor(dom){
this.baseDom = dom;
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: false,
});
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(){
if(this.pageUrl){ //页面存在就跳转
window.open(this.pageUrl);
}
}
refreshPage(){
this.pageUrl = null;
this.clearContent();
this.showLoading();
this.getRandomPage().then((title) => {
this.loadPage(title);
});
}
setTitle(title){
this.title.text(title);
}
showLoading(){
this.loading.show();
this.contentContainer.hide();
}
hideLoading(){
this.loading.hide();
this.contentContainer.show();
}
clearContent(){
this.contentContainer.children().remove();
}
setContent(dom){
this.hideLoading();
this.clearContent();
this.contentContainer.append(dom);
}
showError(msg){
let errorMsg = new OO.ui.MessageWidget( {
type: 'error',
label: msg,
});
this.setContent(errorMsg.$element);
}
getRandomPage(){
return new Promise((resolve, reject) => {
this.api.get({
action: 'query',
list: 'random',
rnlimit: 1,
rnnamespace: 0,
}).done((data) => {
if(data.query && data.query.random && data.query.random.length > 0){
let title = data.query.random[0].title;
this.setTitle(title);
resolve(title);
} else if(data.error){
this.showError(data.error.info);
} else {
this.showError(mw.message('isekai-discover-error-cannotload').parse());
}
});
});
}
parseHTMLString(txt) {
try {
let parser = new DOMParser();
let xmlDoc = parser.parseFromString(txt, "text/html");
return xmlDoc;
} catch(e) {
console.error(e.message);
}
return null;
}
loadPage(title){
let url = mw.util.getUrl(title);
this.pageUrl = url;
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();
this.setContent(content);
}
}, 'html');
}
}
if(!global.isekai){
global.isekai = {};
}
global.isekai.Discover = Discover;

@ -0,0 +1,63 @@
@playIconLight: data-uri('image/svg+xml;charset=UTF-8', 'source/images/media/light/play.svg');
@loopIconLight: data-uri('image/svg+xml;charset=UTF-8', 'source/images/media/light/loop.svg');
@stopIconLight: data-uri('image/svg+xml;charset=UTF-8', 'source/images/media/light/stop.svg');
@pauseIconLight: data-uri('image/svg+xml;charset=UTF-8', 'source/images/media/light/pause.svg');
@muteIconLight: data-uri('image/svg+xml;charset=UTF-8', 'source/images/media/light/volume-mute.svg');
@volumeLowIconLight: data-uri('image/svg+xml;charset=UTF-8', 'source/images/media/light/volume-low.svg');
@volumeMediumIconLight: data-uri('image/svg+xml;charset=UTF-8', 'source/images/media/light/volume-medium.svg');
@volumeHighIconLight: data-uri('image/svg+xml;charset=UTF-8', 'source/images/media/light/volume-high.svg');
@enlargeIconLight: data-uri('image/svg+xml;charset=UTF-8', 'source/images/media/light/enlarge.svg');
@shrinkIconLight: data-uri('image/svg+xml;charset=UTF-8', 'source/images/media/light/shrink.svg');
@playlistIconLight: data-uri('image/svg+xml;charset=UTF-8', 'source/images/media/light/list.svg');
@nextIconLight: data-uri('image/svg+xml;charset=UTF-8', 'source/images/media/light/next.svg');
@prevIconLight: data-uri('image/svg+xml;charset=UTF-8', 'source/images/media/light/prev.svg');
@firstIconLight: data-uri('image/svg+xml;charset=UTF-8', 'source/images/media/light/first.svg');
@lastIconLight: data-uri('image/svg+xml;charset=UTF-8', 'source/images/media/light/last.svg');
@forwardIconLight: data-uri('image/svg+xml;charset=UTF-8', 'source/images/media/light/forward.svg');
@backwardIconLight: data-uri('image/svg+xml;charset=UTF-8', 'source/images/media/light/backward.svg');
@shareIconLight: data-uri('image/svg+xml;charset=UTF-8', 'source/images/media/light/share.svg');
@equalizerIconLight: data-uri('image/svg+xml;charset=UTF-8', 'source/images/media/light/equalizer.svg');
@ejectIconLight: data-uri('image/svg+xml;charset=UTF-8', 'source/images/media/light/eject.svg');
@shuffleIconLight: data-uri('image/svg+xml;charset=UTF-8', 'source/images/media/light/shuffle.svg');
@randomIconLight: data-uri('image/svg+xml;charset=UTF-8', 'source/images/media/light/dice.svg');
@playIconDark: data-uri('image/svg+xml;charset=UTF-8', 'source/images/media/dark/play.svg');
@loopIconDark: data-uri('image/svg+xml;charset=UTF-8', 'source/images/media/dark/loop.svg');
@stopIconDark: data-uri('image/svg+xml;charset=UTF-8', 'source/images/media/dark/stop.svg');
@pauseIconDark: data-uri('image/svg+xml;charset=UTF-8', 'source/images/media/dark/pause.svg');
@muteIconDark: data-uri('image/svg+xml;charset=UTF-8', 'source/images/media/dark/volume-mute.svg');
@volumeLowIconDark: data-uri('image/svg+xml;charset=UTF-8', 'source/images/media/dark/volume-low.svg');
@volumeMediumIconDark: data-uri('image/svg+xml;charset=UTF-8', 'source/images/media/dark/volume-medium.svg');
@volumeHighIconDark: data-uri('image/svg+xml;charset=UTF-8', 'source/images/media/dark/volume-high.svg');
@enlargeIconDark: data-uri('image/svg+xml;charset=UTF-8', 'source/images/media/dark/enlarge.svg');
@shrinkIconDark: data-uri('image/svg+xml;charset=UTF-8', 'source/images/media/dark/shrink.svg');
@playlistIconDark: data-uri('image/svg+xml;charset=UTF-8', 'source/images/media/dark/list.svg');
@nextIconDark: data-uri('image/svg+xml;charset=UTF-8', 'source/images/media/dark/next.svg');
@prevIconDark: data-uri('image/svg+xml;charset=UTF-8', 'source/images/media/dark/prev.svg');
@firstIconDark: data-uri('image/svg+xml;charset=UTF-8', 'source/images/media/dark/first.svg');
@lastIconDark: data-uri('image/svg+xml;charset=UTF-8', 'source/images/media/dark/last.svg');
@forwardIconDark: data-uri('image/svg+xml;charset=UTF-8', 'source/images/media/dark/forward.svg');
@backwardIconDark: data-uri('image/svg+xml;charset=UTF-8', 'source/images/media/dark/backward.svg');
@shareIconDark: data-uri('image/svg+xml;charset=UTF-8', 'source/images/media/dark/share.svg');
@equalizerIconDark: data-uri('image/svg+xml;charset=UTF-8', 'source/images/media/dark/equalizer.svg');
@ejectIconDark: data-uri('image/svg+xml;charset=UTF-8', 'source/images/media/dark/eject.svg');
@shuffleIconDark: data-uri('image/svg+xml;charset=UTF-8', 'source/images/media/dark/shuffle.svg');
@randomIconDark: data-uri('image/svg+xml;charset=UTF-8', 'source/images/media/dark/dice.svg');
@checkIcon: data-uri('image/svg+xml;charset=UTF-8', 'source/images/apps/checkmark.svg');
@crossIcon: data-uri('image/svg+xml;charset=UTF-8', 'source/images/apps/cross.svg');
@searchIcon: data-uri('image/svg+xml;charset=UTF-8', 'source/images/apps/search.svg');
@eyeIcon: data-uri('image/svg+xml;charset=UTF-8', 'source/images/apps/eye.svg');
@plusIcon: data-uri('image/svg+xml;charset=UTF-8', 'source/images/apps/plus.svg');
@minusIcon: data-uri('image/svg+xml;charset=UTF-8', 'source/images/apps/minus.svg');
@helpIcon: data-uri('image/svg+xml;charset=UTF-8', 'source/images/apps/help.svg');
@leftArrowIcon: data-uri('image/svg+xml;charset=UTF-8', 'source/images/apps/arrow-left.svg');
@rightArrowIcon: data-uri('image/svg+xml;charset=UTF-8', 'source/images/apps/arrow-right.svg');
@calendarIcon: data-uri('image/svg+xml;charset=UTF-8', 'source/images/apps/calendar.svg');
@clockIcon: data-uri('image/svg+xml;charset=UTF-8', 'source/images/apps/clock.svg');
@menuIcon: data-uri('image/svg+xml;charset=UTF-8', 'source/images/apps/menu.svg');
@uploadIcon: data-uri('image/svg+xml;charset=UTF-8', 'source/images/apps/upload.svg');
@pencilIcon: data-uri('image/svg+xml;charset=UTF-8', 'source/images/apps/pencil.svg');
@chevronLeftIcon: data-uri('image/svg+xml;charset=UTF-8', 'source/images/apps/chevron-left.svg');
@chevronRightIcon: data-uri('image/svg+xml;charset=UTF-8', 'source/images/apps/chevron-right.svg');

@ -0,0 +1,538 @@
@import (once) "vars";
.show-element() {
//display: initial;
opacity: 1;
.scale(1);
}
.hide-element() {
.scale(0);
opacity: 0;
//display: none;
}
.debug() {
outline: 1px dotted red!important;
min-width: 1px;
min-height: 1px;
}
.clear() {
&::after {
display: block;
clear: both;
content: "";
}
}
.set-relative() {
display: block;
position: relative;
}
.set-absolute() {
position: absolute;
}
.set-flex() {
display: flex;
}
.reset-list() {
list-style: none inside;
margin: 0;
padding: 0;
position: relative;
}
.px2rem(@attr: width; @size: 16) {
.get-values(length(@size));
.get-values(@s, @i: 1) when (@i =< length(@size)) {
@current_value: extract(@size, @i);
& when not(@current_value = 0) {
@{attr}+_: unit( @current_value / 16, rem );
}
& when (@current_value = 0) {
@{attr}+_: 0;
}
.get-values(@s, @i + 1);
}
}
.rem2px(@attr: width; @size: 16) {
.get-values(length(@size));
.get-values(@s, @i: 1) when (@i =< length(@size)) {
@current_value: extract(@size, @i);
& when not(@current_value = 0) {
@{attr}+_: unit( 16 * @current_value, px );
}
& when (@current_value = 0) {
@{attr}+_: 0;
}
.get-values(@s, @i + 1);
}
}
.pt2px(@attr: width; @size: 16) {
.get-values(length(@size));
.get-values(@s, @i: 1) when (@i =< length(@size)) {
@current_value: extract(@size, @i);
& when not(@current_value = 0) {
@{attr}+_: unit( round(@current_value * 1.333333) , px );
}
& when (@current_value = 0) {
@{attr}+_: 0;
}
.get-values(@s, @i + 1);
}
}
.px2pt(@attr: width; @size: 16) {
.get-values(length(@size));
.get-values(@s, @i: 1) when (@i =< length(@size)) {
@current_value: extract(@size, @i);
& when not(@current_value = 0) {
@{attr}+_: unit( round(.75 * @current_value), pt );
}
& when (@current_value = 0) {
@{attr}+_: 0;
}
.get-values(@s, @i + 1);
}
}
.pt2rem(@attr: width; @size: 16){
.get-values(length(@size));
.get-values(@s, @i: 1) when (@i =< length(@size)) {
@current_value: extract(@size, @i);
& when not(@current_value = 0) {
@{attr}+_: unit( round(@current_value * 1.333333 / 16), rem );
}
& when (@current_value = 0) {
@{attr}+_: 0;
}
.get-values(@s, @i + 1);
}
}
.rem2pt(@attr: width; @size: 16){
.get-values(length(@size));
.get-values(@s, @i: 1) when (@i =< length(@size)) {
@current_value: extract(@size, @i);
& when not(@current_value = 0) {
@{attr}+_: unit( round(.75 * 16 * @current_value), pt );
}
& when (@current_value = 0) {
@{attr}+_: 0;
}
.get-values(@s, @i + 1);
}
}
.square(@size: 0, @unit) {
width: unit(@size, @unit);
height: unit(@size, @unit);
}
.circle(@size: 0, @unit) {
width: unit(@size, @unit);
height: unit(@size, @unit);
border-radius: 50%;
}
.halo() {
&::after {
display: block;
content: "";
position: absolute;
.circle(3.125, rem);
background-color: rgba(187, 187, 187, 0.5);
opacity: .3;
top: 50%;
left: 50%;
.px2rem(margin-top, -25px);
.px2rem(margin-left, -25px);
}
}
.animate(@params){
animation: @params;
}
.transition-scheme(@t) {
transition: @t;
}
.collapse() {
overflow: hidden;
max-height: 0;
transition: @transition-collapse;
position: relative;
}
.expand() {
max-height: 1000px !important;
transition: @transition-collapse !important;
transition-duration: 1s !important;
overflow: visible!important;
}
.perspective(@perspective) {
transform+_: perspective(@perspective);
}
.rotate(@degrees) {
transform+_: rotate(@degrees);
}
.rotateX(@degrees) {
transform+_: rotateX(@degrees);
}
.rotateY(@degrees) {
transform+_: rotateY(@degrees);
}
.rotateZ(@degrees) {
transform+_: rotateZ(@degrees);
}
.scale(@ratio) {
transform+_: scale(@ratio);
}
.scaleX(@ratio) {
transform+_: scaleX(@ratio);
}
.scaleY(@ratio) {
transform+_: scaleY(@ratio);
}
.translate(@x: 0, @y: 0) {
transform+_: translate(@x, @y);
}
.skew(@x: 0, @y: 0) {
transform+_: skew(@x, @y);
}
.skewX(@x: 0) {
transform+_: skewX(@x);
}
.skewY(@y: 0) {
transform+_: skewY(@y);
}
.translate3d(@x: 0, @y: 0, @z: 0) {
transform+_: translate3d(@x, @y, @z);
}
.transformOrigin(@origin) {
transform-origin: @origin;
}
.transition(@time: 1s, @func: ease, @target: all){
transition: @target @time @func;
}
.translateX(@x: 0) {
transform+_: translateX(@x);
}
.translateY(@y: 0) {
transform+_: translateY(@y);
}
.shadow(@x, @y, @blur, @stretch, @color, @alpha: .4){
box-shadow+: @x @y @blur @stretch rgba(red(@color), green(@color), blue(@color), @alpha);
}
.default-shadow() {
//.shadow(2px, 2px, 5px, 0, @black);
box-shadow: 2px 2px 2px 0 rgba(red(@ribbonDropdownShadow), green(@ribbonDropdownShadow), blue(@ribbonDropdownShadow), .7),
-.5px 0 1px 0 rgba(red(@ribbonDropdownShadow), green(@ribbonDropdownShadow), blue(@ribbonDropdownShadow), .7);
}
.win-shadow(){
box-shadow+: 0 0 5px 0 rgba(0, 0, 0, 0.3);
}
.shadow(@size) when (@size = 0) {
box-shadow: none;
}
.shadow(@size) when (@size = 1) {
box-shadow+: 0 2px 10px 0 rgba(0, 0, 0, 0.16), 0 2px 5px 0 rgba(0, 0, 0, 0.26);
}
.shadow(@size) when (@size = 2) {
box-shadow+: 0 6px 20px 0 rgba(0, 0, 0, 0.19), 0 8px 17px 0 rgba(0, 0, 0, 0.2);
}
.shadow(@size) when (@size = 3) {
box-shadow+: 0 17px 50px 0 rgba(0, 0, 0, 0.19), 0 12px 15px 0 rgba(0, 0, 0, 0.24);
}
.shadow(@size) when (@size = 4) {
box-shadow+: 0 25px 55px 0 rgba(0, 0, 0, 0.21), 0 16px 28px 0 rgba(0, 0, 0, 0.22);
}
.shadow(@size) when (@size = 5) {
box-shadow+: 0 40px 77px 0 rgba(0, 0, 0, 0.22), 0 27px 24px 0 rgba(0, 0, 0, 0.2);
}
.shadow-right() {
box-shadow+: 5px 0 7px -6px rgba(0,0,0,0.75);
}
.shadow-left() {
box-shadow+: -5px 0 7px -6px rgba(0,0,0,0.75);
}
.text-ellipsis() {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.focus-show(@color){
box-shadow+: 0 0 0 3px rgba(red(@color), green(@color), blue(@color), 0.45);
}
.neb(@size: 1rem, @shift: .625rem) {
&::before {
display: block;
position: absolute;
content: "";
width: @size;
height: @size;
background-color: inherit;
border: 1px solid transparent;
border-right-color: inherit;
border-bottom-color: inherit;
}
&.neb-s {
&::before {
top: 100%;
left: 50%;
.translateX(-50%);
.translateY(-50%);
.rotate(45deg);
}
}
&.neb-sw {
&::before {
top: 100%;
left: @shift;
.translateY(-50%);
.rotate(45deg);
}
}
&.neb-se {
&::before {
top: 100%;
right: @shift;
.translateY(-50%);
.rotate(45deg);
}
}
&.neb-n {
&::before {
top: 0;
left: 50%;
.translateX(-50%);
.translateY(-50%);
.rotate(-135deg);
}
}
&.neb-nw {
&::before {
top: 0;
left: @shift;
.translateY(-50%);
.rotate(-135deg);
}
}
&.neb-ne {
&::before {
top: 0;
right: @shift;
.translateY(-50%);
.rotate(-135deg);
}
}
&.neb-en {
&::before {
top: @shift;
right: 0;
.translateX(50%);
.rotate(-45deg);
}
}
&.neb-e {
&::before {
top: 50%;
right: 0;
.translateX(50%);
.translateY(-50%);
.rotate(-45deg);
}
}
&.neb-es {
&::before {
bottom: @shift;
right: 0;
.translateX(50%);
.rotate(-45deg);
}
}
&.neb-wn {
&::before {
top: @shift;
left: 0;
.translateX(-50%);
.rotate(135deg);
}
}
&.neb-w {
&::before {
top: 50%;
left: 0;
.translateX(-50%);
.translateY(-50%);
.rotate(135deg);
}
}
&.neb-ws {
&::before {
bottom: @shift;
left: 0;
.translateX(-50%);
.rotate(135deg);
}
}
}
.neb2(@size: 1rem; @shift: .625rem; @color: @white){
&::before {
display: block;
content: "";
width: 0;
height: 0;
border-style: solid;
position: absolute;
}
&.neb-s {
&::before {
border-width: @size @size 0 @size;
border-color: @color transparent transparent transparent;
top: 100%;
left: 50%;
.translateX(-50%);
.translateY(-50%);
}
}
&.neb-n {
&::before {
border-width: 0 @size @size @size;
border-color: transparent transparent @color transparent;
top: 0;
left: 50%;
.translateX(-50%);
.translateY(-50%);
}
}
&.neb-e {
&::before {
border-width: @size 0 @size @size;
border-color: transparent transparent transparent @color;
top: 50%;
right: 0;
.translateX(50%);
.translateY(-50%);
}
}
&.neb-w {
&::before {
border-width: @size @size @size 0;
border-color: transparent @color transparent transparent;
top: 50%;
left: 0;
.translateX(-50%);
.translateY(-50%);
}
}
}
.toggle() {
position: relative;
cursor: pointer;
padding-right: 1.5rem!important;
user-select: none;
&::before {
display: block;
position: absolute;
vertical-align: middle;
color: transparent;
font-size: 0;
content: "";
.px2rem(height, 5px);
.px2rem(width, 5px);
background-color: @transparent ;
border-left: 1px solid;
border-bottom: 1px solid;
border-color: @dark;
top: 50%;
left: 100%;
margin-left: -1rem;
margin-top: -.1625rem;
z-index: 2;
transform: rotate(-45deg);
transition: @transition-short;
transform-origin: center center 1px;
}
}
.hideElement(@el){
@{el} {
width: 1px;
height: 1px;
position: absolute;
top: 0;
left: 0;
opacity: 0;
}
}
.hideScrollBars() {
&::-webkit-scrollbar {
display: none!important;
}
-ms-overflow-style: -ms-autohiding-scrollbar;
overflow: -moz-scrollbars-none;
}

@ -0,0 +1,314 @@
@unitSize: 4px;
// Fonts
@fontName: -apple-system, system-ui, BlinkMacSystemFont,
"Segoe UI", "Roboto", "Ubuntu",
"Helvetica Neue", sans-serif;
@fontSize: @unitSize * 4;
// Colors
@lightenValue: 15%;
@darkenValue: 15%;
@transparent: transparent;
@brandColor1: #2ac4f4;
@brandColor2: #004d6f;
@black: #000000;
@white: #ffffff;
@dark: #1d1d1d;
@light: #f8f8f8;
@gray: #bebebe;
@grayBlue: #607d8b;
@grayWhite: #f5f5f5;
@grayMouse: #455a64;
@lime: #a4c400;
@green: #60a917;
@emerald: #008a00;
@blue: #00AFF0;
@teal: #00aba9;
@cyan: #1ba1e2;
@cobalt: #0050ef;
@indigo: #6a00ff;
@violet: #aa00ff;
@pink: #dc4fad;
@magenta: #d80073;
@crimson: #a20025;
@red: #CE352C;
@orange: #fa6800;
@amber: #f0a30a;
@yellow: #fff000;
@brown: #825a2c;
@olive: #6d8764;
@steel: #647687;
@mauve: #76608a;
@taupe: #87794e;
@lightLime: lighten(@lime, @lightenValue);
@lightGreen: lighten(@green, @lightenValue);
@lightEmerald: lighten(@emerald, @lightenValue);
@lightBlue: lighten(@blue, @lightenValue);
@lightTeal: lighten(@teal, @lightenValue);
@lightCyan: lighten(@cyan, @lightenValue);
@lightCobalt: lighten(@cobalt, @lightenValue);
@lightIndigo: lighten(@indigo, @lightenValue);
@lightViolet: lighten(@violet, @lightenValue);
@lightPink: lighten(@pink, @lightenValue);
@lightMagenta: lighten(@magenta, @lightenValue);
@lightCrimson: lighten(@crimson, @lightenValue);
@lightRed: lighten(@red, @lightenValue);
@lightOrange: lighten(@orange, @lightenValue);
@lightAmber: lighten(@amber, @lightenValue);
@lightYellow: lighten(@yellow, @lightenValue);
@lightBrown: lighten(@brown, @lightenValue);
@lightOlive: lighten(@olive, @lightenValue);
@lightSteel: lighten(@steel, @lightenValue);
@lightMauve: lighten(@mauve, @lightenValue);
@lightTaupe: lighten(@taupe, @lightenValue);
@lightGray: lighten(@gray, @lightenValue);
@lightGrayBlue: lighten(@grayBlue, @lightenValue);
@darkLime: darken(@lime, @darkenValue);
@darkGreen: darken(@green, @darkenValue);
@darkEmerald: darken(@emerald, @darkenValue);
@darkBlue: darken(@blue, @darkenValue);
@darkTeal: darken(@teal, @darkenValue);
@darkCyan: darken(@cyan, @darkenValue);
@darkCobalt: darken(@cobalt, @darkenValue);
@darkIndigo: darken(@indigo, @darkenValue);
@darkViolet: darken(@violet, @darkenValue);
@darkPink: darken(@pink, @darkenValue);
@darkMagenta: darken(@magenta, @darkenValue);
@darkCrimson: darken(@crimson, @darkenValue);
@darkRed: darken(@red, @darkenValue);
@darkOrange: darken(@orange, @darkenValue);
@darkAmber: darken(@amber, @darkenValue);
@darkYellow: darken(@yellow, @darkenValue);
@darkBrown: darken(@brown, @darkenValue);
@darkOlive: darken(@olive, @darkenValue);
@darkSteel: darken(@steel, @darkenValue);
@darkMauve: darken(@mauve, @darkenValue);
@darkTaupe: darken(@taupe, @darkenValue);
@darkGray: darken(@gray, @darkenValue);
@darkGrayBlue: darken(@grayBlue, @darkenValue);
@colorList: black, white, dark, light, grayBlue, grayWhite, grayMouse, brandColor1, brandColor2,
lime, green, emerald, blue, teal, cyan, cobalt, indigo, violet, pink, magenta, crimson, red, orange, amber, yellow, brown, olive, steel, mauve, taupe, gray,
lightLime, lightGreen, lightEmerald, lightBlue, lightTeal, lightCyan, lightCobalt, lightIndigo, lightViolet, lightPink, lightMagenta, lightCrimson, lightRed, lightOrange, lightAmber, lightYellow, lightBrown, lightOlive, lightSteel, lightMauve, lightTaupe, lightGray, lightGrayBlue,
darkLime, darkGreen, darkEmerald, darkBlue, darkTeal, darkCyan, darkCobalt, darkIndigo, darkViolet, darkPink, darkMagenta, darkCrimson, darkRed, darkOrange, darkAmber, darkYellow, darkBrown, darkOlive, darkSteel, darkMauve, darkTaupe, darkGray, darkGrayBlue;
@colorListLength: length(@colorList);
// Body
@bodyColor: lighten(@black, 13%);
// Hover
@hoverBackground: rgba(red(@dark), green(@dark), blue(@dark), .1);
@hoverBackground2: rgba(red(@dark), green(@dark), blue(@dark), .5);
@hoverBackgroundLight3: rgba(red(@white), green(@white), blue(@white), .3);
@hoverBackgroundLight2: rgba(red(@white), green(@white), blue(@white), .2);
@hoverBackgroundLight1: rgba(red(@white), green(@white), blue(@white), .1);
@hoverBackgroundLight: rgba(red(@white), green(@white), blue(@white), .01);
// Appbar
@appBarBackground: @brandColor2;
@appBarBackgroundActive: lighten(@brandColor2, 10%);
@appBarColor: @white;
// Taskbar
@taskBarBackground: #053046;
@taskBarItemHover: rgba(red(@white), green(@white), blue(@white), .1);
@taskBarItemActive: rgba(red(@white), green(@white), blue(@white), .3);
// Form and Inputs
@inputBorder: #d9d9d9;
@checkBackground: darken(@inputBorder, 10%);
// Disabled
@disabledBackground: #e9e9e9;
@disabledBorder: #e9e9e9;
@disabledColor: lighten(@dark, 50%);
// Borders
@borderRadius: .25rem;
@borderColor: darken(@light, 10%);
// Links
@linkColor: #0366d6;
@linkColorHover: #0056b3;
// Accent colors
@primaryColor: #0366d6;
@secondaryColor: @grayBlue;
@successColor: @green;
@alertColor: @red;
@warningColor: @lightOrange;
@yellowColor: #ffe484;
@infoColor: @lightCyan;
@darkColor: lighten(@dark, 20%);
@lightColor: @light;
@brand1Color: @brandColor1;
@brand2Color: @brandColor2;
@accentColors: primary, secondary, success, alert, warning, yellow, info, dark, light;
@buttonPredefinedTypes: primary, secondary, success, alert, warning, yellow, info, dark, light, brand1, brand2;
@buttonPredefinedTypesLength: length(@buttonPredefinedTypes);
// Z-index
@zindex-selectedCheck: 100;
@zindex-absolute: 500;
@zindex-dropdown: 1000;
@zindex-sticky: 1020;
@zindex-fixed: 1030;
@zindex-modal-backdrop: 1040;
@zindex-modal: 1050;
@zindex-popover: 1060;
@zindex-tooltip: 1070;
@zindex-top: 1080;
@zindex-notify: 1085;
@zindex-charms: 1090;
@zindex-overlay: 2000;
@zindex-fullscreen: 2147483647;
// Percents breakpoints
@percentBreakpointsList: 25, 50, 75, 100;
@percentBreakpointsLength: length(@percentBreakpointsList);
// Tiles
@tileBaseSize: 25%;
@tileApp: 44px 44px;
@tileSmall: 70px 70px;
@tileMedium: 150px 150px;
@tileWide: 310px 150px;
@tileLarge: 310px 310px;
@tileMargin: 5px;
@tileCellSize: extract(@tileMedium, 1);
@tileOutlineColor: rgba(red(@dark), green(@dark), blue(@dark), .1);
@tileTransformPerspective: 500px;
@tileTransformRotate: 0.138372rad;
@tileSize: extract(@tileMedium, 1);
// Media breakpoints
@fs: 0;
@xs: 360px;
@sm: 576px;
@ld: 640px;
@md: 768px;
@lg: 992px;
@xl: 1200px;
@xxl: 1452px;
@mediaBreakpointListMobile: fs, sm, md, lg, xl, xxl;
@mediaBreakpointListMobile2: sm, md, lg, xl, xxl;
@mediaBreakpointListMobile3: xs, sm, ld, md, lg, xl, xxl;
@mediaBreakpointListDesktop: xxl, xl, lg, md, sm, fs;
@mediaBreakpointListDesktop2: xxl, xl, lg, md, sm;
@mediaBreakpointListDesktop3: xxl, xl, lg, md, ld, sm, xs;
@mediaBreakpointListMobileLength: length(@mediaBreakpointListMobile);
@mediaBreakpointListMobile2Length: length(@mediaBreakpointListMobile2);
@mediaBreakpointListMobile3Length: length(@mediaBreakpointListMobile3);
@mediaBreakpointListDesktopLength: length(@mediaBreakpointListDesktop);
@mediaBreakpointListDesktop2Length: length(@mediaBreakpointListDesktop2);
@mediaBreakpointListDesktop3Length: length(@mediaBreakpointListDesktop3);
@percents: 25, 33, 50, 75, 100;
@percentsLength: length(@percents);
// Transition
@transition-speed: .3s;
@transition-short: all .15s ease-in-out;
@transition-base: all .3s ease-in-out;
@transition-long: all 1s ease-in-out;
@transition-margin: margin .3s ease-in-out;
@transition-fade: opacity .15s linear;
@transition-color: color .3s linear;
@transition-collapse: max-height .3s ease;
@transition-width: width .3s ease;
@transition-left: left .3s ease;
@transition-right: right .3s ease;
@transition-top: top .3s ease;
@transition-bottom: bottom .3s ease;
@transition-transform: transform .3s ease;
// Grid
@gridColumns12: 12;
@gridGapSize: 12px;
@gridCellBaseSize: 8.333335%;
// Windows
@winBorderSize: .5rem;
@winBorderColor: #6badf6;
@winBorderColorInactive: #ebebeb;
@winDialogContentBackground: #ededed;
@winFlatBackgroundColor: #ffffff;
@winFlatBorderColor: #e9e9e9;
@winFlatSystemButtonHoverBackground: #cde6f7;
@winFlatSystemButtonActiveBackground: #92c0e0;
@winFlatSystemButtonActiveColor: #2a8dd4;
@winFlatSystemButtonRestColor: #777777;
@winCloseButtonColor: #c75050;
@winCloseButtonActiveColor: #e04343;
@winCloseButtonInActiveColor: #bcbcbc;
@winCaptionBackground: #3c6478;
@winCaptionColor: @white;
@streamerItemWidth: 224px;
@streamerTimelineImage: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAOAAAAATCAYAAACJKwFWAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA3ZpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTM4IDc5LjE1OTgyNCwgMjAxNi8wOS8xNC0wMTowOTowMSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDo2OWY4NzBhNi0zODU3LWFmNDEtYWMzZS03YzlkOTcxZjMxOTIiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NEREMzg4NkJBQjkyMTFFN0JDQTVFMzg4RUE0RDc4RkQiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NEREMzg4NkFBQjkyMTFFN0JDQTVFMzg4RUE0RDc4RkQiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTcgKFdpbmRvd3MpIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6YzEyZGQ1NjktNmM3YS0yZTQ2LTg2MmQtZWY3OGU5MmQ4NWY2IiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjY5Zjg3MGE2LTM4NTctYWY0MS1hYzNlLTdjOWQ5NzFmMzE5MiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Pv3rUTMAAAIHSURBVHja7Jq/S0JRHMWfpj37oSA8qikIImioIaghaHDrD2hqaG4R6i8paGksh2iIQGhoCYewocChhkDEoAjsx5IGDZV2Ll6huXvoKZwPHHwuh3O/737f03tvpNVqeUKIcIiYBiwUCoe4LhH8FqAadO/oE0BT0AUh0xxUhyqOPklohpRpFvqEbh194tA8dGX9XJi2fteE8S1CN1DD0WcSSpHmpslUhl4dfcahMeiSMTdj9qKYyWR2/uKA5v39dd1OUNebOAKtQtuEQa5Bd9C5o4+pVRbaImRagd6hU4LXJinTMjQMHZEymfn05eizBE1AOUKmDegAeiY8PE0z7xIyZaP2op/0Rk1AaYKPeQP6pEyD9inqyigx05B9ozLG5ttPV5I2FwPf1suVFGlsnUwBwSdt5zmD/qh+hQsRHmpAIdSAQqgBhRBqQCHUgEKIfyBG9jP7SD4pV5KYibFs3EfMZJbWu+0I0oDH24ZI2nq5krD3j5UpTvDxiZnoDWg2Ot8IPmbjfI+UqQo9EXw+vPZJCgYn0HeXNeCjx9vfKtt6uVIjPqhMpjrBx5ykqXRrA1ZJPg3P/RhTh2OSzwu0T/J66MJfQ2dEL1adisRMOZJPyeMcjdN/QCHCRg0ohBpQCDWgECKkBgxUip4k4rVXLiMqRU8SdBowr1r0JE2vvbTeVCl6kvyPAAMASGlSBhr76A8AAAAASUVORK5CYII=";
@activityRingTime: 4000ms;
@activityRingSize: 32px;
@activityColor: @white;
@activityColorDark: @darkGray;
@activityRingRotate: -14deg;
@activityRingTimeMute: 30;
@hintBackground: rgba(255, 252, 192, 1);
@hintColor: @dark;
@mpStep: 4;
@mpUnit: px;
@playerInactiveColor: #555555;
@playerActiveColor: @green;
@playerHoverColor: @white;
@playerControlsBackground: rgba(34, 34, 34, 0.5);
@ribbonMenuStaticBackground: #1979ca;
@ribbonMenuBackground: #ffffff;
@ribbonMenuActiveBackground: #f5f6f7;
@ribbonMenuBorder: #dadbdc;
@ribbonMenuItemBorder: #a4cef9;
@ribbonMenuItemActiveBorder: #1979ca;
@ribbonMenuItemHoverBackground: rgba(red(#a4cef9), green(#a4cef9), blue(#a4cef9), .2);
@ribbonMenuItemActiveBackground: rgba(red(#a4cef9), green(#a4cef9), blue(#a4cef9), .8);
@ribbonDropdownBackground: #fbfcfd;
@ribbonDropdownDivider: #dcddde;
@ribbonDropdownShadow: #e3e4e5;
@inputHeight: 36px;
@input-lx: 50px;
@input-sx: 28px;
@badgeFontSize: 12px;
@johnDoe: "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD//gA7Q1JFQVRPUjogZ2QtanBlZyB2MS4wICh1c2luZyBJSkcgSlBFRyB2NjIpLCBxdWFsaXR5ID0gOTAK/9sAQwADAgIDAgIDAwMDBAMDBAUIBQUEBAUKBwcGCAwKDAwLCgsLDQ4SEA0OEQ4LCxAWEBETFBUVFQwPFxgWFBgSFBUU/9sAQwEDBAQFBAUJBQUJFA0LDRQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQU/8AAEQgAUABQAwEiAAIRAQMRAf/EAB8AAAEFAQEBAQEBAAAAAAAAAAABAgMEBQYHCAkKC//EALUQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5+v/EAB8BAAMBAQEBAQEBAQEAAAAAAAABAgMEBQYHCAkKC//EALURAAIBAgQEAwQHBQQEAAECdwABAgMRBAUhMQYSQVEHYXETIjKBCBRCkaGxwQkjM1LwFWJy0QoWJDThJfEXGBkaJicoKSo1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoKDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uLj5OXm5+jp6vLz9PX29/j5+v/aAAwDAQACEQMRAD8A+t+KKPxo/GgA70Yo/Gj8aADFH4VesdC1HUl3WtjcXCf344yV/PGKW+0HUtNXddWNzbp/fkjIX88YoAofhR+FH40fjQAfhR+FH40fjQAUUUUAFepeAPh5D9li1LVYhK8g3Q27j5VXszDuT6f5HA+FtOXVvEWn2rjMcko3j1UckfkDX0MBgYHAoARVCKFUBVHAA6ClZQwKkZBGCDS0UAec+Pvh3BJay6lpUQimjBeW3QYVx3Kjsfbv/PyqvpuvnvxfpqaT4l1C1QbY0lJUDsrfMB+RoAyKKKKACiiigDa8GXq6f4p02eQgIJQpJ7Bvlz+tfQP4V8yDg17P4A8cw65ZxWV5IE1KMbfmP+uA7j39R+NAHaUfhSUUAL+FeA+OL1NQ8WalNGQU83YCO+0Bf6V6b498cQ6BZyWlrIJNSkXaApz5QP8AEff0FeKk5OTyTQAUUUUAH40fjRU1naTX93DbQIXmlYIijuTQBc0Dw/eeI74W1mm49XkbhUHqTXsHhz4eaXoCpI8YvbscmaYZAP8Asr0H8/etHwv4cg8M6XHaxANIfmllxy7dz9PStigA/Gk/GlooA5bxJ8PdL19XkWMWd43PnwjGT/tL0P8AP3rx/X/D954cvjbXibT1SReVceoNfRFZHijw5B4m0uS1lAWQfNFLjlG7H6etAHz5+NH41NeWk1hdzW06FJonKMp7EGoaACvQfhBowudTudRkXK2y7I8j+Nup/Afzrz6vafhRaCDwmkgHM8zufwO3/wBloA7Kiij8KACkpaSgBaSj8KKAPJvi/owttTttRjXC3K7JMf3l6H8R/KvPq9p+K1qJ/CbyEcwTI4P1O3/2avFqAP/Z";
// animation
@defaultPerspective: 600px;
@defaultAnimationSpeed: .3s;
// additional; colors
@ribbedSize: 20px;
@ribbedAlpha: .15;
@ribbedAngle: -45deg;
@alpha: .1;

@ -0,0 +1,482 @@
/* Please use node.js "less" module to complie this less */
/* 请使用node.js的“less”模块来编译本less */
@import (once) "./include/vars";
@import (once) "./include/mixins";
.tile-small,
.tile-medium,
.tile-wide,
.tile-large,
.tile-app {
display: block;
background-color: @cyan;
color: @white;
width: extract(@tileMedium, 1);
height: extract(@tileMedium, 2);
box-shadow: inset 0 0 1px #FFFFCC;
cursor: pointer;
position: relative;
overflow: hidden;
user-select: none;
max-width: none!important;
}
.tile {
&-small {
width: extract(@tileSmall, 1);
height: extract(@tileSmall, 2);
}
&-medium {
width: extract(@tileMedium, 1);
height: extract(@tileMedium, 2);
}
&-wide {
width: extract(@tileWide, 1);
height: extract(@tileWide, 2);
}
&-large {
width: extract(@tileLarge, 1);
height: extract(@tileLarge, 2);
}
&-app {
width: extract(@tileApp, 1);
height: extract(@tileApp, 2);
}
}
.tile-small,
.tile-medium,
.tile-wide,
.tile-large,
.tile-app {
.icon {
max-width: 33%;
height: 33%;
position: absolute;
top: 50%;
left: 50%;
.translateY(-50%);
.translateX(-50%);
/*font-size: 50px;*/
/*line-height: 50px;*/
z-index: 2;
}
.branding-bar {
height: 32px;
line-height: 32px;
position: absolute;
left: 0;
bottom: 0;
right: 0;
padding: 0 10px 5px;
font-size: .875rem;
font-weight: 500;
.text-ellipsis();
z-index: 2;
}
.badge-top, .badge-bottom {
position: absolute;
display: block;
padding: 4px 8px;
font-size: 12px;
text-align: center;
background-color: @hoverBackground;
z-index: 2;
}
.badge-bottom {
right: 10px;
bottom: 0;
}
.badge-top {
top: 10px;
right: 10px;
}
&:hover {
outline: @tileOutlineColor solid 4px;
}
}
.tile {
&-small {
.icon {
max-width: 50%;
font-size: 35px;
line-height: 35px;
}
/*.branding-bar {
display: none;
}*/
}
&-large {
.icon {
font-size: 102px;
line-height: 102px;
}
}
&-app {
.icon {
max-width: 75%;
height: 75%;
}
}
}
.tile-small,
.tile-medium,
.tile-wide,
.tile-large,
.tile-app {
&.transform-right {
.transformOrigin(left 50%);
.perspective(@tileTransformPerspective)!important;
.rotateY(@tileTransformRotate)!important;
&.tile-small {
.perspective(@tileTransformPerspective)!important;
.rotateY(@tileTransformRotate * 2)!important;
}
&.tile-wide {
.perspective(@tileTransformPerspective)!important;
.rotateY(@tileTransformRotate / 2)!important;
}
&.tile-large {
.perspective(@tileTransformPerspective)!important;
.rotateY(@tileTransformRotate / 3)!important;
}
}
&.transform-left {
.transformOrigin(right 50%);
.perspective(@tileTransformPerspective)!important;
.rotateY(-@tileTransformRotate)!important;
&.tile-small {
.perspective(@tileTransformPerspective)!important;
.rotateY(-@tileTransformRotate * 2)!important;
}
&.tile-wide {
.perspective(@tileTransformPerspective)!important;
.rotateY(-@tileTransformRotate / 2)!important;
}
&.tile-large {
.perspective(@tileTransformPerspective)!important;
.rotateY(-@tileTransformRotate / 3)!important;
}
}
&.transform-top {
.transformOrigin(50% bottom);
.perspective(@tileTransformPerspective)!important;
.rotateX(@tileTransformRotate)!important;
&.tile-small {
.perspective(@tileTransformPerspective)!important;
.rotateX(@tileTransformRotate * 2)!important;
}
&.tile-wide {
.perspective(@tileTransformPerspective)!important;
.rotateX(@tileTransformRotate / 2)!important;
}
&.tile-large {
.perspective(@tileTransformPerspective)!important;
.rotateX(@tileTransformRotate / 3)!important;
}
}
&.transform-bottom {
.transformOrigin(50% top);
.perspective(@tileTransformPerspective)!important;
.rotateX(-@tileTransformRotate)!important;
&.tile-small {
.perspective(@tileTransformPerspective)!important;
.rotateX(-@tileTransformRotate * 2)!important;
}
&.tile-wide {
.perspective(@tileTransformPerspective)!important;
.rotateX(-@tileTransformRotate / 2)!important;
}
&.tile-large {
.perspective(@tileTransformPerspective)!important;
.rotateX(-@tileTransformRotate / 3)!important;
}
}
}
.tiles-grid {
position: relative;
display: grid;
grid-template-columns: repeat(auto-fit, (@tileBaseSize - 1%));
/*grid-template-rows: repeat(auto-fit, (@tileBaseSize - 1%));*/
grid-gap: 5px;
.tile-small {
height: 100%;
width: 100%;
grid-column: span 1;
grid-row: span 1;
}
.tile-medium {
height: 100%;
width: 100%;
grid-column: span 2;
grid-row: span 2;
}
.tile-wide {
height: 100%;
width: 100%;
grid-column: span 4;
grid-row: span 2;
}
.tile-large {
height: 100%;
width: 100%;
grid-column: span 4;
grid-row: span 4;
}
/*.tile-small::before,
.tile-medium::before,
.tile-large::before {
content: '';
padding-bottom: 100%;
display: block;
}
.tile-wide::before {
content: '';
padding-bottom: 50%;
display: block;
}*/
}
.tiles-grid {
.create-tiles-cells(@i: 1, @k: 1) when (@k <= @i) {
.tile-small.col-@{k} {
grid-column: @k / span 1;
}
.tile-medium.col-@{k} {
grid-column: @k / span 2;
}
.tile-wide.col-@{k} {
grid-column: @k / span 4;
}
.tile-large.col-@{k} {
grid-column: @k / span 4;
}
.tile-small.row-@{k} {
grid-row: @k / span 1;
}
.tile-medium.row-@{k} {
grid-row: @k / span 2;
}
.tile-wide.row-@{k} {
grid-row: @k / span 4;
}
.tile-large.row-@{k} {
grid-row: @k / span 4;
}
.create-tiles-cells(@i; @k + 1);
}
.create-tiles-cells(12);
}
.tiles-grid {
&.size-half {
width: 50%;
}
.create-tiles-grid-size(@i: 1, @k: 1) when (@k <= @i) {
&.size-@{k} {
width: (100% * @k / 12);
}
.create-tiles-grid-size(@i; @k + 1);
}
.create-tiles-grid-size(12);
}
.tiles-grid {
each(@mediaBreakpointListMobile, .(@m) {
@media screen and (min-width: @@m) {
each(range(12), .(@k) {
.col-@{m}-@{k} {
grid-column: @k;
}
.row-@{m}-@{k} {
grid-row: @k;
}
})
each(range(12), .(@k) {
&.size-@{m}-@{k} {
width: (100% * @k / 12);
}
})
}
})
}
.tiles-group {
width: 100%;
float: left;
overflow: visible;
&::before {
content: attr(data-group-title);
display: block;
position: absolute;
left: 0;
top: -36px;
height: 1.5em;
line-height: 1.5em;
z-index: 1;
color: inherit;
}
}
// Tiles effects
[class*=tile-] {
&.image-set {
.img {
width: 25%;
height: 50%;
display: block;
float: left;
border: 1px solid @dark;
background-size: cover;
&:nth-child(1) {
width: 50%;
height: 100%;
}
}
background-size: contain;
background-position: center;
}
.slide {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
display: block;
}
[class*=slide-] {
width: 100%;
height: 100%;
position: absolute;
transition: @transition-base;
}
.slide-front {
top: 0;
left: 0;
}
&.effect-hover-slide-up, &.effect-hover-zoom-up {
.slide-back {
top: 100%;
left: 0;
}
&:hover {
.slide-front {
.translateY(-100%);
}
.slide-back {
top: 0;
}
}
}
&.effect-hover-slide-down, &.effect-hover-zoom-down {
.slide-back {
top: 0;
left: 0;
.translateY(-100%);
}
&:hover {
.slide-front {
top: 100%;
}
.slide-back {
.translateY(0);
}
}
}
&.effect-hover-slide-left, &.effect-hover-zoom-left {
.slide-back {
top: 0;
left: 100%;
}
&:hover {
.slide-front {
.translateX(-100%);
}
.slide-back {
left: 0;
}
}
}
&.effect-hover-slide-right, &.effect-hover-zoom-right {
.slide-back {
top: 0;
left: 0;
.translateX(-100%);
}
&:hover {
.slide-front {
left: 100%;
}
.slide-back {
.translateX(0);
}
}
}
&.effect-hover-zoom-up, &.effect-hover-zoom-down, &.effect-hover-zoom-left, &.effect-hover-zoom-right {
&:hover {
.slide-front {
left: 0;
top: 0;
.scale(2);
}
}
}
}

@ -0,0 +1,97 @@
const path = require('path');
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');
/*
* We've enabled HtmlWebpackPlugin for you! This generates a html
* 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 = {
mode: 'production',
entry: {
'createPage': './src/createPage/ext.isekai.createPage.js',
'discover': './src/discover/ext.isekai.discover.js',
},
output: {
filename: '[name]/ext.isekai.[name].js',
path: path.resolve(__dirname, 'modules')
},
plugins: [new webpack.ProgressPlugin(), new HtmlWebpackPlugin()],
module: {
rules: [
{
test: /.(js|jsx)$/,
include: [path.resolve(__dirname, 'src')],
loader: 'babel-loader',
options: {
plugins: ['syntax-dynamic-import'],
presets: [
[
'@babel/preset-env',
{
modules: false
}
]
]
}
},
{
test: /.(scss)$/,
use: [{
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: {
open: true
}
};
Loading…
Cancel
Save