diff --git a/IsekaiWidgets.zip b/IsekaiWidgets.zip new file mode 100644 index 0000000..25feedd Binary files /dev/null and b/IsekaiWidgets.zip differ diff --git a/docs/previewCard-design.md b/docs/previewCard-design.md new file mode 100644 index 0000000..e2c02fa --- /dev/null +++ b/docs/previewCard-design.md @@ -0,0 +1,10 @@ +## 预览卡片设计 +```html + + [[链接1]] + [[链接2]] + + + + +``` diff --git a/extension.json b/extension.json index 8446546..6a141a3 100644 --- a/extension.json +++ b/extension.json @@ -19,6 +19,11 @@ "ParserFirstCallInit": "Isekai\\Widgets\\Widgets::onParserSetup" }, "ResourceModules": { + "ext.isekai.widgets.global": { + "styles": [ + "ext.isekai.alert.less" + ] + }, "ext.isekai.createPage": { "scripts": [ "createPage/ext.isekai.createPage.js", diff --git a/i18n/en.json b/i18n/en.json index f92341e..e5b8827 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -14,5 +14,14 @@ "isekai-discover-loading": "Loading...", "isekai-discover-change-btn": "Another", "isekai-discover-readmore-btn": "Detail", - "isekai-discover-error-cannotload": "Cannot load page from server." + "isekai-discover-error-cannotload": "Cannot load page from server.", + + "isekai-fontface-error-invalid-params": "Please specify src and name attributes.", + "isekai-fontface-error-font-name-invalid": "Font name cannot contain special characters.", + "isekai-fontface-error-font-not-exists": "Font file \"$1\" not exists.", + "isekai-fontface-error-font-already-defined": "Font \"$1\" already imported, please check.", + + "isekai-font-error-invalid-params": "Please specify name attributes.", + "isekai-font-error-font-name-invalid": "Font name cannot contain special characters.", + "isekai-font-error-font-not-imported": "Font \"$1\" not imported." } \ No newline at end of file diff --git a/i18n/zh-hans.json b/i18n/zh-hans.json index 0c3bd95..a2fef24 100644 --- a/i18n/zh-hans.json +++ b/i18n/zh-hans.json @@ -14,5 +14,14 @@ "isekai-discover-loading": "加载中……", "isekai-discover-change-btn": "换一个", "isekai-discover-readmore-btn": "查看", - "isekai-discover-error-cannotload": "无法从服务器加载数据" + "isekai-discover-error-cannotload": "无法从服务器加载数据", + + "isekai-fontface-error-invalid-params": "请提供src和name参数。", + "isekai-fontface-error-font-name-invalid": "字体名中不能包含特殊字符。", + "isekai-fontface-error-font-not-exists": "字体文件 \"$1\" 不存在。", + "isekai-fontface-error-font-already-defined": "字体 \"$1\" 已引用,请检查重复引用。", + + "isekai-font-error-invalid-params": "请提供name参数。", + "isekai-font-error-font-name-invalid": "字体名中不能包含特殊字符。", + "isekai-font-error-font-not-imported": "未导入字体: \"$1\"。" } \ No newline at end of file diff --git a/i18n/zh-hant.json b/i18n/zh-hant.json index 89d9db6..464c574 100644 --- a/i18n/zh-hant.json +++ b/i18n/zh-hant.json @@ -14,5 +14,14 @@ "isekai-discover-loading": "讀取中……", "isekai-discover-change-btn": "換一個", "isekai-discover-readmore-btn": "詳情", - "isekai-discover-error-cannotload": "無法從伺服器讀取數據" + "isekai-discover-error-cannotload": "無法從伺服器讀取數據", + + "isekai-fontface-error-invalid-params": "請提供src和name參數。", + "isekai-fontface-error-font-name-invalid": "字體名中不能包含特殊字元。", + "isekai-fontface-error-font-not-exists": "字體檔案 \"$1\" 不存在。", + "isekai-fontface-error-font-already-defined": "字體 \"$1\" 已被引用,請檢查重複引用。", + + "isekai-font-error-invalid-params": "請提供name參數。", + "isekai-font-error-font-name-invalid": "字體名中不能包含特殊字元。", + "isekai-font-error-font-not-imported": "未導入字體: \"$1\"。" } \ No newline at end of file diff --git a/includes/ExtraFontWidget.php b/includes/ExtraFontWidget.php new file mode 100644 index 0000000..3116ef0 --- /dev/null +++ b/includes/ExtraFontWidget.php @@ -0,0 +1,39 @@ +extIsekaiWidgetsCache->get('extraFonts', INF, []); + + $content = $text = $frame->expand($text); + if (!isset($params['name']) || empty($params['name'])) { + return '' . wfMessage('isekai-font-error-invalid-params')->parse() . '' . $content; + } + + $fontName = 'extra-' . $params['name']; + if (preg_match('/[`~!@#$%^&*()+=<>?:"{}|,.\/;\'\\\\\[\]]\r\n/', $fontName)) { + return '' . + wfMessage('isekai-font-error-font-name-invalid')->parse() . + '' . + $content; + } + + $existsFonts = $parser->extIsekaiWidgetsCache->get('extraFonts', INF, []); + if (!isset($existsFonts[$fontName])) { + return '' . + wfMessage('isekai-font-error-font-not-imported', $params['name'])->parse() . + '' . + $content; + } + $fontId = $existsFonts[$fontName]; + + return [ + Html::rawElement('span', [ + 'class' => 'isekai-extra-font font-' . $fontId, + ], $content), + "markerType" => 'nowiki' + ]; + } +} \ No newline at end of file diff --git a/includes/FontFaceWidget.php b/includes/FontFaceWidget.php new file mode 100644 index 0000000..385c221 --- /dev/null +++ b/includes/FontFaceWidget.php @@ -0,0 +1,53 @@ +' . wfMessage('isekai-fontface-error-invalid-params')->parse() . ''; + } + + $service = MediaWikiServices::getInstance(); + + $fontName = 'extra-' . $params['name']; + $existsFonts = $parser->extIsekaiWidgetsCache->get('extraFonts', INF, []); + if (isset($existsFonts[$fontName])) { + return '' . + wfMessage('isekai-fontface-error-font-already-defined', $params['name'])->parse() . + ''; + } + if (preg_match('/[`~!@#$%^&*()+=<>?:"{}|,.\/;\'\\\\\[\]]\r\n/', $fontName)) { + return '' . + wfMessage('isekai-fontface-error-font-name-invalid')->parse() . + ''; + } + + $title = Title::newFromText($params['src'], NS_FILE); + $file = $service->getRepoGroup()->findFile($title); + if (!$file) { + return '' . + wfMessage('isekai-fontface-error-font-not-exists', $params['src'])->parse() . + ''; + } + + $fontUrl = $file->getUrl(); + $fontId = substr(Utils::safeBase64Encode(md5($fontName, true)), 0, 8); + $css = ""; + + $existsFonts[$fontName] = $fontId; + $existsFonts = $parser->extIsekaiWidgetsCache->set('extraFonts', $existsFonts); + + return [$css, "markerType" => 'nowiki']; + } +} \ No newline at end of file diff --git a/includes/PreviewCardWidget.php b/includes/PreviewCardWidget.php index 0180793..58be736 100644 --- a/includes/PreviewCardWidget.php +++ b/includes/PreviewCardWidget.php @@ -5,7 +5,7 @@ class PreviewCardWidget { public static function getHtml($variables){ extract($variables); ob_start(); - include(dirname(__DIR__) . '/modules/previewCard/ext.isekai.previewCard.tpl'); + include(dirname(__DIR__) . '/modules/previewCard/ext.isekai.previewCard.html'); $template = ob_get_clean(); return [$template, "markerType" => 'nowiki']; } diff --git a/includes/Utils.php b/includes/Utils.php new file mode 100644 index 0000000..d18d572 --- /dev/null +++ b/includes/Utils.php @@ -0,0 +1,8 @@ +extIsekaiWidgetsCache = new MapCacheLRU( 100 ); // 100 is arbitrary + $parser->setHook('createpage', CreatePageWidget::class . '::create'); $parser->setHook('discoverbox', DiscoverWidget::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'); return true; } } \ No newline at end of file diff --git a/modules/ext.isekai.alert.less b/modules/ext.isekai.alert.less new file mode 100644 index 0000000..e69de29 diff --git a/modules/previewCard/ext.isekai.previewCard.tpl b/modules/previewCard/ext.isekai.previewCard.html similarity index 91% rename from modules/previewCard/ext.isekai.previewCard.tpl rename to modules/previewCard/ext.isekai.previewCard.html index 4a5d098..93a6f62 100644 --- a/modules/previewCard/ext.isekai.previewCard.tpl +++ b/modules/previewCard/ext.isekai.previewCard.html @@ -1,5 +1,5 @@
-
+