Merge branch 'master' of https://github.com/Isekai-Project/mediawiki-extension-IsekaiWidgets
commit
50fc3ce7a6
@ -1,17 +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": "サーバからのページを読み取りに失敗しました。"
|
||||
{
|
||||
"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": "サーバからのページを読み取りに失敗しました。"
|
||||
}
|
@ -1,39 +1,39 @@
|
||||
<?php
|
||||
namespace Isekai\Widgets;
|
||||
|
||||
use Html;
|
||||
|
||||
class ExtraFontWidget {
|
||||
public static function create($text, $params, $parser, $frame){
|
||||
$existsFonts = $parser->extIsekaiWidgetsCache->get('extraFonts', INF, []);
|
||||
|
||||
$content = $text = $parser->recursiveTagParse($text, $frame);
|
||||
if (!isset($params['name']) || empty($params['name'])) {
|
||||
return '<span class="error">' . wfMessage('isekai-font-error-invalid-params')->parse() . '</span>' . $content;
|
||||
}
|
||||
|
||||
$fontName = 'extra-' . $params['name'];
|
||||
if (preg_match('/[`~!@#$%^&*()+=<>?:"{}|,.\/;\'\\\\\[\]]\r\n/', $fontName)) {
|
||||
return '<span class="error">' .
|
||||
wfMessage('isekai-font-error-font-name-invalid')->parse() .
|
||||
'</span>' .
|
||||
$content;
|
||||
}
|
||||
|
||||
$existsFonts = $parser->extIsekaiWidgetsCache->get('extraFonts', INF, []);
|
||||
if (!isset($existsFonts[$fontName])) {
|
||||
return '<span class="error">' .
|
||||
wfMessage('isekai-font-error-font-not-imported', $params['name'])->parse() .
|
||||
'</span>' .
|
||||
$content;
|
||||
}
|
||||
$fontId = $existsFonts[$fontName];
|
||||
|
||||
return [
|
||||
Html::rawElement('span', [
|
||||
'class' => 'isekai-extra-font font-' . $fontId,
|
||||
], $content),
|
||||
"markerType" => 'nowiki'
|
||||
];
|
||||
}
|
||||
<?php
|
||||
namespace Isekai\Widgets;
|
||||
|
||||
use Html;
|
||||
|
||||
class ExtraFontWidget {
|
||||
public static function create($text, $params, $parser, $frame){
|
||||
$existsFonts = $parser->extIsekaiWidgetsCache->get('extraFonts', INF, []);
|
||||
|
||||
$content = $text = $parser->recursiveTagParse($text, $frame);
|
||||
if (!isset($params['name']) || empty($params['name'])) {
|
||||
return '<span class="error">' . wfMessage('isekai-font-error-invalid-params')->parse() . '</span>' . $content;
|
||||
}
|
||||
|
||||
$fontName = 'extra-' . $params['name'];
|
||||
if (preg_match('/[`~!@#$%^&*()+=<>?:"{}|,.\/;\'\\\\\[\]]\r\n/', $fontName)) {
|
||||
return '<span class="error">' .
|
||||
wfMessage('isekai-font-error-font-name-invalid')->parse() .
|
||||
'</span>' .
|
||||
$content;
|
||||
}
|
||||
|
||||
$existsFonts = $parser->extIsekaiWidgetsCache->get('extraFonts', INF, []);
|
||||
if (!isset($existsFonts[$fontName])) {
|
||||
return '<span class="error">' .
|
||||
wfMessage('isekai-font-error-font-not-imported', $params['name'])->parse() .
|
||||
'</span>' .
|
||||
$content;
|
||||
}
|
||||
$fontId = $existsFonts[$fontName];
|
||||
|
||||
return [
|
||||
Html::rawElement('span', [
|
||||
'class' => 'isekai-extra-font font-' . $fontId,
|
||||
], $content),
|
||||
"markerType" => 'nowiki'
|
||||
];
|
||||
}
|
||||
}
|
@ -1,53 +1,53 @@
|
||||
<?php
|
||||
namespace Isekai\Widgets;
|
||||
|
||||
use Title;
|
||||
use MediaWiki\MediaWikiServices;
|
||||
|
||||
class FontFaceWidget {
|
||||
/**
|
||||
* @param string $text
|
||||
* @param array $params
|
||||
* @param \Parser $parser
|
||||
* @param \PPFrame $frame
|
||||
*/
|
||||
public static function create($text, $params, $parser, $frame) {
|
||||
if (!isset($params['src']) || !isset($params['name']) ||
|
||||
empty($params['src']) || empty($params['name'])) {
|
||||
return '<span class="error">' . wfMessage('isekai-fontface-error-invalid-params')->parse() . '</span>';
|
||||
}
|
||||
|
||||
$service = MediaWikiServices::getInstance();
|
||||
|
||||
$fontName = 'extra-' . $params['name'];
|
||||
$existsFonts = $parser->extIsekaiWidgetsCache->get('extraFonts', INF, []);
|
||||
if (isset($existsFonts[$fontName])) {
|
||||
return '<span class="error">' .
|
||||
wfMessage('isekai-fontface-error-font-already-defined', $params['name'])->parse() .
|
||||
'</span>';
|
||||
}
|
||||
if (preg_match('/[`~!@#$%^&*()+=<>?:"{}|,.\/;\'\\\\\[\]]\r\n/', $fontName)) {
|
||||
return '<span class="error">' .
|
||||
wfMessage('isekai-fontface-error-font-name-invalid')->parse() .
|
||||
'</span>';
|
||||
}
|
||||
|
||||
$title = Title::newFromText($params['src'], NS_FILE);
|
||||
$file = $service->getRepoGroup()->findFile($title);
|
||||
if (!$file) {
|
||||
return '<span class="error">' .
|
||||
wfMessage('isekai-fontface-error-font-not-exists', $params['src'])->parse() .
|
||||
'</span>';
|
||||
}
|
||||
|
||||
$fontUrl = $file->getUrl();
|
||||
$fontId = substr(Utils::safeBase64Encode(md5($fontName, true)), 0, 8);
|
||||
$css = "<span><style>@font-face{src: url('{$fontUrl}');font-family:'{$fontName}'}" .
|
||||
".isekai-extra-font.font-{$fontId}{font-family:'{$fontName}'}</style></span>";
|
||||
|
||||
$existsFonts[$fontName] = $fontId;
|
||||
$existsFonts = $parser->extIsekaiWidgetsCache->set('extraFonts', $existsFonts);
|
||||
|
||||
return [$css, "markerType" => 'nowiki'];
|
||||
}
|
||||
<?php
|
||||
namespace Isekai\Widgets;
|
||||
|
||||
use Title;
|
||||
use MediaWiki\MediaWikiServices;
|
||||
|
||||
class FontFaceWidget {
|
||||
/**
|
||||
* @param string $text
|
||||
* @param array $params
|
||||
* @param \Parser $parser
|
||||
* @param \PPFrame $frame
|
||||
*/
|
||||
public static function create($text, $params, $parser, $frame) {
|
||||
if (!isset($params['src']) || !isset($params['name']) ||
|
||||
empty($params['src']) || empty($params['name'])) {
|
||||
return '<span class="error">' . wfMessage('isekai-fontface-error-invalid-params')->parse() . '</span>';
|
||||
}
|
||||
|
||||
$service = MediaWikiServices::getInstance();
|
||||
|
||||
$fontName = 'extra-' . $params['name'];
|
||||
$existsFonts = $parser->extIsekaiWidgetsCache->get('extraFonts', INF, []);
|
||||
if (isset($existsFonts[$fontName])) {
|
||||
return '<span class="error">' .
|
||||
wfMessage('isekai-fontface-error-font-already-defined', $params['name'])->parse() .
|
||||
'</span>';
|
||||
}
|
||||
if (preg_match('/[`~!@#$%^&*()+=<>?:"{}|,.\/;\'\\\\\[\]]\r\n/', $fontName)) {
|
||||
return '<span class="error">' .
|
||||
wfMessage('isekai-fontface-error-font-name-invalid')->parse() .
|
||||
'</span>';
|
||||
}
|
||||
|
||||
$title = Title::newFromText($params['src'], NS_FILE);
|
||||
$file = $service->getRepoGroup()->findFile($title);
|
||||
if (!$file) {
|
||||
return '<span class="error">' .
|
||||
wfMessage('isekai-fontface-error-font-not-exists', $params['src'])->parse() .
|
||||
'</span>';
|
||||
}
|
||||
|
||||
$fontUrl = $file->getUrl();
|
||||
$fontId = substr(Utils::safeBase64Encode(md5($fontName, true)), 0, 8);
|
||||
$css = "<span><style>@font-face{src: url('{$fontUrl}');font-family:'{$fontName}'}" .
|
||||
".isekai-extra-font.font-{$fontId}{font-family:'{$fontName}'}</style></span>";
|
||||
|
||||
$existsFonts[$fontName] = $fontId;
|
||||
$existsFonts = $parser->extIsekaiWidgetsCache->set('extraFonts', $existsFonts);
|
||||
|
||||
return [$css, "markerType" => 'nowiki'];
|
||||
}
|
||||
}
|
@ -1,35 +1,35 @@
|
||||
<?php
|
||||
namespace Isekai\Widgets;
|
||||
|
||||
use Html;
|
||||
|
||||
class Html5Widget {
|
||||
public static function createDetails(string $text, array $args, \Parser $parser, \PPFrame $frame) {
|
||||
$parser->getOutput()->addModules('ext.isekai.collapse');
|
||||
$allowedAttr = ['class'];
|
||||
$htmlArgs = array_filter($args, function($k) use($allowedAttr) {
|
||||
return in_array($k, $allowedAttr);
|
||||
}, ARRAY_FILTER_USE_KEY);
|
||||
|
||||
$content = '';
|
||||
if ($text) {
|
||||
$content = Utils::makeParagraph($parser->recursiveTagParse($text, $frame), true);
|
||||
}
|
||||
|
||||
return [Html::rawElement('details', $htmlArgs, $content), "markerType" => 'nowiki'];
|
||||
}
|
||||
|
||||
public static function createSummary(string $text, array $args, \Parser $parser, \PPFrame $frame) {
|
||||
$allowedAttr = ['class'];
|
||||
$htmlArgs = array_filter($args, function($k) use($allowedAttr) {
|
||||
return in_array($k, $allowedAttr);
|
||||
}, ARRAY_FILTER_USE_KEY);
|
||||
|
||||
$content = '';
|
||||
if ($text) {
|
||||
$content = $parser->recursiveTagParse($text, $frame);
|
||||
}
|
||||
|
||||
return [Html::rawElement('summary', $htmlArgs, $content), "markerType" => 'nowiki'];
|
||||
}
|
||||
<?php
|
||||
namespace Isekai\Widgets;
|
||||
|
||||
use Html;
|
||||
|
||||
class Html5Widget {
|
||||
public static function createDetails(string $text, array $args, \Parser $parser, \PPFrame $frame) {
|
||||
$parser->getOutput()->addModules('ext.isekai.collapse');
|
||||
$allowedAttr = ['class'];
|
||||
$htmlArgs = array_filter($args, function($k) use($allowedAttr) {
|
||||
return in_array($k, $allowedAttr);
|
||||
}, ARRAY_FILTER_USE_KEY);
|
||||
|
||||
$content = '';
|
||||
if ($text) {
|
||||
$content = Utils::makeParagraph($parser->recursiveTagParse($text, $frame), true);
|
||||
}
|
||||
|
||||
return [Html::rawElement('details', $htmlArgs, $content), "markerType" => 'nowiki'];
|
||||
}
|
||||
|
||||
public static function createSummary(string $text, array $args, \Parser $parser, \PPFrame $frame) {
|
||||
$allowedAttr = ['class'];
|
||||
$htmlArgs = array_filter($args, function($k) use($allowedAttr) {
|
||||
return in_array($k, $allowedAttr);
|
||||
}, ARRAY_FILTER_USE_KEY);
|
||||
|
||||
$content = '';
|
||||
if ($text) {
|
||||
$content = $parser->recursiveTagParse($text, $frame);
|
||||
}
|
||||
|
||||
return [Html::rawElement('summary', $htmlArgs, $content), "markerType" => 'nowiki'];
|
||||
}
|
||||
}
|
@ -1,217 +1,217 @@
|
||||
<?php
|
||||
namespace Isekai\Widgets;
|
||||
|
||||
use Html;
|
||||
use MediaWiki\MediaWikiServices;
|
||||
use Title;
|
||||
|
||||
class TileWidget {
|
||||
private $size = 'medium';
|
||||
private $icon = false;
|
||||
private $title = '';
|
||||
private $href = '';
|
||||
private $badge = false;
|
||||
private $color = false;
|
||||
private $cover = false;
|
||||
private $images = [];
|
||||
private $grid = false;
|
||||
|
||||
private $attributes = [];
|
||||
|
||||
public function __construct($args, $content){
|
||||
$this->content = $content;
|
||||
$this->parseArgs($args);
|
||||
}
|
||||
|
||||
public static function create(string $text, array $args, \Parser $parser, \PPFrame $frame){
|
||||
$parser->getOutput()->addModules('ext.isekai.tile');
|
||||
|
||||
$content = '';
|
||||
if ($text) {
|
||||
$content = $frame->expand($text);
|
||||
|
||||
$title = preg_replace('/\[\[.*?\]\]/', '', $content);
|
||||
$title = preg_replace('/<img .*?src="(?<src>.*?)".*?srcset="(?<srcset>.*?)"[^\>]+>/', '', $title);
|
||||
$title = strip_tags(trim($title));
|
||||
$args['title'] = $title;
|
||||
}
|
||||
|
||||
$tile = new TileWidget($args, $content);
|
||||
return [$tile->toHtml(), 'markerType' => 'nowiki'];
|
||||
}
|
||||
|
||||
private function parseArgs($args){
|
||||
$allowedArgs = ['size', 'icon', 'title', 'cover', '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 getCoverArgs(array &$element, array &$content){
|
||||
$element['data-cover'] = $this->cover;
|
||||
}
|
||||
|
||||
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){
|
||||
$service = MediaWikiServices::getInstance();
|
||||
$this->images = [];
|
||||
// 提取wikitext图片
|
||||
preg_match_all('/\[\[(?<title>.+?:.+?)(\|.*?)?\]\]/', $this->content, $matches);
|
||||
if (isset($matches['title']) && !empty($matches['title'])) {
|
||||
foreach ($matches['title'] as $titleText) {
|
||||
$title = Title::newFromText($titleText);
|
||||
if ($title->inNamespace(NS_FILE)) {
|
||||
$file = $service->getRepoGroup()->findFile($title);
|
||||
$thumb = $file->getUrl();
|
||||
$this->images[] = $thumb;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 提取html图片
|
||||
preg_match_all('/<img .*?src="(?<src>.*?)".*?srcset="(?<srcset>.*?)"[^\>]+>/', $this->content, $matches);
|
||||
if (isset($matches['src']) && !empty($matches['src'])) {
|
||||
$this->images = array_merge($this->images, $matches['src']);
|
||||
}
|
||||
|
||||
if(!empty($this->images)){
|
||||
$element['data-effect'] = 'image-set';
|
||||
foreach($this->images as $image){
|
||||
$content[] = Html::element('img', [
|
||||
'src' => $image,
|
||||
'style' => 'display: none'
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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->getCoverArgs($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);
|
||||
}
|
||||
<?php
|
||||
namespace Isekai\Widgets;
|
||||
|
||||
use Html;
|
||||
use MediaWiki\MediaWikiServices;
|
||||
use Title;
|
||||
|
||||
class TileWidget {
|
||||
private $size = 'medium';
|
||||
private $icon = false;
|
||||
private $title = '';
|
||||
private $href = '';
|
||||
private $badge = false;
|
||||
private $color = false;
|
||||
private $cover = false;
|
||||
private $images = [];
|
||||
private $grid = false;
|
||||
|
||||
private $attributes = [];
|
||||
|
||||
public function __construct($args, $content){
|
||||
$this->content = $content;
|
||||
$this->parseArgs($args);
|
||||
}
|
||||
|
||||
public static function create(string $text, array $args, \Parser $parser, \PPFrame $frame){
|
||||
$parser->getOutput()->addModules('ext.isekai.tile');
|
||||
|
||||
$content = '';
|
||||
if ($text) {
|
||||
$content = $frame->expand($text);
|
||||
|
||||
$title = preg_replace('/\[\[.*?\]\]/', '', $content);
|
||||
$title = preg_replace('/<img .*?src="(?<src>.*?)".*?srcset="(?<srcset>.*?)"[^\>]+>/', '', $title);
|
||||
$title = strip_tags(trim($title));
|
||||
$args['title'] = $title;
|
||||
}
|
||||
|
||||
$tile = new TileWidget($args, $content);
|
||||
return [$tile->toHtml(), 'markerType' => 'nowiki'];
|
||||
}
|
||||
|
||||
private function parseArgs($args){
|
||||
$allowedArgs = ['size', 'icon', 'title', 'cover', '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 getCoverArgs(array &$element, array &$content){
|
||||
$element['data-cover'] = $this->cover;
|
||||
}
|
||||
|
||||
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){
|
||||
$service = MediaWikiServices::getInstance();
|
||||
$this->images = [];
|
||||
// 提取wikitext图片
|
||||
preg_match_all('/\[\[(?<title>.+?:.+?)(\|.*?)?\]\]/', $this->content, $matches);
|
||||
if (isset($matches['title']) && !empty($matches['title'])) {
|
||||
foreach ($matches['title'] as $titleText) {
|
||||
$title = Title::newFromText($titleText);
|
||||
if ($title->inNamespace(NS_FILE)) {
|
||||
$file = $service->getRepoGroup()->findFile($title);
|
||||
$thumb = $file->getUrl();
|
||||
$this->images[] = $thumb;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 提取html图片
|
||||
preg_match_all('/<img .*?src="(?<src>.*?)".*?srcset="(?<srcset>.*?)"[^\>]+>/', $this->content, $matches);
|
||||
if (isset($matches['src']) && !empty($matches['src'])) {
|
||||
$this->images = array_merge($this->images, $matches['src']);
|
||||
}
|
||||
|
||||
if(!empty($this->images)){
|
||||
$element['data-effect'] = 'image-set';
|
||||
foreach($this->images as $image){
|
||||
$content[] = Html::element('img', [
|
||||
'src' => $image,
|
||||
'style' => 'display: none'
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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->getCoverArgs($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);
|
||||
}
|
||||
}
|
@ -1,35 +1,35 @@
|
||||
<?php
|
||||
namespace Isekai\Widgets;
|
||||
|
||||
use MapCacheLRU;
|
||||
use Parser;
|
||||
|
||||
class Widgets {
|
||||
/**
|
||||
* @param \Parser $parser
|
||||
*/
|
||||
public static function onParserSetup(&$parser){
|
||||
$parser->extIsekaiWidgetsCache = new MapCacheLRU( 100 ); // 100 is arbitrary
|
||||
|
||||
$parser->setHook('createpage', [CreatePageWidget::class, 'create']);
|
||||
$parser->setHook('discoverbox', [DiscoverWidget::class, 'create']);
|
||||
$parser->setHook('feedlist', [FeedListWidget::class, 'create']);
|
||||
$parser->setHook('previewcard', [PreviewCardWidget::class, 'create']);
|
||||
|
||||
$parser->setHook('tile', [TileWidget::class, 'create']);
|
||||
$parser->setHook('tilegroup', [TileGroupWidget::class, 'create']);
|
||||
|
||||
$parser->setHook('fontface', [FontFaceWidget::class, 'create']);
|
||||
$parser->setHook('exfont', [ExtraFontWidget::class, 'create']);
|
||||
|
||||
$parser->setHook('details', [Html5Widget::class, 'createDetails']);
|
||||
$parser->setHook('summary', [Html5Widget::class, 'createSummary']);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function onLoad(\OutputPage $outputPage) {
|
||||
$outputPage->addModuleStyles("ext.isekai.widgets.global");
|
||||
$outputPage->addModuleStyles("ext.isekai.collapse");
|
||||
}
|
||||
<?php
|
||||
namespace Isekai\Widgets;
|
||||
|
||||
use MapCacheLRU;
|
||||
use Parser;
|
||||
|
||||
class Widgets {
|
||||
/**
|
||||
* @param \Parser $parser
|
||||
*/
|
||||
public static function onParserSetup(&$parser){
|
||||
$parser->extIsekaiWidgetsCache = new MapCacheLRU( 100 ); // 100 is arbitrary
|
||||
|
||||
$parser->setHook('createpage', [CreatePageWidget::class, 'create']);
|
||||
$parser->setHook('discoverbox', [DiscoverWidget::class, 'create']);
|
||||
$parser->setHook('feedlist', [FeedListWidget::class, 'create']);
|
||||
$parser->setHook('previewcard', [PreviewCardWidget::class, 'create']);
|
||||
|
||||
$parser->setHook('tile', [TileWidget::class, 'create']);
|
||||
$parser->setHook('tilegroup', [TileGroupWidget::class, 'create']);
|
||||
|
||||
$parser->setHook('fontface', [FontFaceWidget::class, 'create']);
|
||||
$parser->setHook('exfont', [ExtraFontWidget::class, 'create']);
|
||||
|
||||
$parser->setHook('details', [Html5Widget::class, 'createDetails']);
|
||||
$parser->setHook('summary', [Html5Widget::class, 'createSummary']);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function onLoad(\OutputPage $outputPage) {
|
||||
$outputPage->addModuleStyles("ext.isekai.widgets.global");
|
||||
$outputPage->addModuleStyles("ext.isekai.collapse");
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue