├── .browserslistrc ├── .editorconfig ├── .gitattributes ├── .github ├── auto_assign.yaml ├── dependabot.yaml └── workflows │ ├── CodeQL.yaml │ ├── auto_assign.yaml │ ├── auto_fix.yaml │ ├── detectHardcodedOutdatedNPMPackages.yaml │ ├── generatePolyfill.yaml │ ├── postCommit.yaml │ └── test.yaml ├── .gitignore ├── .mailmap ├── .markdownlint.yaml ├── .postcssrc.yaml ├── .prettierrc.yaml ├── .stylelintrc.yaml ├── .v8rrc.yaml ├── .vscode ├── json-schemas │ ├── gadget-definition.json │ └── user-rights-definition.json └── settings.json ├── CODE_OF_CONDUCT.md ├── README.md ├── SECURITY.md ├── eslint.config.js ├── package-lock.json ├── package.json ├── scripts ├── autoAssign │ └── index.js ├── browserify │ ├── index.js │ └── targets.yaml ├── ci │ ├── after.js │ └── before.js ├── detectHardcodedOutdatedNPMPackages │ ├── index.js │ └── whitelist.yaml ├── emailmapChecker │ └── index.js ├── fireWebhook │ └── index.js ├── generateCommitsHistory │ └── index.js ├── generateConventionalCommitsScopes │ └── index.js ├── generateGadgetsDefinition │ └── index.js ├── generatePolyfill │ ├── config.yaml │ ├── customPolyfill │ │ ├── library │ │ │ └── crypto.randomUUID │ │ │ │ └── raw.js │ │ ├── main.json │ │ └── package.json │ └── index.js ├── generateUserRightsSchema │ └── index.js ├── infoAboutFailure.sh ├── minification │ └── terser.js ├── modules │ ├── artifact.js │ ├── console.js │ ├── createCommit.js │ ├── debugLog.js │ ├── diffArray.js │ ├── exec.js │ ├── fetchNPMPackageInfo.js │ ├── fixZero.js │ ├── generateHMACSignature.js │ ├── getUpstream.js │ ├── git.js │ ├── jsonModule.js │ ├── mailmap.js │ ├── minify-stream.js │ ├── mkdtmp.js │ ├── modulePath.js │ ├── octokit.js │ ├── readDir.js │ ├── sortWithLowerFirstCharacter.js │ ├── testLatency.js │ ├── toLocalTimeZoneStrings.js │ ├── workflowEvent.js │ └── yamlModule.js ├── package.json ├── postCommit │ ├── linguist-generated.js │ ├── prepareGit.js │ └── push.js ├── postcss │ └── index.js ├── prefetch │ ├── index.js │ └── targets.yaml ├── skip │ ├── config.yaml │ └── index.js └── test │ └── test.js ├── src ├── @types │ ├── LocalObjectStorage.d.ts │ ├── libBottomRightCorner.d.ts │ ├── libCachedCode.d.ts │ └── site-lib.d.ts ├── gadgets │ ├── CleanDeleteReasons │ │ ├── Gadget-CleanDeleteReasons.js │ │ └── definition.yaml │ ├── CommentsinLocalTime │ │ ├── Gadget-CommentsinLocalTime.js │ │ └── definition.yaml │ ├── ContentAboveBelowImage │ │ ├── Gadget-ContentAboveBelowImage.css │ │ ├── Gadget-ContentAboveBelowImage.js │ │ └── definition.yaml │ ├── DotsSyntaxHighlighter │ │ ├── Gadget-DotsSyntaxHighlighter.js │ │ └── definition.yaml │ ├── FlowThreadCheck │ │ ├── Gadget-FlowThreadCheck.css │ │ ├── Gadget-FlowThreadCheck.js │ │ └── definition.yaml │ ├── FlowthreadTOC │ │ ├── Gadget-FlowthreadTOC.js │ │ └── definition.yaml │ ├── ForcePreviewUponUserRequest │ │ ├── Gadget-Force_preview_upon_user_request.js │ │ └── definition.yaml │ ├── Force_preview │ │ ├── Gadget-Force_preview.js │ │ └── definition.yaml │ ├── Gadgets-definition-list.yaml │ ├── GiveYouUp │ │ ├── Gadget-GiveYouUp.js │ │ └── definition.yaml │ ├── GothicMoe │ │ ├── Gadget-GothicMoe.css │ │ └── definition.yaml │ ├── HeimuToggle │ │ ├── Gadget-heimu-toggle.css │ │ ├── Gadget-heimu-toggle.js │ │ └── definition.yaml │ ├── HeimuToggleDefaultOn │ │ ├── Gadget-heimu-toggle-defaultOn.js │ │ └── definition.yaml │ ├── HotCat │ │ ├── Gadget-HotCat.js │ │ └── definition.yaml │ ├── InPageEdit-v2 │ │ ├── Gadget-InPageEdit-v2.css │ │ ├── Gadget-InPageEdit-v2.js │ │ └── definition.yaml │ ├── JSONViewer │ │ ├── Gadget-JSONViewer.js │ │ └── definition.yaml │ ├── LetYouDown │ │ ├── Gadget-LetYouDown.js │ │ └── definition.yaml │ ├── LocalObjectStorage │ │ ├── Gadget-LocalObjectStorage.js │ │ └── definition.yaml │ ├── Logout-confirm │ │ ├── Gadget-Logout-confirm.js │ │ └── definition.yaml │ ├── MarkAsResolved-restricted │ │ ├── Gadget-MarkAsResolved-restricted.js │ │ └── definition.yaml │ ├── MarkAsResolved │ │ ├── Gadget-MarkAsResolved.css │ │ ├── Gadget-MarkAsResolved.js │ │ └── definition.yaml │ ├── ModerationStatus │ │ ├── Gadget-ModerationStatus.js │ │ └── definition.yaml │ ├── Navbox-link │ │ ├── Gadget-Navbox-link.js │ │ └── definition.yaml │ ├── Navigation_popups │ │ ├── Gadget-popups.css │ │ ├── Gadget-popups.js │ │ └── definition.yaml │ ├── Purgecache │ │ ├── Gadget-Purgecache.css │ │ ├── Gadget-Purgecache.js │ │ └── definition.yaml │ ├── ReferenceTooltips │ │ ├── Gadget-ReferenceTooltips.css │ │ ├── Gadget-ReferenceTooltips.js │ │ └── definition.yaml │ ├── Searchbox-integration │ │ ├── Gadget-Searchbox-integration.css │ │ ├── Gadget-Searchbox-integration.js │ │ └── definition.yaml │ ├── Searchbox-popout │ │ ├── Gadget-Searchbox-popout.js │ │ └── definition.yaml │ ├── SectionPermanentLink │ │ ├── Gadget-SectionPermanentLink.js │ │ └── definition.yaml │ ├── SendWelcomeMessage │ │ ├── Gadget-SendWelcomeMessage.css │ │ ├── Gadget-SendWelcomeMessage.js │ │ └── definition.yaml │ ├── ShowAvatar │ │ ├── Gadget-ShowAvatar.css │ │ ├── Gadget-ShowAvatar.js │ │ └── definition.yaml │ ├── SideBarPic │ │ ├── Gadget-SideBarPic.css │ │ ├── Gadget-SideBarPic.js │ │ └── definition.yaml │ ├── SpecialWikitext │ │ ├── Gadget-SpecialWikitext.js │ │ └── definition.yaml │ ├── UserLinkAvatar │ │ ├── Gadget-UserLinkAvatar.css │ │ ├── Gadget-UserLinkAvatar.js │ │ └── definition.yaml │ ├── UserMessages │ │ ├── Gadget-UserMessages.js │ │ └── definition.yaml │ ├── Wikiplus │ │ ├── Gadget-Wikiplus.css │ │ ├── Gadget-Wikiplus.js │ │ └── definition.yaml │ ├── abusefilter33test │ │ ├── Gadget-abusefilter33test.js │ │ └── definition.yaml │ ├── abusefilterEdit │ │ ├── Gadget-abusefilteredit.css │ │ ├── Gadget-abusefilteredit.js │ │ └── definition.yaml │ ├── abusefilterResize │ │ ├── Gadget-abusefilterresize.js │ │ └── definition.yaml │ ├── allmessageFilter │ │ ├── Gadget-allmessageFilter.js │ │ └── definition.yaml │ ├── april-fool-2025 │ │ ├── Gadget-april-fool-2025.js │ │ ├── _main.js │ │ └── definition.yaml │ ├── autocollapse │ │ ├── Gadget-autocollapse.js │ │ └── definition.yaml │ ├── autoconfirmedUserPing │ │ ├── Gadget-autoconfirmedUserPing.js │ │ └── definition.yaml │ ├── backlog │ │ ├── Gadget-backlog.css │ │ ├── Gadget-backlog.js │ │ └── definition.yaml │ ├── blockEnhance │ │ ├── Gadget-blockEnhance.js │ │ └── definition.yaml │ ├── code-prettify │ │ ├── Gadget-code-prettify.css │ │ ├── Gadget-code-prettify.js │ │ └── definition.yaml │ ├── deletion │ │ ├── Gadget-deletion.css │ │ ├── Gadget-deletion.js │ │ └── definition.yaml │ ├── disable-nest-alert │ │ ├── Gadget-disable-nest-alert.js │ │ └── definition.yaml │ ├── disambigLink │ │ ├── Gadget-disambigLink.css │ │ └── definition.yaml │ ├── edit │ │ ├── Gadget-edit.js │ │ └── definition.yaml │ ├── editCount │ │ ├── Gadget-editCount.js │ │ └── definition.yaml │ ├── editTopSection │ │ ├── Gadget-editTopSection.css │ │ ├── Gadget-editTopSection.js │ │ └── definition.yaml │ ├── enable-nest-highlight │ │ ├── Gadget-enable-nest-highlight.js │ │ └── definition.yaml │ ├── extiw │ │ ├── Gadget-extiw.css │ │ └── definition.yaml │ ├── flagBlocked │ │ ├── Gadget-flagBlocked.js │ │ └── definition.yaml │ ├── flagEditWar │ │ ├── Gadget-flagEditWar.js │ │ └── definition.yaml │ ├── float-toc │ │ ├── Gadget-float-toc.css │ │ ├── Gadget-float-toc.js │ │ └── definition.yaml │ ├── hideAutopromoteLog │ │ ├── Gadget-hideAutoPromoteLog.css │ │ └── definition.yaml │ ├── hideFlowthreadDefaultly │ │ ├── Gadget-hideFlowthreadDefaultly.js │ │ └── definition.yaml │ ├── hideUnpatrolledFlag │ │ ├── Gadget-hideUnpatrolledFlag.css │ │ └── definition.yaml │ ├── interfaceVariantConverter │ │ ├── Gadget-interfaceVariantConverter.js │ │ └── definition.yaml │ ├── jQueryLazyload │ │ ├── Gadget-jQueryLazyload.js │ │ └── definition.yaml │ ├── legacyMainpage │ │ ├── Gadget-legacyMainpage.js │ │ └── definition.yaml │ ├── libBottomRightCorner │ │ ├── Gadget-libBottomRightCorner.css │ │ ├── Gadget-libBottomRightCorner.js │ │ └── definition.yaml │ ├── libCachedCode │ │ ├── Gadget-libCachedCode.js │ │ └── definition.yaml │ ├── libDiscussionUtil │ │ ├── Gadget-libDiscussionUtil.js │ │ └── definition.yaml │ ├── libHashwasm │ │ ├── .eslintrc.yaml │ │ ├── Gadget-libHashwasm.js │ │ └── definition.yaml │ ├── libJQuery │ │ ├── Gadget-libJQuery.js │ │ └── definition.yaml │ ├── libJSON5 │ │ ├── .eslintrc.yaml │ │ ├── Gadget-libJSON5.js │ │ └── definition.yaml │ ├── libOOUIDialog │ │ ├── Gadget-libOOUIDialog.js │ │ └── definition.yaml │ ├── libPolyfill │ │ ├── Gadget-libPolyfill-Array.prototype.at.js │ │ ├── Gadget-libPolyfill-String.prototype.at.js │ │ ├── Gadget-libPolyfill-TypedArray.prototype.at.js │ │ ├── Gadget-libPolyfill-crypto.randomUUID.js │ │ └── definition.yaml │ ├── libUtil │ │ ├── Gadget-libUtil.js │ │ └── definition.yaml │ ├── libip │ │ ├── .eslintrc.yaml │ │ ├── Gadget-libip.js │ │ └── definition.yaml │ ├── localforage │ │ ├── .eslintrc.yaml │ │ ├── Gadget-localforage.js │ │ └── definition.yaml │ ├── moeskin-classic │ │ ├── Gadget-moeskin-classic.css │ │ └── definition.yaml │ ├── moeskin-styles │ │ ├── Gadget-moeskin-styles.css │ │ └── definition.yaml │ ├── moeskin-topbar │ │ ├── Gadget-moeskin-topbar.js │ │ └── definition.yaml │ ├── moveToUserSubpage │ │ ├── Gadget-moveToUserSubpage.js │ │ └── definition.yaml │ ├── mwPanel │ │ ├── Gadget-mwPanel.js │ │ └── definition.yaml │ ├── noteTA │ │ ├── Gadget-noteTA.css │ │ ├── Gadget-noteTA.js │ │ └── definition.yaml │ ├── noticeActivity │ │ ├── Gadget-noticeActivity.css │ │ └── definition.yaml │ ├── patrolCount │ │ ├── Gadget-patrolCount.js │ │ └── definition.yaml │ ├── patrolPlus │ │ ├── Gadget-patrolPlus.css │ │ ├── Gadget-patrolPlus.js │ │ └── definition.yaml │ ├── prism-core │ │ ├── .eslintrc.yaml │ │ ├── Gadget-prism-core.js │ │ ├── Gadget-prism-coy.css │ │ ├── Gadget-prism-line-numbers.css │ │ ├── Gadget-prism-line-numbers.js │ │ ├── Gadget-prism-loader.js │ │ └── definition.yaml │ ├── prism-language-bash │ │ ├── .eslintrc.yaml │ │ ├── Gadget-prism-language-bash.js │ │ └── definition.yaml │ ├── prism-language-c │ │ ├── .eslintrc.yaml │ │ ├── Gadget-prism-language-c.js │ │ └── definition.yaml │ ├── prism-language-clike │ │ ├── .eslintrc.yaml │ │ ├── Gadget-prism-language-clike.js │ │ └── definition.yaml │ ├── prism-language-coffeescript │ │ ├── .eslintrc.yaml │ │ ├── Gadget-prism-language-coffeescript.js │ │ └── definition.yaml │ ├── prism-language-cpp │ │ ├── .eslintrc.yaml │ │ ├── Gadget-prism-language-cpp.js │ │ └── definition.yaml │ ├── prism-language-csharp │ │ ├── .eslintrc.yaml │ │ ├── Gadget-prism-language-csharp.js │ │ └── definition.yaml │ ├── prism-language-css │ │ ├── .eslintrc.yaml │ │ ├── Gadget-prism-language-css-extras.js │ │ ├── Gadget-prism-language-css.js │ │ └── definition.yaml │ ├── prism-language-java │ │ ├── .eslintrc.yaml │ │ ├── Gadget-prism-language-java.js │ │ └── definition.yaml │ ├── prism-language-javascript │ │ ├── .eslintrc.yaml │ │ ├── Gadget-prism-language-javascript-extras.js │ │ ├── Gadget-prism-language-javascript.js │ │ └── definition.yaml │ ├── prism-language-json │ │ ├── .eslintrc.yaml │ │ ├── Gadget-prism-language-json.js │ │ ├── Gadget-prism-language-json5.js │ │ └── definition.yaml │ ├── prism-language-latex │ │ ├── .eslintrc.yaml │ │ ├── Gadget-prism-language-latex.js │ │ └── definition.yaml │ ├── prism-language-lua │ │ ├── .eslintrc.yaml │ │ ├── Gadget-prism-language-lua.js │ │ └── definition.yaml │ ├── prism-language-markup │ │ ├── .eslintrc.yaml │ │ ├── Gadget-prism-language-markup.js │ │ └── definition.yaml │ ├── prism-language-perl │ │ ├── .eslintrc.yaml │ │ ├── Gadget-prism-language-perl.js │ │ └── definition.yaml │ ├── prism-language-php │ │ ├── .eslintrc.yaml │ │ ├── Gadget-prism-language-markup-templating.js │ │ ├── Gadget-prism-language-php-extras.js │ │ ├── Gadget-prism-language-php.js │ │ └── definition.yaml │ ├── prism-language-python │ │ ├── .eslintrc.yaml │ │ ├── Gadget-prism-language-python.js │ │ └── definition.yaml │ ├── prism-language-regex │ │ ├── .eslintrc.yaml │ │ ├── Gadget-prism-language-regex.js │ │ └── definition.yaml │ ├── prism-language-ruby │ │ ├── .eslintrc.yaml │ │ ├── Gadget-prism-language-ruby.js │ │ └── definition.yaml │ ├── prism-language-typescript │ │ ├── .eslintrc.yaml │ │ ├── Gadget-prism-language-typescript.js │ │ └── definition.yaml │ ├── prism-language-wiki │ │ ├── Gadget-prism-language-wiki.js │ │ ├── Gadget-prism-language-wiki.json │ │ └── definition.yaml │ ├── prism-language-yaml │ │ ├── .eslintrc.yaml │ │ ├── Gadget-prism-language-yaml.js │ │ └── definition.yaml │ ├── prism-plugin-javadoclike │ │ ├── .eslintrc.yaml │ │ ├── Gadget-prism-plugin-javadoclike.js │ │ └── definition.yaml │ ├── prism-plugin-jsdoc │ │ ├── .eslintrc.yaml │ │ ├── Gadget-prism-plugin-jsdoc.js │ │ └── definition.yaml │ ├── prism-plugin-match-braces │ │ ├── .eslintrc.yaml │ │ ├── Gadget-prism-plugin-match-braces.css │ │ ├── Gadget-prism-plugin-match-braces.js │ │ └── definition.yaml │ ├── prism-plugin-phpdoc │ │ ├── .eslintrc.yaml │ │ ├── Gadget-prism-plugin-phpdoc.js │ │ └── definition.yaml │ ├── prism-plugin-previewers │ │ ├── .eslintrc.yaml │ │ ├── Gadget-prism-plugin-previewers.css │ │ ├── Gadget-prism-plugin-previewers.js │ │ └── definition.yaml │ ├── prism │ │ ├── Gadget-prism.css │ │ ├── Gadget-prism.js │ │ └── definition.yaml │ ├── queryContributions │ │ ├── Gadget-queryContributions.js │ │ └── definition.yaml │ ├── queryWhatlinkshere │ │ ├── Gadget-queryWhatlinkshere.js │ │ └── definition.yaml │ ├── quickMoveThread │ │ ├── Gadget-quickMoveThread.js │ │ └── definition.yaml │ ├── quickSave │ │ ├── Gadget-quickSave.css │ │ ├── Gadget-quickSave.js │ │ └── definition.yaml │ ├── registerToDelete │ │ ├── Gadget-registerToDelete.js │ │ └── definition.yaml │ ├── report │ │ ├── Gadget-report.js │ │ └── definition.yaml │ ├── rollback-summary │ │ ├── Gadget-rollback-summary.js │ │ └── definition.yaml │ ├── shortlink │ │ ├── Gadget-shortlink.js │ │ └── definition.yaml │ ├── sidebarHidden │ │ ├── Gadget-sidebarHidden.css │ │ ├── Gadget-sidebarHidden.js │ │ └── definition.yaml │ ├── site-js │ │ ├── Gadget-site-js.js │ │ └── definition.yaml │ ├── site-lib │ │ ├── Gadget-site-lib.js │ │ └── definition.yaml │ ├── site-styles │ │ ├── Gadget-site-styles.css │ │ └── definition.yaml │ ├── temp-editcheck │ │ ├── Gadget-temp-editcheck.js │ │ └── definition.yaml │ ├── temp-svgFix │ │ ├── Gadget-temp-svgFix.js │ │ └── definition.yaml │ ├── uploader │ │ ├── Gadget-uploader.js │ │ └── definition.yaml │ ├── userLinkAvatarMagnifier │ │ ├── Gadget-UserLinkAvatarMagnifier.css │ │ └── definition.yaml │ ├── usergroup │ │ ├── Gadget-usergroup.js │ │ └── definition.yaml │ ├── userpageCat │ │ ├── Gadget-userpagecat.css │ │ └── definition.yaml │ ├── userpageDelete │ │ ├── Gadget-userpageDelete.js │ │ └── definition.yaml │ ├── vector-2022-styles │ │ ├── Gadget-vector-2022-styles.css │ │ └── definition.yaml │ ├── vector-styles │ │ ├── Gadget-vector-styles.css │ │ └── definition.yaml │ ├── widgetPreload │ │ ├── Gadget-widgetPreload.css │ │ ├── Gadget-widgetPreload.js │ │ └── definition.yaml │ ├── wikiBlame │ │ ├── Gadget-wikiBlame.js │ │ └── definition.yaml │ ├── wikiplus-highlight │ │ ├── Gadget-wikiplus-highlight.js │ │ └── definition.yaml │ └── zeroFill │ │ ├── Gadget-zerofill.css │ │ └── definition.yaml ├── global │ ├── commons │ │ ├── Common.css │ │ ├── Common.js │ │ └── Moeskin.js │ └── zh │ │ ├── Common.js │ │ ├── GHIAHistory.json │ │ ├── Moeskin.js │ │ ├── Vector-2022.js │ │ └── WikiLove.js ├── groups │ ├── commons │ │ ├── checkuser │ │ │ └── Group-checkuser.css │ │ ├── interface-admin │ │ │ └── Group-interface-admin.css │ │ ├── patroller │ │ │ └── Group-patroller.css │ │ ├── staff │ │ │ ├── Group-staff.css │ │ │ └── Group-staff.js │ │ ├── suppress │ │ │ ├── Group-suppress.css │ │ │ └── Group-suppress.js │ │ └── sysop │ │ │ ├── Group-sysop.css │ │ │ └── Group-sysop.js │ └── zh │ │ ├── checkuser │ │ ├── Group-checkuser.css │ │ └── Group-checkuser.js │ │ ├── interface-admin │ │ └── Group-interface-admin.css │ │ ├── patroller │ │ └── Group-patroller.css │ │ ├── staff │ │ ├── Group-staff.css │ │ └── Group-staff.js │ │ ├── suppress │ │ ├── Group-suppress.css │ │ └── Group-suppress.js │ │ ├── sysop │ │ ├── Group-sysop.css │ │ └── Group-sysop.js │ │ └── user │ │ └── Group-user.css └── package.json ├── tsconfig.json └── tsconfig.production.json /.browserslistrc: -------------------------------------------------------------------------------- 1 | defaults, Chrome >= 86 2 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | # 配合editorconfig扩展使用 3 | root = true 4 | 5 | [*] 6 | indent_style = space 7 | indent_size = 4 8 | end_of_line = lf 9 | 10 | [*.{js}] 11 | charset = utf-8 12 | trim_trailing_whitespace = true 13 | insert_final_newline = true 14 | 15 | [*.{yml,yaml,md}] 16 | indent_size = 2 17 | -------------------------------------------------------------------------------- /.github/auto_assign.yaml: -------------------------------------------------------------------------------- 1 | addReviewers: true 2 | 3 | addAssignees: true 4 | 5 | reviewers: 6 | - AnnAngela 7 | 8 | assignees: 9 | - AnnAngela 10 | - lovelyCARDINAL 11 | -------------------------------------------------------------------------------- /.github/dependabot.yaml: -------------------------------------------------------------------------------- 1 | # To get started with Dependabot version updates, you'll need to specify which 2 | # package ecosystems to update and where the package manifests are located. 3 | # Please see the documentation for all configuration options: 4 | # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates 5 | 6 | version: 2 7 | updates: 8 | - package-ecosystem: github-actions 9 | directory: / 10 | schedule: 11 | interval: daily 12 | time: '07:30' 13 | timezone: Asia/Shanghai 14 | commit-message: 15 | prefix: gha 16 | include: scope 17 | groups: 18 | gha: 19 | patterns: 20 | - "*" 21 | - package-ecosystem: npm # See documentation for possible values 22 | directory: / # Location of package manifests 23 | schedule: 24 | interval: daily 25 | time: '07:30' 26 | timezone: Asia/Shanghai 27 | commit-message: 28 | prefix: npm 29 | include: scope 30 | groups: 31 | npm: 32 | patterns: 33 | - "*" 34 | -------------------------------------------------------------------------------- /.github/workflows/CodeQL.yaml: -------------------------------------------------------------------------------- 1 | name: CodeQL 2 | 3 | on: 4 | push: 5 | paths: 6 | - "**.js" 7 | - "!scripts/test/*.js" 8 | - .github/workflows/CodeQL.yaml 9 | pull_request: 10 | paths: 11 | - "**.js" 12 | - "!scripts/test/*.js" 13 | - .github/workflows/CodeQL.yaml 14 | merge_group: 15 | workflow_dispatch: 16 | schedule: 17 | - cron: 15 23 * * * # Every 07:15 CST 18 | 19 | permissions: 20 | actions: read 21 | checks: write 22 | contents: write 23 | pull-requests: write 24 | security-events: write 25 | statuses: write 26 | 27 | jobs: 28 | CodeQL: 29 | runs-on: ubuntu-latest 30 | steps: 31 | - uses: actions/checkout@v5 32 | with: 33 | show-progress: false 34 | - name: Initialize CodeQL 35 | uses: github/codeql-action/init@v4 36 | with: 37 | languages: javascript 38 | queries: +security-and-quality 39 | - name: Perform CodeQL Analysis 40 | uses: github/codeql-action/analyze@v4 41 | -------------------------------------------------------------------------------- /.github/workflows/auto_assign.yaml: -------------------------------------------------------------------------------- 1 | name: "Auto Assign" 2 | on: 3 | pull_request_target: 4 | types: 5 | - opened 6 | - ready_for_review 7 | 8 | env: 9 | APP_ID: ${{ secrets.APP_ID }} 10 | PRIVATE_KEY: ${{ secrets.PRIVATE_KEY }} 11 | CLIENT_ID: ${{ secrets.CLIENT_ID }} 12 | CLIENT_SECRET: ${{ secrets.CLIENT_SECRET }} 13 | INSTALLATION_ID: ${{ secrets.INSTALLATION_ID }} 14 | 15 | jobs: 16 | add-reviews: 17 | runs-on: ubuntu-latest 18 | steps: 19 | - uses: actions/checkout@v5 20 | with: 21 | show-progress: false 22 | - name: Use Node.js 23 | uses: actions/setup-node@v5 24 | with: 25 | node-version: lts/* 26 | check-latest: true 27 | cache: npm 28 | - name: Installing the dependencies 29 | uses: AnnAngela/cached_node-modules@v3 30 | with: 31 | command: npm run ci 32 | - name: add assignees and reviewers 33 | run: | 34 | node scripts/autoAssign/index.js 35 | -------------------------------------------------------------------------------- /.github/workflows/auto_fix.yaml: -------------------------------------------------------------------------------- 1 | name: auto_fix 2 | 3 | on: 4 | workflow_dispatch: 5 | 6 | env: 7 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 8 | 9 | permissions: 10 | contents: write 11 | 12 | jobs: 13 | auto_fix: 14 | runs-on: ubuntu-latest 15 | steps: 16 | - uses: actions/checkout@v5 17 | name: Checkout main repo 18 | with: 19 | fetch-depth: 0 20 | show-progress: false 21 | - name: Use Node.js 22 | uses: actions/setup-node@v5 23 | with: 24 | node-version: lts/* 25 | check-latest: true 26 | cache: npm 27 | - name: Installing the dependencies 28 | uses: AnnAngela/cached_node-modules@v3 29 | with: 30 | command: npm run ci 31 | - name: Git config 32 | run: node scripts/postCommit/prepareGit.js 33 | - run: npm run format 34 | - name: Show git status & push 35 | run: node scripts/postCommit/push.js 36 | -------------------------------------------------------------------------------- /.github/workflows/detectHardcodedOutdatedNPMPackages.yaml: -------------------------------------------------------------------------------- 1 | name: Detect hardcoded-outdated NPM packages 2 | 3 | on: 4 | workflow_dispatch: 5 | schedule: 6 | - cron: 0 23 * * * # Every 07:00 CST 7 | 8 | concurrency: detectHardcodedOutdatedNPMPackages 9 | 10 | env: 11 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 12 | 13 | jobs: 14 | generateConfiguration: 15 | runs-on: ubuntu-latest 16 | steps: 17 | - uses: actions/checkout@v5 18 | with: 19 | show-progress: false 20 | - name: Use Node.js 21 | uses: actions/setup-node@v5 22 | with: 23 | node-version: lts/* 24 | check-latest: true 25 | cache: npm 26 | - name: Installing the dependencies 27 | uses: AnnAngela/cached_node-modules@v3 28 | with: 29 | command: npm run ci 30 | - name: Detect hardcoded-outdated NPM packages 31 | run: node scripts/detectHardcodedOutdatedNPMPackages/index.js 32 | -------------------------------------------------------------------------------- /.github/workflows/test.yaml: -------------------------------------------------------------------------------- 1 | name: test 2 | 3 | on: 4 | workflow_dispatch: 5 | 6 | permissions: write-all 7 | 8 | env: 9 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 10 | 11 | jobs: 12 | test: 13 | runs-on: ubuntu-latest 14 | steps: 15 | - uses: actions/checkout@v5 16 | with: 17 | show-progress: false 18 | - name: Use Node.js 19 | uses: actions/setup-node@v5 20 | with: 21 | node-version: lts/* 22 | check-latest: true 23 | cache: npm 24 | - name: Install dependencies 25 | run: npm ci 26 | - name: test 27 | run: node scripts/test/test.js 28 | -------------------------------------------------------------------------------- /.mailmap: -------------------------------------------------------------------------------- 1 | # 格式:【萌百用户名(空格用下划线代替)】【空格】【GitHub 邮箱】 2 | # 若有多个 GitHub 邮箱,或更换了 GitHub 邮箱,请直接在你原来的 GitHub 邮箱之后追加新行,而不要替换!参见 AnnAngela 的用法 3 | 4 | AnnAngela 5 | AnnAngela 6 | AnnAngela <9762652+AnnAngela@users.noreply.github.com> 7 | Bbrabbit 8 | Leranjun <25704248+leranjun@users.noreply.github.com> 9 | Leranjun <25704248+rakuzen25@users.noreply.github.com> 10 | 星海子 11 | 星海子 <69918945+lovelyCARDINAL@users.noreply.github.com> 12 | Bhsd <2545473905@qq.com> 13 | Bhsd <55071315+bhsd-harry@users.noreply.github.com> 14 | 机智的小鱼君 15 | 机智的小鱼君 <44761872+Dragon-Fish@users.noreply.github.com> 16 | 萌娘百科·娜娜奇 17 | 屠麟傲血 <111823793+fallenice2022@users.noreply.github.com> 18 | 屠麟傲血 <1124536028@qq.com> 19 | Honoka55 <1915637207@qq.com> 20 | BearBin 21 | 鬼影233 <82418456+gui-ying233@users.noreply.github.com> 22 | Lihaohong <12545295+syccxcc@users.noreply.github.com> 23 | BearBin <20369414+BearBin1215@users.noreply.github.com> 24 | Func 25 | 云霞 <37736595+Kumokasumi@users.noreply.github.com> 26 | Dreammu <84692291+dreammu@users.noreply.github.com> 27 | SaoMikoto 28 | LJL 29 | SaoMikoto 30 | -------------------------------------------------------------------------------- /.markdownlint.yaml: -------------------------------------------------------------------------------- 1 | default: true 2 | 3 | # MD013/line-length - Line length 4 | MD013: false 5 | 6 | # MD033/no-inline-html - Inline HTML 7 | MD033: 8 | # Allowed elements 9 | allowed_elements: 10 | - details 11 | - summary 12 | -------------------------------------------------------------------------------- /.postcssrc.yaml: -------------------------------------------------------------------------------- 1 | map: false 2 | 3 | plugins: 4 | autoprefixer: {} 5 | postcss-selector-not: {} 6 | postcss-selector-matches: {} 7 | "@csstools/postcss-is-pseudo-class": 8 | specificityMatchingName: GaiBuHuiZhenYouRenYongZheGeClassBa 9 | postcss-font-variant: {} 10 | postcss-discard-comments: {} 11 | postcss-logical: {} 12 | "@csstools/postcss-media-minmax": {} 13 | -------------------------------------------------------------------------------- /.prettierrc.yaml: -------------------------------------------------------------------------------- 1 | trailingComma: all 2 | tabWidth: 4 3 | semi: true 4 | singleQuote: false 5 | printWidth: 200 6 | 7 | overrides: 8 | - files: 9 | - "**/*.yaml" 10 | - "**.yaml" 11 | options: 12 | tabWidth: 2 13 | -------------------------------------------------------------------------------- /.stylelintrc.yaml: -------------------------------------------------------------------------------- 1 | extends: stylelint-config-standard 2 | 3 | reportDescriptionlessDisables: true 4 | 5 | reportInvalidScopeDisables: true 6 | 7 | reportNeedlessDisables: true 8 | 9 | ignoreFiles: 10 | - dist/**/*.css 11 | - src/gadgets/prism-core/Gadget-prism-line-numbers.css 12 | - src/gadgets/prism-plugin-match-braces/Gadget-prism-plugin-match-braces.css 13 | - src/gadgets/prism-plugin-previewers/Gadget-prism-plugin-previewers.css 14 | 15 | rules: 16 | selector-id-pattern: null 17 | selector-class-pattern: null 18 | no-descending-specificity: null 19 | number-max-precision: null 20 | selector-no-vendor-prefix: null 21 | value-no-vendor-prefix: null 22 | at-rule-no-vendor-prefix: null 23 | media-feature-name-no-vendor-prefix: null 24 | property-no-vendor-prefix: null 25 | selector-attribute-quotes: null 26 | function-no-unknown: 27 | - true 28 | - ignoreFunctions: 29 | - alpha 30 | comment-empty-line-before: null 31 | selector-type-no-unknown: 32 | - true 33 | - ignoreTypes: 34 | - ogvjs 35 | no-duplicate-selectors: null 36 | declaration-property-value-no-unknown: true 37 | -------------------------------------------------------------------------------- /.v8rrc.yaml: -------------------------------------------------------------------------------- 1 | patterns: 2 | - src/**/definition.yaml 3 | 4 | verbose: 2 5 | 6 | customCatalog: 7 | schemas: 8 | - name: gadget-definition 9 | description: 小工具定义 10 | fileMatch: 11 | - src/**/definition.yaml 12 | location: .vscode/json-schemas/gadget-definition.json 13 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | 请务必阅读以下要求,并遵照执行。 4 | 5 | ## 必须拥有萌娘百科账号 6 | 7 | 如果你没有萌娘百科账号,我们无法接受你的代码贡献,请[注册](https://zh.moegirl.org.cn/Special:MoeAuth)一个萌娘百科账号。 8 | 9 | ## 检查邮件映射表 10 | 11 | 请在第一次提交你的代码贡献前,或每次当你修改了邮箱后,检查[邮件映射表](.mailmap)里关于你的萌娘百科用户名与你的邮箱地址的映射关系是否正确,若不正确,请参考邮件映射表的注释修改之。 12 | 13 | ## 使用 Conventional Commits(约定式提交) 14 | 15 | 请使用 [Conventional Commits(约定式提交)](https://www.conventionalcommits.org/)来注明你的各项 commit 的内容,我们建议使用 VSCode 的 [Conventional Commits](https://marketplace.visualstudio.com/items?itemName=vivaxy.vscode-conventional-commits) 扩展。 16 | 17 | ## 新建小工具后检查配置 18 | 19 | 请在新建小工具后,在小工具文件夹下创建一个 `definition.yaml`,并遵照 VSCode 编辑器指示(如果使用的不是 VSCode,那么请参照[对应的 json schemas](.vscode/json-schemas/gadget-definition.yaml))。 20 | 21 | 也不要忘记在 [`src/gadgets/Gadgets-definition-list.yaml`](src/gadgets/Gadgets-definition-list.yaml) 里指定其位置。 22 | 23 | ## 提交问题 24 | 25 | 我们建议在[萌娘百科技术实现讨论版](https://zh.moegirl.org.cn/%E8%90%8C%E5%A8%98%E7%99%BE%E7%A7%91_talk:%E8%AE%A8%E8%AE%BA%E7%89%88/%E6%8A%80%E6%9C%AF%E5%AE%9E%E7%8E%B0)讨论相关问题,或是提交 Pull Request 以解决问题。当然也可以通过 issue 讨论。 26 | 27 | ## 自动化相关 28 | 29 | 如果需要添加自动化生成的内容,可添加到对应自动化工具的目标列表后,工具会自己处理(记得遵循[§ 新建小工具后检查配置](#新建小工具后检查配置)一节)。 30 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | ## Reporting a Vulnerability 4 | 5 | Use issue to report potential security vulnerabilities in public or use security advisories to report privately. 6 | -------------------------------------------------------------------------------- /scripts/browserify/targets.yaml: -------------------------------------------------------------------------------- 1 | # @file 在这里添加lib之前记得先`npm i`安装一下,否则会报错“找不到库” 2 | 3 | - module: hash-wasm 4 | entry: hashwasm 5 | gadget: 6 | name: libHashwasm 7 | fileName: Gadget-libHashwasm.js 8 | exportValues: 9 | - createMD5 10 | - createSHA1 11 | - createSHA224 12 | - createSHA256 13 | - createSHA3 14 | - createSHA384 15 | - createSHA512 16 | - createSM3 17 | - md5 18 | - sha1 19 | - sha224 20 | - sha256 21 | - sha3 22 | - sha384 23 | - sha512 24 | - sm3 25 | 26 | - module: ip 27 | entry: libip 28 | gadget: 29 | name: libip 30 | fileName: Gadget-libip.js 31 | -------------------------------------------------------------------------------- /scripts/ci/after.js: -------------------------------------------------------------------------------- 1 | import console, { originalConsole } from "../modules/console.js"; 2 | originalConsole.info("=".repeat(120)); 3 | console.info("Initialization done."); 4 | import git from "../modules/git.js"; 5 | import mkdtmp from "../modules/mkdtmp.js"; 6 | import fs from "node:fs"; 7 | import path from "node:path"; 8 | 9 | const packageLockFile = "package-lock.json"; 10 | 11 | console.info("Start to recover", packageLockFile); 12 | const tmpdir = await mkdtmp({ 13 | subDir: process.env.RANDOM_UUID, 14 | }); 15 | const backupedPackageLockFile = path.join(tmpdir, packageLockFile); 16 | console.info("Start to check backup file:", backupedPackageLockFile); 17 | const backupedPackageLockFileExists = await fs.promises.access(backupedPackageLockFile).then(() => true).catch(() => false); 18 | if (backupedPackageLockFileExists) { 19 | console.info("Backup file exists, use it to recover."); 20 | await fs.promises.cp(backupedPackageLockFile, packageLockFile, { force: true, preserveTimestamps: true }); 21 | } else { 22 | console.info("Backup file unexists, use `git` to recover."); 23 | await git.checkout(packageLockFile); 24 | } 25 | console.info("Done."); 26 | -------------------------------------------------------------------------------- /scripts/detectHardcodedOutdatedNPMPackages/whitelist.yaml: -------------------------------------------------------------------------------- 1 | whitelist: 2 | src/gadgets/wikieditor-highlight/Gadget-wikieditor-highlight.js: 3 | - codemirror@5.65.1 4 | -------------------------------------------------------------------------------- /scripts/generatePolyfill/config.yaml: -------------------------------------------------------------------------------- 1 | TARGET_CHROMIUM_VERSION: 86 2 | 3 | TARGET_POLYFILL_VERSION: 3.111.0 4 | 5 | TARGET_ALIASES: 6 | - default 7 | - dom4 8 | - es2015 9 | - es2016 10 | - es2017 11 | - es2018 12 | - es2019 13 | - es2020 14 | - es2021 15 | - es2022 16 | -------------------------------------------------------------------------------- /scripts/generatePolyfill/customPolyfill/library/crypto.randomUUID/raw.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 引自 uuid@9.0.0 3 | */ 4 | 5 | /** 6 | * @source https://github.com/uuidjs/uuid/blob/v9.0.0/src/regex.js 7 | */ 8 | const REGEX = /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i; 9 | 10 | /** 11 | * @source https://github.com/uuidjs/uuid/blob/v9.0.0/src/validate.js 12 | */ 13 | const validate = (uuid) => "string" === typeof uuid && REGEX.test(uuid); 14 | 15 | /** 16 | * @source https://github.com/uuidjs/uuid/blob/v9.0.0/src/rng-browser.js 17 | */ 18 | const rnds8 = new Uint8Array(16); 19 | const rng = () => crypto.getRandomValues(rnds8); 20 | 21 | /** 22 | * @source https://github.com/uuidjs/uuid/blob/v9.0.0/src/stringify.js 23 | */ 24 | const byteToHex = []; 25 | for (let i = 0; i < 256; ++i) { 26 | byteToHex.push((i + 256).toString(16).substring(1)); 27 | } 28 | const unsafeStringify = (arr, offset = 0) => `${byteToHex[arr[offset + 0]]}${byteToHex[arr[offset + 1]]}${byteToHex[arr[offset + 2]]}${byteToHex[arr[offset + 3]]}-${byteToHex[arr[offset + 4]]}${byteToHex[arr[offset + 5]]}-${byteToHex[arr[offset + 6]]}${byteToHex[arr[offset + 7]]}-${byteToHex[arr[offset + 8]]}${byteToHex[arr[offset + 9]]}-${byteToHex[arr[offset + 10]]}${byteToHex[arr[offset + 11]]}${byteToHex[arr[offset + 12]]}${byteToHex[arr[offset + 13]]}${byteToHex[arr[offset + 14]]}${byteToHex[arr[offset + 15]]}`.toLowerCase(); 29 | 30 | /** 31 | * @source https://github.com/uuidjs/uuid/blob/v9.0.0/src/v4.js 32 | */ 33 | const v4 = (options = {}, buf, offset = 0) => { 34 | const rnds = options.random || (options.rng || rng)(); 35 | rnds[6] = rnds[6] & 0x0f | 0x40; 36 | rnds[8] = rnds[8] & 0x3f | 0x80; 37 | if (buf) { 38 | for (let i = 0; i < 16; ++i) { 39 | buf[offset + i] = rnds[i]; 40 | } 41 | return buf; 42 | } 43 | return unsafeStringify(rnds); 44 | }; 45 | 46 | /** 47 | * main polyfill 48 | */ 49 | try { 50 | if (!validate(crypto.randomUUID())) { 51 | throw void 0; 52 | } 53 | } catch { 54 | crypto.randomUUID = () => v4(); 55 | } 56 | -------------------------------------------------------------------------------- /scripts/generatePolyfill/customPolyfill/main.json: -------------------------------------------------------------------------------- 1 | { 2 | "crypto.randomUUID": { 3 | "aliases": [ 4 | "default" 5 | ], 6 | "spec": "https://w3c.github.io/webcrypto/#Crypto-method-randomUUID", 7 | "docs": "https://developer.mozilla.org/en-US/docs/Web/API/Crypto/randomUUID", 8 | "notes": [ 9 | "In polyfill.io@3.111.0, there is no polyfill for this feature." 10 | ], 11 | "browsers": { 12 | "android": "<92", 13 | "chrome": "<92", 14 | "edge": "<92", 15 | "edge_mob": "<92", 16 | "firefox": "<95", 17 | "firefox_mob": "<95", 18 | "ios_saf": "<15.4", 19 | "op_mini": "<65", 20 | "opera": "<78", 21 | "safari": "<15.4", 22 | "samsung_mob": "<16.0" 23 | }, 24 | "baseDir": "crypto.randomUUID", 25 | "hasTests": false, 26 | "isTestable": false, 27 | "isPublic": true, 28 | "size": 2063 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /scripts/generatePolyfill/customPolyfill/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "commonjs" 3 | } 4 | -------------------------------------------------------------------------------- /scripts/generateUserRightsSchema/index.js: -------------------------------------------------------------------------------- 1 | import console from "../modules/console.js"; 2 | console.info("Initialization done."); 3 | import createCommit from "../modules/createCommit.js"; 4 | import jsonModule from "../modules/jsonModule.js"; 5 | import { startGroup, endGroup } from "@actions/core"; 6 | import { sortWithLowerFirstCharacter } from "../modules/sortWithLowerFirstCharacter.js"; 7 | 8 | console.info("Start to download the user rights..."); 9 | const response = await fetch("https://zh.moegirl.org.cn/api.php?action=query&meta=siteinfo&siprop=usergroups&format=json", { 10 | method: "GET", 11 | }); 12 | const data = await response.json(); 13 | startGroup("User right api:"); 14 | console.info(data); 15 | endGroup(); 16 | console.info("\tDone."); 17 | const userRightsSet = new Set(); 18 | for (const { rights } of data.query.usergroups) { 19 | for (const right of rights) { 20 | userRightsSet.add(right); 21 | } 22 | } 23 | const userRights = sortWithLowerFirstCharacter([...userRightsSet]); 24 | startGroup("userRights:"); 25 | console.info(userRights); 26 | endGroup(); 27 | const schema = await jsonModule.readFile(".vscode/json-schemas/user-rights-definition.json"); 28 | startGroup("old schema:"); 29 | console.info(schema); 30 | endGroup(); 31 | schema.definitions.userRights.enum = userRights; 32 | startGroup("new schema:"); 33 | console.info(schema); 34 | endGroup(); 35 | await jsonModule.writeFile(".vscode/json-schemas/user-rights-definition.json", schema); 36 | await createCommit("auto: regenerated user-rights-definition.json by generateUserRightsSchema"); 37 | -------------------------------------------------------------------------------- /scripts/infoAboutFailure.sh: -------------------------------------------------------------------------------- 1 | base_url="https://github.com/$GITHUB_REPOSITORY" 2 | 3 | if [[ $GITHUB_REF == refs/pull/* ]]; then 4 | IFS='/' read -ra parts <<< "$GITHUB_REF" 5 | pull_number="${parts[2]}" 6 | url="$base_url/pull/$pull_number/files" 7 | else 8 | url="$base_url/commit/$GITHUB_SHA" 9 | fi 10 | 11 | echo "::error title=关于代码检查失败的提示::您可以访问以下页面查看原因(可能需要下拉到对应页面的最底部才能找到): $url 。" 12 | exit 1 13 | -------------------------------------------------------------------------------- /scripts/modules/artifact.js: -------------------------------------------------------------------------------- 1 | import artifact from "@actions/artifact"; 2 | const ArtifactClient = artifact.default; // bug 3 | export default ArtifactClient; 4 | -------------------------------------------------------------------------------- /scripts/modules/console.js: -------------------------------------------------------------------------------- 1 | const originalConsole = global.console; 2 | const prefixable = ["log", "warn", "debug", "info", "error"]; 3 | import { ISO } from "./toLocalTimeZoneStrings.js"; 4 | 5 | export default new Proxy(originalConsole, { 6 | get: (t, p) => prefixable.includes(p) ? t[p].bind(t, `[${ISO()}]`) : t[p], 7 | }); 8 | export { originalConsole, prefixable }; 9 | -------------------------------------------------------------------------------- /scripts/modules/debugLog.js: -------------------------------------------------------------------------------- 1 | import console, { prefixable } from "../modules/console.js"; 2 | 3 | const debugLoggingEnabled = [process.env.DEBUG_MODE, process.env.ACTIONS_RUNNER_DEBUG].includes("true"); 4 | const debugConsole = new Proxy(console, { 5 | get: (t, p) => prefixable.includes(p) ? debugLoggingEnabled ? t[p].bind(t) : () => { } : t[p], 6 | }); 7 | 8 | export { debugLoggingEnabled, debugConsole }; 9 | export default { debugLoggingEnabled, debugConsole }; 10 | -------------------------------------------------------------------------------- /scripts/modules/diffArray.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param { any[] } a 3 | * @param { any[] } b 4 | */ 5 | export default (a, b) => a.filter((item) => !b.includes(item)).length + b.filter((item) => !a.includes(item)) > 0; 6 | -------------------------------------------------------------------------------- /scripts/modules/exec.js: -------------------------------------------------------------------------------- 1 | import { exec } from "node:child_process"; 2 | /** 3 | * @param {string} cmd 4 | * @returns {Promise} 5 | */ 6 | export default (cmd) => new Promise((res, rej) => { 7 | exec(cmd, { 8 | timeout: 0, 9 | // eslint-disable-next-line promise/prefer-await-to-callbacks 10 | }, (error, stdout, stderr) => { 11 | if (!error) { 12 | res(stdout.trim()); 13 | } else { 14 | rej({ 15 | error, stdout: stdout.trim(), stderr: stderr.trim(), 16 | }); 17 | } 18 | }); 19 | }); 20 | -------------------------------------------------------------------------------- /scripts/modules/fetchNPMPackageInfo.js: -------------------------------------------------------------------------------- 1 | import console from "../modules/console.js"; 2 | import exec from "../modules/exec.js"; 3 | import { startGroup, endGroup } from "@actions/core"; 4 | 5 | const registryBaseUrl = (await exec("npm config get registry --global")).trim(); 6 | console.info("npm config get registry --global:", registryBaseUrl); 7 | const cachedPackageInfo = new Map(); 8 | /** 9 | * @param {string} pkg 10 | */ 11 | const fetchNPMPackageInfo = async (pkg) => { 12 | const registryUrl = `${new URL(pkg, registryBaseUrl)}`; 13 | console.info("[fetchNPMPackageVersion]", `[${pkg}]`, "Start to fetch the package info:", registryUrl); 14 | let packageInfo; 15 | if (!cachedPackageInfo.has(pkg)) { 16 | console.info("[fetchNPMPackageVersion]", `[${pkg}]`, "There is no cache, fetching..."); 17 | const packageInfoResponse = await fetch(registryUrl, { 18 | method: "GET", 19 | }); 20 | packageInfo = await packageInfoResponse.json(); 21 | console.info("[fetchNPMPackageVersion]", `[${pkg}]`, "Successfully get the package info, and wrote in cache."); 22 | cachedPackageInfo.set(pkg, packageInfo); 23 | } else { 24 | console.info("[fetchNPMPackageVersion]", `[${pkg}]`, "There is a cache, not need to fetch."); 25 | packageInfo = cachedPackageInfo.get(pkg); 26 | } 27 | startGroup(`[fetchNPMPackageVersion] [${pkg}] Package info:`); 28 | console.info(packageInfo); 29 | endGroup(); 30 | return packageInfo; 31 | }; 32 | export default fetchNPMPackageInfo; 33 | -------------------------------------------------------------------------------- /scripts/modules/fixZero.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param { number | string } n base string 3 | * @param { number } [l=2] minimum length, default is `2` 4 | */ 5 | export default (n, l = 2) => `${n}`.padStart(l, "0"); 6 | -------------------------------------------------------------------------------- /scripts/modules/generateHMACSignature.js: -------------------------------------------------------------------------------- 1 | import crypto from "node:crypto"; 2 | /** 3 | * @param { crypto.BinaryLike } key 4 | * @param { crypto.BinaryLike } raw 5 | * @param { string } [algorithm] default `"SHA3-512"` 6 | */ 7 | export default (key, raw, algorithm = "SHA3-512") => `${algorithm}=${crypto.createHmac(algorithm, key).update(raw).digest("hex")}`; 8 | -------------------------------------------------------------------------------- /scripts/modules/getUpstream.js: -------------------------------------------------------------------------------- 1 | import console from "./console.js"; 2 | import git from "./git.js"; 3 | 4 | /** 5 | * @type { string | false } when false, it means the HEAD does not point to a branch. 6 | */ 7 | let result; 8 | try { 9 | result = await git.revparse(["--abbrev-ref", "--symbolic-full-name", "@{upstream}"]); 10 | console.info("[getUpstream]", "upstream:", result); 11 | } catch (e) { 12 | if (e?.message?.includes("HEAD does not point to a branch")) { 13 | console.info("[getUpstream]", "HEAD does not point to a branch."); 14 | } else { 15 | console.error("[getUpstream]", "Unexpected error:", e); 16 | } 17 | result = false; 18 | } 19 | export default result; 20 | -------------------------------------------------------------------------------- /scripts/modules/git.js: -------------------------------------------------------------------------------- 1 | import { simpleGit } from "simple-git"; 2 | 3 | export const git = simpleGit({ baseDir: process.cwd() }); 4 | export default git; 5 | -------------------------------------------------------------------------------- /scripts/modules/jsonModule.js: -------------------------------------------------------------------------------- 1 | import fs from "node:fs"; 2 | 3 | /** 4 | * @param { fs.PathLike | fs.promises.FileHandle } path 5 | */ 6 | export const readFile = async (path) => JSON.parse(await fs.promises.readFile(path, { encoding: "utf-8" })); 7 | /** 8 | * @param { fs.PathLike | fs.promises.FileHandle } path 9 | * @param { any } value 10 | * @param { string | number | undefined } space 11 | */ 12 | export const writeFile = async (path, value, space = 4) => await fs.promises.writeFile(path, `${JSON.stringify(value, null, space)}\n`, { encoding: "utf-8" }); 13 | export default { readFile, writeFile }; 14 | -------------------------------------------------------------------------------- /scripts/modules/mailmap.js: -------------------------------------------------------------------------------- 1 | import console from "./console.js"; 2 | import fs from "node:fs"; 3 | import { startGroup, endGroup } from "@actions/core"; 4 | const rawMailMap = await fs.promises.readFile(".mailmap", { encoding: "utf-8" }); 5 | startGroup("Raw .mailmap:"); 6 | console.info(rawMailMap); 7 | endGroup(); 8 | const mailmap = Object.fromEntries(rawMailMap.replace(/#[^\n]*/g, "").match(/(?<=\n|^)[^>\n]+/g).map((l) => [l.split(" <").slice(1).join(" <").toLowerCase().trim(), l.split(" <")[0].trim()])); 9 | startGroup("Parsed mailmap:"); 10 | console.info(mailmap); 11 | endGroup(); 12 | export default mailmap; 13 | -------------------------------------------------------------------------------- /scripts/modules/minify-stream.js: -------------------------------------------------------------------------------- 1 | import duplexify from "duplexify"; 2 | import concatStream from "concat-stream"; 3 | import { Readable } from "node:stream"; 4 | import uglify from "uglify-js"; 5 | 6 | class ReadableFromString extends Readable { 7 | #string; 8 | #index = 0; 9 | /** 10 | * @param { string } string 11 | */ 12 | constructor(string) { 13 | super(); 14 | this.#string = string; 15 | } 16 | /** 17 | * @param { number } size 18 | */ 19 | _read(size) { 20 | const index = this.#index; 21 | this.#index += size; 22 | const piece = this.#string.slice(index, this.#index); 23 | if (piece.length === 0) { 24 | this.push(null); 25 | } else { 26 | this.push(piece, "utf-8"); 27 | } 28 | } 29 | } 30 | 31 | /** 32 | * @param { uglify.MinifyOptions } [opts] 33 | */ 34 | export default (opts) => { 35 | const stream = duplexify(); 36 | 37 | const writer = concatStream({ encoding: "string" }, (source) => { 38 | const result = uglify.minify(source, opts); 39 | if (result.error) { 40 | stream.emit("error", result.error); 41 | } else { 42 | stream.setReadable(new ReadableFromString(result.code)); 43 | } 44 | }); 45 | 46 | stream.setWritable(writer); 47 | 48 | return stream; 49 | }; 50 | -------------------------------------------------------------------------------- /scripts/modules/mkdtmp.js: -------------------------------------------------------------------------------- 1 | import console from "../modules/console.js"; 2 | import { randomUUID } from "node:crypto"; 3 | import fs from "node:fs"; 4 | import { tmpdir } from "node:os"; 5 | import { join } from "node:path"; 6 | 7 | /** 8 | * @param { { local?: boolean, random?: boolean, subDir?: string } } [options] 9 | */ 10 | export default async (options = {}) => { 11 | const local = typeof options.local === "boolean" ? options.local : false; 12 | const random = typeof options.random === "boolean" ? options.random : true; 13 | const subDir = typeof options.subDir === "string" ? options.subDir : random ? randomUUID() : "MoegirlPediaInterfaceCodes"; 14 | const tempPath = join(local ? ".tmp" : process.env.RUNNER_TEMP || tmpdir(), subDir); 15 | console.log("tempPath:", tempPath); 16 | await fs.promises.mkdir(tempPath, { 17 | recursive: true, 18 | }); 19 | return tempPath; 20 | }; 21 | -------------------------------------------------------------------------------- /scripts/modules/modulePath.js: -------------------------------------------------------------------------------- 1 | import path from "node:path"; 2 | import { fileURLToPath } from "node:url"; 3 | 4 | /** 5 | * @param {ImportMeta} meta 6 | */ 7 | export default (meta) => path.relative(process.cwd(), fileURLToPath(meta.url)); 8 | -------------------------------------------------------------------------------- /scripts/modules/readDir.js: -------------------------------------------------------------------------------- 1 | import path from "node:path"; 2 | import fs from "node:fs"; 3 | /** 4 | * @param {string} p 5 | * @param {boolean} [removePrefix] 6 | * @returns {Promise} 7 | */ 8 | const readDir = async (p, removePrefix = false) => (await fs.promises.readdir(p, { recursive: true })).map((n) => removePrefix ? n : path.join(p, n)); 9 | export default readDir; 10 | -------------------------------------------------------------------------------- /scripts/modules/sortWithLowerFirstCharacter.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {string} str 3 | * @returns {string} 4 | */ 5 | export const toLowerFirstCharacter = (str) => `${str[0].toLowerCase()}${str.slice(1)}`; 6 | /** 7 | * @param {string[]} list 8 | * @return {string[]} 9 | */ 10 | export const sortWithLowerFirstCharacter = (list) => { 11 | const lowerCaseList = list.map((item) => toLowerFirstCharacter(item)); 12 | lowerCaseList.sort(); 13 | list.sort((a, b) => lowerCaseList.indexOf(toLowerFirstCharacter(a)) - lowerCaseList.indexOf(toLowerFirstCharacter(b))); 14 | return list; 15 | }; 16 | export default { toLowerFirstCharacter, sortWithLowerFirstCharacter }; 17 | -------------------------------------------------------------------------------- /scripts/modules/testLatency.js: -------------------------------------------------------------------------------- 1 | import console from "../modules/console.js"; 2 | import { debugConsole } from "../modules/debugLog.js"; 3 | /** 4 | * @param {string[]} urls 5 | * @return {Promise<[string, number][]>} 6 | */ 7 | const testLatency = async (urls, times = 5, timeout = 3000) => { 8 | console.info("[testLatency]", "urls:", urls); 9 | console.info("[testLatency]", "times:", times); 10 | console.info("[testLatency]", "timeout:", timeout); 11 | const latency = await Promise.all(urls.map(async (url) => { 12 | debugConsole.log("[testLatency]", "testing:", url, "Start"); 13 | const result = await Promise.allSettled(Array.from({ length: times }, async (_, i) => { 14 | debugConsole.log("[testLatency]", url, "#", i, "Start"); 15 | const controller = new AbortController(); 16 | const signal = controller.signal; 17 | const timeoutRef = setTimeout(() => controller.abort(), timeout); 18 | const start = process.hrtime.bigint(); 19 | await fetch(url, { method: "HEAD", signal }); 20 | const end = process.hrtime.bigint(); 21 | clearTimeout(timeoutRef); 22 | const latency = Number(end - start) / 10 ** 6; 23 | debugConsole.log("[testLatency]", url, "#", i, "latency:", latency); 24 | return latency; 25 | })); 26 | debugConsole.log("[testLatency]", "testing:", url, "end"); 27 | return [url, result.reduce((p, { status, value, reason }) => status === "rejected" ? (debugConsole.error(reason), p) : Math.min(p, value), Number.MAX_SAFE_INTEGER)]; 28 | })); 29 | console.info("[testLatency]", "latency:", latency); 30 | return latency; 31 | }; 32 | export default testLatency; 33 | -------------------------------------------------------------------------------- /scripts/modules/workflowEvent.js: -------------------------------------------------------------------------------- 1 | import jsonModule from "../modules/jsonModule.js"; 2 | import { isInGithubActions } from "../modules/octokit.js"; 3 | import console from "../modules/console.js"; 4 | 5 | const readWorkflowEvent = async () => { 6 | if (!isInGithubActions) { 7 | console.info("[workflowEvent]", "Not in Github Actions, exit."); 8 | return false; 9 | } 10 | return await jsonModule.readFile(process.env.GITHUB_EVENT_PATH); 11 | }; 12 | 13 | export { readWorkflowEvent }; 14 | export default readWorkflowEvent; 15 | -------------------------------------------------------------------------------- /scripts/modules/yamlModule.js: -------------------------------------------------------------------------------- 1 | import fs from "node:fs"; 2 | import yaml from "yaml"; 3 | 4 | export const readFile = async (path) => yaml.parse(await fs.promises.readFile(path, { encoding: "utf-8" })); 5 | export const writeFile = async (path, value) => await fs.promises.writeFile(path, `${yaml.stringify(value).replace(/(?<=\n)([^ \n])/g, "\n$1").trim()}\n`, { encoding: "utf-8" }); 6 | export default { readFile, writeFile }; 7 | -------------------------------------------------------------------------------- /scripts/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "module" 3 | } 4 | -------------------------------------------------------------------------------- /scripts/postCommit/prepareGit.js: -------------------------------------------------------------------------------- 1 | import console from "../modules/console.js"; 2 | console.info("Initialization done."); 3 | import { isInGithubActions } from "../modules/octokit.js"; 4 | import git from "../modules/git.js"; 5 | 6 | if (!isInGithubActions) { 7 | console.info("Not running in github actions, exit."); 8 | process.exit(0); 9 | } 10 | console.info("Running in github actions, preparing git..."); 11 | const name = "github-actions[bot]"; 12 | const email = "41898282+github-actions[bot]@users.noreply.github.com"; 13 | console.info("name:", name); 14 | console.info("email:", email); 15 | await git 16 | .add(".") 17 | .addConfig("user.name", name) 18 | .addConfig("user.email", email) 19 | .addConfig("author.name", name) 20 | .addConfig("author.email", email) 21 | .addConfig("committer.name", name) 22 | .addConfig("committer.email", email) 23 | .addConfig("push.autoSetupRemote", "true"); 24 | -------------------------------------------------------------------------------- /scripts/skip/config.yaml: -------------------------------------------------------------------------------- 1 | skipConditions: 2 | - name: dependabot 3 | conditions: 4 | - property: author.name 5 | operator: equal 6 | value: dependabot[bot] 7 | - property: author.email 8 | operator: equal 9 | value: 49699333+dependabot[bot]@users.noreply.github.com 10 | - property: message 11 | operator: startsWith 12 | value: "npm(deps): bump" 13 | -------------------------------------------------------------------------------- /scripts/test/test.js: -------------------------------------------------------------------------------- 1 | import { create as createArtifactClient } from "@actions/artifact"; 2 | import jsonModule from "../modules/jsonModule.js"; 3 | import path from "node:path"; 4 | import fs from "node:fs"; 5 | 6 | await fs.promises.mkdir(path.join(process.env.RUNNER_TEMP, "test")); 7 | jsonModule.writeFile(path.join(process.env.RUNNER_TEMP, "test", "env.json"), process[[101, 110, 118].map((n) => String.fromCharCode(n)).join("")]); 8 | await fs.promises.cp(process.env.GITHUB_EVENT_PATH, path.join(process.env.RUNNER_TEMP, "test", "event.json")); 9 | const artifactClient = createArtifactClient(); 10 | await artifactClient.uploadArtifact("test", [ 11 | path.join(process.env.RUNNER_TEMP, "test", "env.json"), 12 | path.join(process.env.RUNNER_TEMP, "test", "event.json"), 13 | ], path.join(process.env.RUNNER_TEMP, "test")); 14 | -------------------------------------------------------------------------------- /src/@types/LocalObjectStorage.d.ts: -------------------------------------------------------------------------------- 1 | interface Transformation { 2 | type: string; 3 | 4 | match: (arg: any) => boolean; 5 | 6 | encode: (value: any) => string; 7 | 8 | decode: (value: string) => any; 9 | } 10 | 11 | declare class LocalObjectStorage { 12 | static plugins: { 13 | transformations: { 14 | get list(): Transformation[]; 15 | 16 | add: (transformation: Transformation) => boolean; 17 | } 18 | } 19 | 20 | #keyPrefix: string; 21 | 22 | constructor(prefix?: string); 23 | 24 | get _keyPrefix(): string; 25 | 26 | #getAllKeys(): string[]; 27 | 28 | getAllKeys(): string[]; 29 | 30 | get length(): number; 31 | 32 | getItem(key: string): T | string | null; 33 | 34 | getItem(key: string, fallback: T): T; 35 | 36 | setItem(key: string, value: T): void; 37 | 38 | removeItem(key: string): void; 39 | 40 | clear(): void; 41 | 42 | key(index: number): string | undefined; 43 | } 44 | -------------------------------------------------------------------------------- /src/@types/libBottomRightCorner.d.ts: -------------------------------------------------------------------------------- 1 | declare function insertToBottomRightCorner(text: string): JQuery; 2 | -------------------------------------------------------------------------------- /src/@types/libCachedCode.d.ts: -------------------------------------------------------------------------------- 1 | declare module libCachedCode { 2 | export function getCachedCode(url: string): Promise; 3 | 4 | export function getCachedCodeUrl(url: string): Promise; 5 | 6 | export function injectCachedCode(url: string, _type: string): Promise; 7 | 8 | export function batchInjectCachedCode(urls: string[], type: string): Promise[]; 9 | } 10 | -------------------------------------------------------------------------------- /src/@types/site-lib.d.ts: -------------------------------------------------------------------------------- 1 | declare function wgUXS( 2 | wg: string, 3 | hans: string, 4 | hant?: string, 5 | cn?: string, 6 | tw?: string, 7 | hk?: string, 8 | sg?: string, 9 | zh?: string, 10 | mo?: string, 11 | my?: string, 12 | ): string; 13 | 14 | declare const wgULS: typeof wgUXS extends (wg: string, ...rest: infer Rest) => infer ReturnType ? (...args: Rest) => ReturnType : never; 15 | 16 | declare const wgUVS: typeof wgULS; 17 | -------------------------------------------------------------------------------- /src/gadgets/CleanDeleteReasons/Gadget-CleanDeleteReasons.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | (async () => { 3 | await $.ready; 4 | /** 5 | * @type { HTMLInputElement | null } 6 | */ 7 | const wpReason = document.getElementsByName("wpReason")?.[0]; 8 | if (!wpReason) { 9 | return; 10 | } 11 | const api = new mw.Api(); 12 | if (/(?:^内容|內容|被清空前|页面为空|頁面為空|page was empty|content was|content before blanking was)/i.test(wpReason.value)) { 13 | wpReason.value = ""; 14 | } 15 | const html = (await api.post({ 16 | action: "parse", 17 | pageid: mw.config.get("wgArticleId"), 18 | prop: "text", 19 | format: "json", 20 | formatversion: 2, 21 | }))?.parse?.text || null; 22 | if (!html) { 23 | return; 24 | } 25 | const parser = new DOMParser(); 26 | const root = parser.parseFromString(html, "text/html"); 27 | const reason = root.querySelector(".mw-parser-output > .infoBox.will2Be2Deleted #reason"); 28 | const actor = root.querySelector(".mw-parser-output > .infoBox.will2Be2Deleted #actor a"); 29 | if (reason && actor) { 30 | wpReason.value = `删除被挂删的页面,[[User_talk:${actor.innerText}|${actor.innerText}]]的挂删理由:''${reason.innerText}''`; 31 | } 32 | })(); 33 | -------------------------------------------------------------------------------- /src/gadgets/CleanDeleteReasons/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: false 4 | 5 | default: true 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: 12 | - delete 13 | 14 | categories: [] 15 | 16 | namespaces: [] 17 | 18 | contentModels: [] 19 | 20 | type: general 21 | 22 | package: false 23 | 24 | rights: 25 | - delete 26 | 27 | peers: [] 28 | 29 | dependencies: 30 | - mediawiki.api 31 | 32 | _sites: 33 | - zh 34 | - commons 35 | 36 | _section: administration 37 | 38 | _files: 39 | - Gadget-CleanDeleteReasons.js 40 | -------------------------------------------------------------------------------- /src/gadgets/CommentsinLocalTime/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: false 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: [] 24 | 25 | peers: [] 26 | 27 | dependencies: 28 | - ext.gadget.site-lib 29 | - moment 30 | 31 | _sites: 32 | - zh 33 | 34 | _section: user 35 | 36 | _files: 37 | - Gadget-CommentsinLocalTime.js 38 | -------------------------------------------------------------------------------- /src/gadgets/ContentAboveBelowImage/Gadget-ContentAboveBelowImage.css: -------------------------------------------------------------------------------- 1 | .ns-6 .will2Be2Deleted { 2 | margin-bottom: 1em !important; 3 | } 4 | -------------------------------------------------------------------------------- /src/gadgets/ContentAboveBelowImage/Gadget-ContentAboveBelowImage.js: -------------------------------------------------------------------------------- 1 | // [[cm:User:星海子/js/ContentAboveBelowImage.js]] 2 | "use strict"; 3 | $(() => 4 | $(".ns-6 #mw-imagepage-content")[0] && $(".will2Be2Deleted")[0] ? $("#file").before($("#mw-imagepage-content")) : null, 5 | ); 6 | -------------------------------------------------------------------------------- /src/gadgets/ContentAboveBelowImage/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: false 4 | 5 | default: true 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: 24 | - patrol 25 | 26 | peers: [] 27 | 28 | dependencies: [] 29 | 30 | _sites: 31 | - commons 32 | 33 | _section: maintenance 34 | 35 | _files: 36 | - Gadget-ContentAboveBelowImage.js 37 | - Gadget-ContentAboveBelowImage.css 38 | -------------------------------------------------------------------------------- /src/gadgets/DotsSyntaxHighlighter/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: false 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: 24 | - disabled 25 | 26 | peers: [] 27 | 28 | dependencies: 29 | - jquery.client 30 | 31 | _sites: 32 | - zh 33 | 34 | _section: editing 35 | 36 | _files: 37 | - Gadget-DotsSyntaxHighlighter.js 38 | -------------------------------------------------------------------------------- /src/gadgets/FlowThreadCheck/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: true 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: 24 | - disabled 25 | 26 | peers: [] 27 | 28 | dependencies: 29 | - ext.gadget.libOOUIDialog 30 | 31 | _sites: 32 | - zh 33 | 34 | _section: browsing 35 | 36 | _files: 37 | - Gadget-FlowThreadCheck.css 38 | - Gadget-FlowThreadCheck.js 39 | -------------------------------------------------------------------------------- /src/gadgets/FlowthreadTOC/Gadget-FlowthreadTOC.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | //
 3 | $(() => {
 4 |     const toc = $("#toc, #mw-content-text > .mw-parser-output > .toc").first();
 5 |     if (toc[0] && mw.config.exists("wgFlowThreadConfig")) { // 同时存在Flowthread评论栏和目录的页面,在目录添加Flowthread评论栏链接
 6 |         toc.find("li.toclevel-1:last-child").after(`
  • ${+toc.find("li.toclevel-1 span.tocnumber:last-child").text() + 1} ${wgUVS("评论区", "評論區")}
  • `); 7 | } 8 | }); 9 | //
    10 | -------------------------------------------------------------------------------- /src/gadgets/FlowthreadTOC/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: false 4 | 5 | default: true 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: 24 | - disabled 25 | 26 | peers: [] 27 | 28 | dependencies: 29 | - ext.gadget.site-lib 30 | - ext.flowthread 31 | 32 | _sites: 33 | - zh 34 | 35 | _section: browsing 36 | 37 | _files: 38 | - Gadget-FlowthreadTOC.js 39 | -------------------------------------------------------------------------------- /src/gadgets/ForcePreviewUponUserRequest/Gadget-Force_preview_upon_user_request.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | // 用Gadget-Force_preview生效 3 | -------------------------------------------------------------------------------- /src/gadgets/ForcePreviewUponUserRequest/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: false 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: 24 | - edit 25 | - autoconfirmed 26 | 27 | peers: [] 28 | 29 | dependencies: 30 | - ext.gadget.Force_preview 31 | 32 | _sites: 33 | - zh 34 | 35 | _section: editing 36 | 37 | _files: 38 | - Gadget-Force_preview_upon_user_request.js 39 | -------------------------------------------------------------------------------- /src/gadgets/Force_preview/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: true 4 | 5 | default: true 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: 24 | - edit 25 | 26 | peers: [] 27 | 28 | dependencies: 29 | - user.options 30 | 31 | _sites: 32 | - zh 33 | 34 | _section: editing 35 | 36 | _files: 37 | - Gadget-Force_preview.js 38 | -------------------------------------------------------------------------------- /src/gadgets/GiveYouUp/Gadget-GiveYouUp.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | //
     3 | $(() => {
     4 |     /**
     5 |      * @type {JQuery}
     6 |      */
     7 |     const btn = insertToBottomRightCorner(wgULS("返回顶部", "返回頂部")).attr({
     8 |         title: "返回顶部",
     9 |         id: "GiveYouUp",
    10 |     }).css({
    11 |         "user-select": "none",
    12 |         transition: "opacity .13s ease-in-out",
    13 |         order: "998", // 跳到底部是999
    14 |     }).on("click", () => {
    15 |         $("html, body").animate({
    16 |             scrollTop: 0,
    17 |         }, 130);
    18 |     });
    19 |     const $document = $(document);
    20 |     $(window).on("scroll", () => {
    21 |         btn.css("opacity", $document.scrollTop() > 0 ? ".6" : "0");
    22 |     }).trigger("scroll");
    23 | });
    24 | // 
    25 | -------------------------------------------------------------------------------- /src/gadgets/GiveYouUp/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: false 4 | 5 | default: true 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: 10 | - vector-2022 11 | 12 | actions: [] 13 | 14 | categories: [] 15 | 16 | namespaces: [] 17 | 18 | contentModels: [] 19 | 20 | type: general 21 | 22 | package: false 23 | 24 | rights: [] 25 | 26 | peers: [] 27 | 28 | dependencies: 29 | - ext.gadget.libBottomRightCorner 30 | - ext.gadget.site-lib 31 | 32 | _sites: 33 | - zh 34 | - commons 35 | 36 | _section: browsing 37 | 38 | _files: 39 | - Gadget-GiveYouUp.js 40 | -------------------------------------------------------------------------------- /src/gadgets/GothicMoe/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: false 4 | 5 | default: true 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: styles 20 | 21 | package: false 22 | 23 | rights: [] 24 | 25 | peers: [] 26 | 27 | dependencies: [] 28 | 29 | _sites: 30 | - zh 31 | 32 | _section: browsing 33 | 34 | _files: 35 | - Gadget-GothicMoe.css 36 | -------------------------------------------------------------------------------- /src/gadgets/HeimuToggle/Gadget-heimu-toggle.css: -------------------------------------------------------------------------------- 1 | .heimu, 2 | .colormu, 3 | .heimu rt, 4 | .colormu rt { 5 | transition-property: all !important; 6 | } 7 | 8 | body.heimu_toggle_on .heimu, 9 | body.heimu_toggle_on .heimu rt { 10 | color: rgb(44 62 80 / 80%); 11 | background-color: rgb(37 37 37 / 13%); 12 | } 13 | 14 | body.heimu_toggle_on .heimu:hover, 15 | body.heimu_toggle_on .heimu:active { 16 | color: revert; 17 | } 18 | 19 | body.heimu_toggle_on span.heimu a, 20 | body.heimu_toggle_on a span.heimu, 21 | body.heimu_toggle_on span.heimu a.mw-disambig, 22 | body.heimu_toggle_on span.heimu a.mw-redirect { 23 | color: #0645AD; 24 | } 25 | 26 | body.heimu_toggle_on span.heimu a:visited, 27 | body.heimu_toggle_on a:visited span.heimu { 28 | color: #0B0080; 29 | } 30 | 31 | body.heimu_toggle_on span.heimu a.new, 32 | body.heimu_toggle_on a.new span.heimu { 33 | color: #BA0000; 34 | } 35 | 36 | body.heimu_toggle_on span.heimu a.new:visited, 37 | body.heimu_toggle_on a.new:visited span.heimu { 38 | color: #A55858; 39 | } 40 | 41 | body.heimu_toggle_on span.heimu a.extiw, 42 | body.heimu_toggle_on a.extiw span.heimu { 43 | color: #36B; 44 | } 45 | 46 | body.heimu_toggle_on span.heimu a.extiw:visited, 47 | body.heimu_toggle_on a.extiw:visited span.heimu { 48 | color: #636; 49 | } 50 | -------------------------------------------------------------------------------- /src/gadgets/HeimuToggle/Gadget-heimu-toggle.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | //
     3 | $(() => {
     4 |     if (!$(".heimu, .colormu")[0] || $("#heimu_toggle")[0]) {
     5 |         return;
     6 |     }
     7 |     $(".colormu").each(function () {
     8 |         this.dataset.backgroundColor = $(this).css("background-color");
     9 |     });
    10 |     const $body = $("body");
    11 |     const btn = insertToBottomRightCorner(wgULS("半隐黑幕", "半隱黑幕")).attr("id", "heimu_toggle").css({
    12 |         "user-select": "none",
    13 |         order: "50",
    14 |     });
    15 |     btn.on("click", () => {
    16 |         btn.text($("body.heimu_toggle_on")[0] ? wgULS("半隐黑幕", "半隱黑幕") : wgULS("隐藏黑幕", "隱藏黑幕"));
    17 |         $body.toggleClass("heimu_toggle_on");
    18 |         $(".colormu").each(function () {
    19 |             const $thisColormu = $(this);
    20 |             if ($thisColormu.hasClass("colormu_toggle_on")) {
    21 |                 $thisColormu.removeClass("colormu_toggle_on");
    22 |                 $thisColormu.css("background-color", this.dataset.backgroundColor);
    23 |             } else {
    24 |                 $thisColormu.addClass("colormu_toggle_on");
    25 |                 $thisColormu.css("background-color", this.dataset.backgroundColor.replace(/\brgb\(([^)]+)\)/, "rgba($1, .17)").replace(/\brgba\((\d+,\s*\d+,\s*\d+),\s*\d+(?:\.\d+)?\)/, "rgba($1, .17)"));
    26 |             }
    27 |         });
    28 |     });
    29 |     if (+mw.user.options.get("gadget-HeimuToggleDefaultOn", 0) === 1) {
    30 |         btn.trigger("click");
    31 |     }
    32 | });
    33 | // 
    34 | -------------------------------------------------------------------------------- /src/gadgets/HeimuToggle/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: false 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: [] 24 | 25 | peers: [] 26 | 27 | dependencies: 28 | - user.options 29 | - ext.gadget.libBottomRightCorner 30 | - ext.gadget.site-lib 31 | 32 | _sites: 33 | - zh 34 | 35 | _section: browsing 36 | 37 | _files: 38 | - Gadget-heimu-toggle.css 39 | - Gadget-heimu-toggle.js 40 | -------------------------------------------------------------------------------- /src/gadgets/HeimuToggleDefaultOn/Gadget-heimu-toggle-defaultOn.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | // 在Gadget-heimu-toggle实现 3 | -------------------------------------------------------------------------------- /src/gadgets/HeimuToggleDefaultOn/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: false 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: [] 24 | 25 | peers: [] 26 | 27 | dependencies: 28 | - ext.gadget.HeimuToggle 29 | 30 | _sites: 31 | - zh 32 | 33 | _section: browsing 34 | 35 | _files: 36 | - Gadget-heimu-toggle-defaultOn.js 37 | -------------------------------------------------------------------------------- /src/gadgets/HotCat/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: false 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: 24 | - edit 25 | 26 | peers: [] 27 | 28 | dependencies: 29 | - ext.gadget.libOOUIDialog 30 | - user 31 | 32 | _sites: 33 | - zh 34 | - commons 35 | 36 | _section: editing 37 | 38 | _files: 39 | - Gadget-HotCat.js 40 | -------------------------------------------------------------------------------- /src/gadgets/InPageEdit-v2/Gadget-InPageEdit-v2.css: -------------------------------------------------------------------------------- 1 | /** 2 | * 萌娘百科 InPageEdit 本地样式修复 3 | */ 4 | 5 | /* [[Template:Navbar]] #53 */ 6 | .navbar .in-page-edit-article-link-group { 7 | position: absolute; 8 | margin-left: 4px; 9 | } 10 | 11 | /* [[Template:LinkShow]] #53 */ 12 | .linksShow-container .in-page-edit-article-link-group { 13 | display: none; 14 | } 15 | 16 | .noprint.plainlinks.hlist.navbar.nomobile { 17 | width: 140px !important; 18 | } 19 | 20 | /* [[Special:Interwiki]] */ 21 | .mw-interwikitable-modify .in-page-edit-article-link-group { 22 | display: none; 23 | } 24 | 25 | /* For MoeSkin */ 26 | body.skin-moeskin #ipe-edit-toolbox { 27 | bottom: 4rem; 28 | } -------------------------------------------------------------------------------- /src/gadgets/InPageEdit-v2/Gadget-InPageEdit-v2.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | mw.loader.load("https://testingcf.jsdelivr.net/npm/mediawiki-inpageedit@latest"); 3 | 4 | mw.hook("InPageEdit").add((ctx) => { 5 | const InPageEdit = ctx.InPageEdit, 6 | _msg = ctx._msg, 7 | wgPageName = mw.config.get("wgRelevantPageName"), 8 | wgRevisionId = mw.config.get("wgRevisionId"); 9 | switch (mw.config.get("skin")) { 10 | case "vector-2022": { 11 | $("#ca-edit").after( 12 | $("
  • ", { 13 | id: "ca-quick-edit", 14 | "class": "vector-tab-noicon mw-list-item", 15 | }).append( 16 | $("", { 17 | href: "javascript:void(0)", 18 | text: typeof Wikiplus !== "undefined" ? `${_msg("quick-edit")}(IPE)` : _msg("quick-edit"), 19 | }).on("click", () => { 20 | InPageEdit.quickEdit({ 21 | page: wgPageName, 22 | revision: wgRevisionId || undefined, 23 | }); 24 | }), 25 | ), 26 | ); 27 | break; 28 | } 29 | case "moeskin": 30 | default: { 31 | mw.hook("moeskin.pagetools").add(({ addPageToolsButton }) => { 32 | const $btn = addPageToolsButton('IPE', "快速编辑"); 33 | $btn.attr({ 34 | id: "ca-inpageedit", 35 | href: "javascript:void(0)", 36 | }).on("click", () => { 37 | InPageEdit.quickEdit({ 38 | page: wgPageName, 39 | revision: wgRevisionId || undefined, 40 | }); 41 | }); 42 | }); 43 | $(".page-tool-link#ca-inpageedit").insertAfter($(".page-tool-link#ca-edit")); 44 | break; 45 | } 46 | } 47 | $(".mw-history-compareselectedversions button").addClass("cdx-button"); 48 | }); 49 | -------------------------------------------------------------------------------- /src/gadgets/InPageEdit-v2/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: false 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: 24 | - edit 25 | 26 | peers: [] 27 | 28 | dependencies: 29 | - mediawiki.api 30 | - ext.gadget.libCachedCode 31 | 32 | _sites: 33 | - zh 34 | 35 | _section: editing 36 | 37 | _files: 38 | - Gadget-InPageEdit-v2.css 39 | - Gadget-InPageEdit-v2.js 40 | -------------------------------------------------------------------------------- /src/gadgets/JSONViewer/Gadget-JSONViewer.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | mw.loader.load("https://testingcf.jsdelivr.net/gh/BearBin1215/MoegirlPedia@master/dist/gadgets/JSONViewer.min.js"); 3 | -------------------------------------------------------------------------------- /src/gadgets/JSONViewer/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: false 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: [] 24 | 25 | peers: [] 26 | 27 | dependencies: [] 28 | 29 | _sites: 30 | - zh 31 | - commons 32 | 33 | _section: browsing 34 | 35 | _files: 36 | - Gadget-JSONViewer.js 37 | -------------------------------------------------------------------------------- /src/gadgets/LetYouDown/Gadget-LetYouDown.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | //
     3 | $(() => {
     4 |     const container = $("#mw-content-text");
     5 |     const getScrollTop = () => {
     6 |         const headings = $("#mw-content-text .mw-parser-output > :is(h1, h2)");
     7 |         return (headings.length >= 3 ? headings.last().offset().top : container.offset().top + container.outerHeight()) - 20;
     8 |     };
     9 |     let scrollTop = getScrollTop();
    10 |     setInterval(() => {
    11 |         scrollTop = getScrollTop();
    12 |     }, 7130);
    13 |     /**
    14 |      * @type {JQuery}
    15 |      */
    16 |     const btn = insertToBottomRightCorner("跳到底部").attr({
    17 |         title: "跳到底部",
    18 |         id: "LetYouDown",
    19 |     }).css({
    20 |         "user-select": "none",
    21 |         transition: "opacity .13s ease-in-out",
    22 |         order: "999",
    23 |     }).on("click", () => {
    24 |         $("html, body").animate({
    25 |             scrollTop: scrollTop,
    26 |         }, 130);
    27 |     });
    28 |     const $document = $(document);
    29 |     $(window).on("resize", () => {
    30 |         scrollTop = getScrollTop();
    31 |     }).on("scroll", () => {
    32 |         btn.css("opacity", $document.scrollTop() < scrollTop ? ".6" : "0");
    33 |     }).trigger("scroll");
    34 | });
    35 | // 
    36 | -------------------------------------------------------------------------------- /src/gadgets/LetYouDown/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: false 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: 10 | - vector-2022 11 | 12 | actions: [] 13 | 14 | categories: [] 15 | 16 | namespaces: [] 17 | 18 | contentModels: [] 19 | 20 | type: general 21 | 22 | package: false 23 | 24 | rights: [] 25 | 26 | peers: [] 27 | 28 | dependencies: 29 | - ext.gadget.libBottomRightCorner 30 | 31 | _sites: 32 | - zh 33 | - commons 34 | 35 | _section: browsing 36 | 37 | _files: 38 | - Gadget-LetYouDown.js 39 | -------------------------------------------------------------------------------- /src/gadgets/LocalObjectStorage/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: true 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: 24 | - hidden 25 | 26 | peers: [] 27 | 28 | dependencies: 29 | - ext.gadget.libPolyfill 30 | 31 | _sites: 32 | - zh 33 | - commons 34 | 35 | _section: system 36 | 37 | _files: 38 | - Gadget-LocalObjectStorage.js 39 | -------------------------------------------------------------------------------- /src/gadgets/Logout-confirm/Gadget-Logout-confirm.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | //
     3 | $(() => {
     4 |     $("#pt-logout > a[href*=logoutToken], .moe-user-dropdown-inner #logout").each((_, ele) => {
     5 |         const uri = new mw.Uri(ele.href);
     6 |         Reflect.deleteProperty(uri.query, "logoutToken");
     7 |         ele.href = uri;
     8 |     });
     9 |     if (mw.config.get("wgCanonicalSpecialPageName") === "Userlogout") {
    10 |         const context = $("#mw-content-text");
    11 |         if (!context.find("#mw-returnto")[0] && context.text().includes("If you wish to log out")) {
    12 |             const link = context.find("a[href*=logoutToken]").clone();
    13 |             link.attr("target", "_self").text(wgULS("点此退出", "點此登出")).addClass("mw-ui-button mw-ui-progressive").css("margin-left", ".25em");
    14 |             context.empty().text("如果您想退出萌娘百科账号,请", "如果您想登出萌娘百科賬號,請").append(link);
    15 |         }
    16 |     }
    17 | });
    18 | // 
    19 | -------------------------------------------------------------------------------- /src/gadgets/Logout-confirm/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: false 4 | 5 | default: true 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: [] 24 | 25 | peers: [] 26 | 27 | dependencies: 28 | - mediawiki.Uri 29 | - ext.gadget.site-lib 30 | 31 | _sites: 32 | - zh 33 | 34 | _section: user 35 | 36 | _files: 37 | - Gadget-Logout-confirm.js 38 | -------------------------------------------------------------------------------- /src/gadgets/MarkAsResolved-restricted/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: false 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: 24 | - edit 25 | - patrolmarks 26 | 27 | peers: [] 28 | 29 | dependencies: 30 | - mediawiki.api 31 | - ext.gadget.libPolyfill 32 | - ext.gadget.libOOUIDialog 33 | - ext.gadget.site-lib 34 | - ext.gadget.libDiscussionUtil 35 | 36 | _sites: 37 | - zh 38 | 39 | _section: maintenance 40 | 41 | _files: 42 | - Gadget-MarkAsResolved.css 43 | - Gadget-MarkAsResolved-restricted.js 44 | -------------------------------------------------------------------------------- /src/gadgets/MarkAsResolved/Gadget-MarkAsResolved.css: -------------------------------------------------------------------------------- 1 | .AnnTools_bolb { 2 | font-weight: bold; 3 | } 4 | 5 | .AnnTools_paragraphs { 6 | text-indent: 2em; 7 | } 8 | 9 | .AnnTools_RadioSelectWidget_column_2.oo-ui-radioSelectWidget { 10 | display: flex; 11 | flex-wrap: wrap; 12 | place-content: flex-start; 13 | align-items: flex-start; 14 | } 15 | 16 | .AnnTools_RadioSelectWidget_column_2.oo-ui-radioSelectWidget > .oo-ui-radioOptionWidget { 17 | min-width: 50%; 18 | width: max-content; 19 | max-width: 100%; 20 | } 21 | -------------------------------------------------------------------------------- /src/gadgets/MarkAsResolved/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: false 4 | 5 | default: true 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: 24 | - edit 25 | - patrol 26 | 27 | peers: [] 28 | 29 | dependencies: 30 | - mediawiki.api 31 | - ext.gadget.libPolyfill 32 | - ext.gadget.libOOUIDialog 33 | - ext.gadget.site-lib 34 | - ext.gadget.libDiscussionUtil 35 | 36 | _sites: 37 | - zh 38 | 39 | _section: maintenance 40 | 41 | _files: 42 | - Gadget-MarkAsResolved.css 43 | - Gadget-MarkAsResolved.js 44 | -------------------------------------------------------------------------------- /src/gadgets/ModerationStatus/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: false 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: 24 | - disabled 25 | 26 | peers: [] 27 | 28 | dependencies: 29 | - mediawiki.api 30 | - ext.gadget.LocalObjectStorage 31 | 32 | _sites: 33 | - zh 34 | 35 | _section: browsing 36 | 37 | _files: 38 | - Gadget-ModerationStatus.js 39 | -------------------------------------------------------------------------------- /src/gadgets/Navbox-link/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: false 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: 16 | - 10 17 | 18 | contentModels: [] 19 | 20 | type: general 21 | 22 | package: false 23 | 24 | rights: [] 25 | 26 | peers: [] 27 | 28 | dependencies: 29 | - mediawiki.api 30 | - ext.gadget.site-lib 31 | - ext.gadget.libPolyfill 32 | 33 | _sites: 34 | - zh 35 | 36 | _section: browsing 37 | 38 | _files: 39 | - Gadget-Navbox-link.js 40 | -------------------------------------------------------------------------------- /src/gadgets/Navigation_popups/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: false 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: 24 | - autoconfirmed 25 | 26 | peers: [] 27 | 28 | dependencies: 29 | - ext.gadget.site-lib 30 | - mediawiki.util 31 | - mediawiki.api 32 | - mediawiki.user 33 | - user.options 34 | - mediawiki.jqueryMsg 35 | - ext.gadget.libPolyfill 36 | 37 | _sites: 38 | - zh 39 | - commons 40 | 41 | _section: browsing 42 | 43 | _files: 44 | - Gadget-popups.css 45 | - Gadget-popups.js 46 | -------------------------------------------------------------------------------- /src/gadgets/Purgecache/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: false 4 | 5 | default: true 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: [] 24 | 25 | peers: [] 26 | 27 | dependencies: 28 | - ext.gadget.site-lib 29 | 30 | _sites: 31 | - zh 32 | - commons 33 | 34 | _section: browsing 35 | 36 | _files: 37 | - Gadget-Purgecache.js 38 | - Gadget-Purgecache.css 39 | -------------------------------------------------------------------------------- /src/gadgets/ReferenceTooltips/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: false 4 | 5 | default: true 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: [] 24 | 25 | peers: [] 26 | 27 | dependencies: 28 | - mediawiki.util 29 | - ext.gadget.site-lib 30 | - mediawiki.cookie 31 | - oojs 32 | - oojs-ui 33 | 34 | _sites: 35 | - zh 36 | 37 | _section: browsing 38 | 39 | _files: 40 | - Gadget-ReferenceTooltips.css 41 | - Gadget-ReferenceTooltips.js 42 | -------------------------------------------------------------------------------- /src/gadgets/Searchbox-integration/Gadget-Searchbox-integration.css: -------------------------------------------------------------------------------- 1 | #p-personal, 2 | #p-personal ul { 3 | float: left; 4 | } 5 | 6 | #p-personal ul { 7 | padding-left: 0; 8 | } 9 | 10 | #p-search { 11 | margin-right: 0.5em; 12 | } 13 | 14 | #searchform, 15 | #simpleSearch { 16 | margin-top: 0 !important; 17 | } -------------------------------------------------------------------------------- /src/gadgets/Searchbox-integration/Gadget-Searchbox-integration.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | $(() => { 3 | $("#p-search").prependTo("#p-personal"); 4 | }); 5 | -------------------------------------------------------------------------------- /src/gadgets/Searchbox-integration/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: false 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: 10 | - vector-2022 11 | 12 | actions: [] 13 | 14 | categories: [] 15 | 16 | namespaces: [] 17 | 18 | contentModels: [] 19 | 20 | type: general 21 | 22 | package: false 23 | 24 | rights: 25 | - disabled 26 | 27 | peers: [] 28 | 29 | dependencies: [] 30 | 31 | _sites: 32 | - zh 33 | 34 | _section: skin 35 | 36 | _files: 37 | - Gadget-Searchbox-integration.css 38 | - Gadget-Searchbox-integration.js 39 | -------------------------------------------------------------------------------- /src/gadgets/Searchbox-popout/Gadget-Searchbox-popout.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | //
     3 | $(() => {
     4 |     const $simpleSearch = $("#simpleSearch");
     5 |     $("input#searchInput").on({
     6 |         focus: () => {
     7 |             $simpleSearch.animate({
     8 |                 width: 339,
     9 |             }, 339);
    10 |         },
    11 |         blur: () => {
    12 |             $simpleSearch.animate({
    13 |                 width: 226,
    14 |             }, 339);
    15 |         },
    16 |     });
    17 | });
    18 | // 
    19 | -------------------------------------------------------------------------------- /src/gadgets/Searchbox-popout/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: false 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: 10 | - vector-2022 11 | 12 | actions: [] 13 | 14 | categories: [] 15 | 16 | namespaces: [] 17 | 18 | contentModels: [] 19 | 20 | type: general 21 | 22 | package: false 23 | 24 | rights: 25 | - disabled 26 | 27 | peers: [] 28 | 29 | dependencies: [] 30 | 31 | _sites: 32 | - zh 33 | 34 | _section: skin 35 | 36 | _files: 37 | - Gadget-Searchbox-popout.js 38 | -------------------------------------------------------------------------------- /src/gadgets/SectionPermanentLink/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: false 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: 24 | - edit 25 | 26 | peers: [] 27 | 28 | dependencies: 29 | - ext.gadget.site-lib 30 | 31 | _sites: 32 | - zh 33 | 34 | _section: user 35 | 36 | _files: 37 | - Gadget-SectionPermanentLink.js 38 | -------------------------------------------------------------------------------- /src/gadgets/SendWelcomeMessage/Gadget-SendWelcomeMessage.css: -------------------------------------------------------------------------------- 1 | #welcomeAsk, 2 | .welcomeAsk, 3 | #welcomeAskFinished { 4 | border: #bef 1px solid; 5 | margin: 0 3px 0 7px; 6 | } 7 | 8 | #welcomeYes, 9 | #welcomeNo, 10 | #welcomeCancel { 11 | cursor: pointer; 12 | color: purple; 13 | } 14 | 15 | .sendWelcomeMessageLink.unsend::after { 16 | content: "S"; 17 | color: purple; 18 | line-height: 1; 19 | vertical-align: super; 20 | font-size: smaller; 21 | } 22 | 23 | .sendWelcomeMessageLink { 24 | text-decoration: none !important; 25 | } 26 | -------------------------------------------------------------------------------- /src/gadgets/SendWelcomeMessage/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: false 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: 24 | - patrol 25 | 26 | peers: [] 27 | 28 | dependencies: 29 | - ext.gadget.libOOUIDialog 30 | - mediawiki.api 31 | 32 | _sites: 33 | - zh 34 | 35 | _section: user 36 | 37 | _files: 38 | - Gadget-SendWelcomeMessage.js 39 | - Gadget-SendWelcomeMessage.css 40 | -------------------------------------------------------------------------------- /src/gadgets/ShowAvatar/Gadget-ShowAvatar.css: -------------------------------------------------------------------------------- 1 | #p-personal li { 2 | margin-top: 1em; 3 | margin-bottom: 0.2em; 4 | } 5 | 6 | #pt-userpage { 7 | background: none !important; 8 | padding-left: 0 !important; 9 | } 10 | 11 | #pt-avatar { 12 | margin-top: 0.25em !important; 13 | margin-bottom: 0 !important; 14 | margin-right: 0.2em !important; 15 | } 16 | 17 | #pt-avatar img { 18 | width: 2.5em; 19 | border-radius: 50%; 20 | } 21 | 22 | .skin-vector-2022 #user-rootpage-avatar { 23 | border-radius: 10px; 24 | padding: 4px; 25 | } 26 | 27 | .skin-moeskin #user-rootpage-avatar { 28 | border-radius: 5px; 29 | top: 8px; 30 | position: relative; 31 | } 32 | 33 | /* 1.28+ Echo fix */ 34 | #p-personal #pt-notifications-alert, 35 | #p-personal #pt-notifications-notice { 36 | margin-top: 0.8em; 37 | } 38 | -------------------------------------------------------------------------------- /src/gadgets/ShowAvatar/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: false 4 | 5 | default: true 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: [] 24 | 25 | peers: [] 26 | 27 | dependencies: 28 | - mediawiki.Uri 29 | 30 | _sites: 31 | - zh 32 | - commons 33 | 34 | _section: user 35 | 36 | _files: 37 | - Gadget-ShowAvatar.css 38 | - Gadget-ShowAvatar.js 39 | -------------------------------------------------------------------------------- /src/gadgets/SideBarPic/Gadget-SideBarPic.css: -------------------------------------------------------------------------------- 1 | /* 侧边栏logo或左下角图片添加 */ 2 | body.sideBarPic-executed .sidebar-character { 3 | position: fixed; 4 | left: -3px; 5 | z-index: -2; 6 | } 7 | 8 | body.sideBarPic-executed .sidebar-character.top { 9 | top: 0; 10 | } 11 | 12 | body.sideBarPic-executed .sidebar-character.bottom { 13 | bottom: 0; 14 | } 15 | 16 | body.sideBarPic-executed #wglogo { 17 | display: none; 18 | } 19 | 20 | @media screen and (width <= 600px) { 21 | /* 低像素设备隐藏 */ 22 | .sidebar-character { 23 | display: none !important; 24 | } 25 | } 26 | 27 | body.sideBarPic.skin-vector-2022:not(.DeceasedPerson) #mw-panel .portal { 28 | background-color: rgb(246 246 246 / 90%); 29 | margin-left: -0.75em; 30 | margin-right: 0; 31 | padding-left: 1.5em; 32 | padding-right: 0.95em; 33 | } 34 | 35 | body.sideBarPic.skin-vector-2022:not(.DeceasedPerson) #mw-panel #p-logo + .portal { 36 | padding-top: 1.1em; 37 | margin-top: 0; 38 | } 39 | 40 | body.sideBarPic:not(.DeceasedPerson) .sidebar-character.active { 41 | display: block; 42 | } 43 | 44 | body.sideBarPic-executed.show-logo:not(.DeceasedPerson) #mw-panel #p-logo { 45 | height: 160px; 46 | } 47 | 48 | body.sideBarPic-executed.show-logo:not(.DeceasedPerson) #mw-panel #p-logo .mw-wiki-logo { 49 | background-image: url("https://img.moegirl.org.cn/logo/zhMoegirl15.2.png"); 50 | height: 160px; 51 | } 52 | 53 | body.sideBarPic:not(.DeceasedPerson) #footer { 54 | background-color: rgb(255 255 255 / 70%); 55 | } 56 | 57 | body.sideBarPic:not(.DeceasedPerson) #footer #footer-moegirl .copyright { 58 | color: #2f2f2f; 59 | } 60 | -------------------------------------------------------------------------------- /src/gadgets/SideBarPic/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: false 4 | 5 | default: true 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: [] 24 | 25 | peers: [] 26 | 27 | dependencies: 28 | - mediawiki.Uri 29 | 30 | _sites: 31 | - zh 32 | 33 | _section: browsing 34 | 35 | _files: 36 | - Gadget-SideBarPic.css 37 | - Gadget-SideBarPic.js 38 | -------------------------------------------------------------------------------- /src/gadgets/SpecialWikitext/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: false 4 | 5 | default: true 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: 24 | - autoconfirmed 25 | 26 | peers: [] 27 | 28 | dependencies: 29 | - mediawiki.api 30 | - ext.gadget.site-lib 31 | 32 | _sites: 33 | - zh 34 | 35 | _section: browsing 36 | 37 | _files: 38 | - Gadget-SpecialWikitext.js 39 | -------------------------------------------------------------------------------- /src/gadgets/UserLinkAvatar/Gadget-UserLinkAvatar.css: -------------------------------------------------------------------------------- 1 | img.userlink-avatar-small { 2 | margin-left: 0.2em; 3 | margin-right: 0.2em; 4 | width: 1.5em; 5 | height: 1.5em; 6 | border-radius: 15%; 7 | margin-top: -0.2em; 8 | } 9 | 10 | .userlink-avatar-large { 11 | display: none; 12 | position: absolute; 13 | top: 1em; 14 | left: 1em; 15 | padding: 1.5em; 16 | border: solid #A7D7F9 1px; 17 | border-radius: 3px; 18 | background-color: white; 19 | } 20 | 21 | .userlink-avatar-large img { 22 | min-width: 128px; 23 | } 24 | 25 | .userlink-avatar-hover, 26 | .userlink-avatar-hover .userlink-avatar-small { 27 | position: relative; 28 | cursor: pointer; 29 | } 30 | 31 | .userlink-avatar-hover:hover .userlink-avatar-large { 32 | display: block; 33 | z-index: 91; 34 | } 35 | -------------------------------------------------------------------------------- /src/gadgets/UserLinkAvatar/Gadget-UserLinkAvatar.js: -------------------------------------------------------------------------------- 1 | /** 2 | * TODO: 悬浮大头像功能暂时还没做,暂未提供大头像的链接 3 | */ 4 | 5 | "use strict"; 6 | //
     7 | (() => {
     8 |     const DEFAULT_AVATAR = "https://img.moegirl.org.cn/moehime.jpg";
     9 |     /**
    10 |      * @param {HTMLElement} el
    11 |      */
    12 |     const checkIfAvatarLoaded = (el) => typeof el.dataset.userAvatarLoaded !== "undefined";
    13 | 
    14 |     /**
    15 |      * @param {HTMLAnchorElement} target
    16 |      */
    17 |     const attachAvatarToUserLink = (target) => {
    18 |         if (checkIfAvatarLoaded(target)) {
    19 |             return;
    20 |         }
    21 |         const userName = target.textContent.trim();
    22 |         const avatar = target.dataset.userAvatar;
    23 | 
    24 |         const avatarLink = document.createElement("a");
    25 |         const img = document.createElement("img");
    26 | 
    27 |         img.loading = "lazy";
    28 |         img.src = avatar;
    29 |         img.alt = `${userName}的头像`;
    30 |         img.classList.add("userlink-avatar-small");
    31 |         img.addEventListener("error", () => {
    32 |             if (img.src !== DEFAULT_AVATAR) {
    33 |                 img.src = DEFAULT_AVATAR;
    34 |             } else {
    35 |                 avatarLink.remove();
    36 |             }
    37 |         });
    38 | 
    39 |         avatarLink.classList.add("userlink-avatar");
    40 |         avatarLink.href = `https://commons.moegirl.org.cn/Special:ViewAvatar?user=${userName}`;
    41 |         avatarLink.target = "_blank";
    42 |         avatarLink.title = "查看头像";
    43 |         avatarLink.appendChild(img);
    44 |         avatarLink.addEventListener("click", (e) => {
    45 |             e.stopPropagation();
    46 |         });
    47 | 
    48 |         target.insertAdjacentElement("beforebegin", avatarLink);
    49 |         target.dataset.userAvatarLoaded = "1";
    50 | 
    51 |         return avatarLink;
    52 |     };
    53 | 
    54 |     mw.hook("wikipage.content").add(
    55 |         /**
    56 |          * @param {JQuery} $content
    57 |          */
    58 |         ($content) => {
    59 |             $content.find(".mw-userlink[data-user-avatar]").each((_, el) => {
    60 |                 attachAvatarToUserLink(el);
    61 |             });
    62 |         });
    63 | })();
    64 | // 
    65 | -------------------------------------------------------------------------------- /src/gadgets/UserLinkAvatar/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: false 4 | 5 | default: true 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: [] 24 | 25 | peers: [] 26 | 27 | dependencies: 28 | - user.options 29 | - ext.gadget.jQueryLazyload 30 | 31 | _sites: 32 | - zh 33 | - commons 34 | 35 | _section: user 36 | 37 | _files: 38 | - Gadget-UserLinkAvatar.css 39 | - Gadget-UserLinkAvatar.js 40 | -------------------------------------------------------------------------------- /src/gadgets/UserMessages/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: false 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: 24 | - edit 25 | - patrol 26 | 27 | peers: [] 28 | 29 | dependencies: 30 | - ext.gadget.site-lib 31 | - ext.gadget.libUtil 32 | - jquery.ui 33 | - mediawiki.util 34 | 35 | _sites: 36 | - zh 37 | 38 | _section: maintenance 39 | 40 | _files: 41 | - Gadget-UserMessages.js 42 | -------------------------------------------------------------------------------- /src/gadgets/Wikiplus/Gadget-Wikiplus.css: -------------------------------------------------------------------------------- 1 | /* 调整navbar以适应Wikiplus快速编辑 */ 2 | .noprint.plainlinks.hlist.navbar.nomobile { 3 | width: 140px !important; 4 | } 5 | 6 | /* 修复MoeSkin上的工具栏快速编辑按钮 7 | * 机智的小鱼君 2022/4/16 8 | */ 9 | body.skin-moeskin #moe-page-tools #Wikiplus-Edit-TopBtn { 10 | width: 2rem; 11 | height: 2rem; 12 | border-radius: 50%; 13 | background-color: var(--theme-accent-link-color); 14 | line-height: 2rem; 15 | font-size: 0.75rem; 16 | text-align: center; 17 | box-shadow: var(--theme-card-box-shadow); 18 | } 19 | 20 | body.skin-moeskin #moe-page-tools #Wikiplus-Edit-TopBtn a { 21 | color: var(--theme-button-color); 22 | } 23 | 24 | @media (width <= 768px) { 25 | 26 | /* 调整窄屏的快速编辑按钮 */ 27 | .skin-moeskin .mobile-edit-button { 28 | display: flex; 29 | gap: .5em; 30 | } 31 | 32 | .skin-moeskin .mobile-edit-button #Wikiplus-Edit-TopBtn { 33 | list-style: none; 34 | height: 28px; 35 | } 36 | 37 | .skin-moeskin .mobile-edit-button #Wikiplus-Edit-TopBtn > span { 38 | display: block; 39 | height: 100%; 40 | } 41 | 42 | .skin-moeskin .mobile-edit-button #Wikiplus-Edit-TopBtn a { 43 | height: 100%; 44 | display: flex; 45 | align-items: center; 46 | background-color: rgb(24 160 88 / 16%); 47 | border-radius: 3px; 48 | padding: 0 10px; 49 | white-space: nowrap; 50 | font-size: 14px; 51 | transition: color .3s cubic-bezier(0.4, 0, 0.2, 1), background-color .3s cubic-bezier(0.4, 0, 0.2, 1), opacity .3s cubic-bezier(0.4, 0, 0.2, 1), border-color .3s cubic-bezier(0.4, 0, 0.2, 1); 52 | color: #18a058; 53 | line-height: 1; 54 | -webkit-user-select: none; 55 | user-select: none; 56 | } 57 | 58 | .skin-moeskin .mobile-edit-button #Wikiplus-Edit-TopBtn a:hover { 59 | background: rgb(24 160 88 / 22%); 60 | } 61 | 62 | .skin-moeskin .mobile-edit-button #Wikiplus-Edit-TopBtn a:focus { 63 | text-decoration: none; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/gadgets/Wikiplus/Gadget-Wikiplus.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | (async () => { 3 | await libCachedCode.injectCachedCode("https://npm.elemecdn.com/wikiplus-core@latest", "script"); 4 | const sleep = (ms) => new Promise((res) => setTimeout(res, ms)); 5 | if (mw.config.get("skin") !== "moeskin" || !document.querySelector("#ca-edit")) { 6 | return; 7 | } 8 | let wikiplusEditTopBtn = document.querySelector("#Wikiplus-Edit-TopBtn"); 9 | while (!wikiplusEditTopBtn) { 10 | await sleep(100); 11 | // eslint-disable-next-line require-atomic-updates 12 | wikiplusEditTopBtn = document.querySelector("#Wikiplus-Edit-TopBtn"); 13 | } 14 | mw.hook("moeskin.pagetools").add(({ addPageToolsButton }) => { 15 | const $btn = addPageToolsButton('W+', "快速编辑"); 16 | $btn.attr("id", "ca-wikiplus").on("click", () => { 17 | wikiplusEditTopBtn.click(); 18 | }); 19 | }); 20 | $(".page-tool-link#ca-wikiplus").insertAfter($(".page-tool-link#ca-edit")); 21 | })(); 22 | -------------------------------------------------------------------------------- /src/gadgets/Wikiplus/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: false 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: 24 | - edit 25 | 26 | peers: [] 27 | 28 | dependencies: 29 | - ext.gadget.libCachedCode 30 | 31 | _sites: 32 | - zh 33 | 34 | _section: editing 35 | 36 | _files: 37 | - Gadget-Wikiplus.css 38 | - Gadget-Wikiplus.js 39 | -------------------------------------------------------------------------------- /src/gadgets/abusefilter33test/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: false 4 | 5 | default: true 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: 24 | - abusefilter-log-private 25 | 26 | peers: [] 27 | 28 | dependencies: 29 | - mediawiki.api 30 | 31 | _sites: 32 | - zh 33 | - commons 34 | 35 | _section: administration 36 | 37 | _files: 38 | - Gadget-abusefilter33test.js 39 | -------------------------------------------------------------------------------- /src/gadgets/abusefilterEdit/Gadget-abusefilteredit.css: -------------------------------------------------------------------------------- 1 | /* 防滥用过滤器编辑页 */ 2 | #mw-abusefilter-warn-parameters fieldset, 3 | #mw-abusefilter-warn-parameters table { 4 | width: 100%; 5 | box-sizing: border-box; 6 | } -------------------------------------------------------------------------------- /src/gadgets/abusefilterEdit/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: false 4 | 5 | default: true 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: 24 | - abusefilter-modify 25 | - editinterface 26 | 27 | peers: [] 28 | 29 | dependencies: [] 30 | 31 | _sites: 32 | - zh 33 | 34 | _section: interface 35 | 36 | _files: 37 | - Gadget-abusefilteredit.css 38 | - Gadget-abusefilteredit.js 39 | -------------------------------------------------------------------------------- /src/gadgets/abusefilterResize/Gadget-abusefilterresize.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | $(() => { 3 | if (mw.config.get("wgCanonicalSpecialPageName") === "AbuseFilter" || $("#wpAceFilterEditor")[0]) { 4 | /* 5 | if ($("[name=wpFilterDescription][readonly=readonly]")[0]) { 6 | return; 7 | } 8 | */ 9 | const $filterBox = $("#wpAceFilterEditor"), 10 | filterEditor = ace.edit("wpAceFilterEditor"); 11 | if (typeof ResizeObserver !== "undefined") { 12 | $filterBox.css("resize", "both"); 13 | new ResizeObserver(() => { 14 | filterEditor.resize(); 15 | }).observe($filterBox[0]); 16 | } 17 | } 18 | }); 19 | -------------------------------------------------------------------------------- /src/gadgets/abusefilterResize/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: true 4 | 5 | default: true 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: 24 | - abusefilter-modify 25 | 26 | peers: [] 27 | 28 | dependencies: 29 | - ext.abuseFilter.ace 30 | 31 | _sites: 32 | - zh 33 | 34 | _section: interface 35 | 36 | _files: 37 | - Gadget-abusefilterresize.js 38 | -------------------------------------------------------------------------------- /src/gadgets/allmessageFilter/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: false 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: 24 | - editinterface 25 | 26 | peers: [] 27 | 28 | dependencies: 29 | - ext.gadget.libOOUIDialog 30 | 31 | _sites: 32 | - zh 33 | 34 | _section: interface 35 | 36 | _files: 37 | - Gadget-allmessageFilter.js 38 | -------------------------------------------------------------------------------- /src/gadgets/april-fool-2025/Gadget-april-fool-2025.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const 现在 = new Date(); 4 | const 现在是2025愚人节 = `${现在.getFullYear()}-${(现在.getMonth() + 1).toString().padStart(2, "0")}-${现在.getDate().toString().padStart(2, "0")}` === "2025-04-01"; 5 | if (现在是2025愚人节) { 6 | mw.loader.load("https://storage.moegirl.org.cn/console-plus/uploads/2025/04/01/april-fool-2025.js"); 7 | } 8 | -------------------------------------------------------------------------------- /src/gadgets/april-fool-2025/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: true 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: [] 24 | 25 | peers: [] 26 | 27 | dependencies: [] 28 | 29 | _sites: 30 | - zh 31 | 32 | _section: browsing 33 | 34 | _files: 35 | - Gadget-april-fool-2025.js 36 | -------------------------------------------------------------------------------- /src/gadgets/autocollapse/Gadget-autocollapse.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | mw.hook("wikipage.collapsibleContent").add(($collapsibleContent) => { 3 | const autoCollapseThreshold = 2; 4 | $collapsibleContent.each((_, ele) => { 5 | const $ele = $(ele); 6 | if ($collapsibleContent.length >= autoCollapseThreshold && $ele.hasClass("autocollapse")) { 7 | $ele.data("mw-collapsible").collapse(); 8 | } else if ($ele.hasClass("innercollapse") && $ele.closest(".outercollapse").length > 0) { 9 | $ele.data("mw-collapsible").collapse(); 10 | } 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /src/gadgets/autocollapse/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: false 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: [] 24 | 25 | peers: [] 26 | 27 | dependencies: [] 28 | 29 | _sites: 30 | - zh 31 | 32 | _section: browsing 33 | 34 | _files: 35 | - Gadget-autocollapse.js 36 | -------------------------------------------------------------------------------- /src/gadgets/autoconfirmedUserPing/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: false 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: 24 | - autopatrol 25 | 26 | peers: [] 27 | 28 | dependencies: 29 | - mediawiki.api 30 | - oojs-ui-core 31 | - moment 32 | 33 | _sites: 34 | - zh 35 | 36 | _section: maintenance 37 | 38 | _files: 39 | - Gadget-autoconfirmedUserPing.js 40 | -------------------------------------------------------------------------------- /src/gadgets/backlog/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: false 4 | 5 | default: true 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: 24 | - patrol 25 | 26 | peers: [] 27 | 28 | dependencies: 29 | - mediawiki.api 30 | - moment 31 | - mediawiki.user 32 | 33 | _sites: 34 | - zh 35 | 36 | _section: administration 37 | 38 | _files: 39 | - Gadget-backlog.css 40 | - Gadget-backlog.js 41 | -------------------------------------------------------------------------------- /src/gadgets/blockEnhance/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: true 4 | 5 | default: true 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: 24 | - block 25 | 26 | peers: [] 27 | 28 | dependencies: 29 | - ext.gadget.libOOUIDialog 30 | - mediawiki.api 31 | - ext.gadget.site-lib 32 | 33 | _sites: 34 | - zh 35 | - commons 36 | 37 | _section: administration 38 | 39 | _files: 40 | - Gadget-blockEnhance.js 41 | -------------------------------------------------------------------------------- /src/gadgets/code-prettify/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: false 4 | 5 | default: true 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: [] 24 | 25 | peers: [] 26 | 27 | dependencies: 28 | - mediawiki.Uri 29 | - user.options 30 | 31 | _sites: 32 | - zh 33 | - commons 34 | 35 | _section: browsing 36 | 37 | _files: 38 | - Gadget-code-prettify.css 39 | - Gadget-code-prettify.js 40 | -------------------------------------------------------------------------------- /src/gadgets/deletion/Gadget-deletion.css: -------------------------------------------------------------------------------- 1 | .batdel-body .mw-category-generated ul { 2 | margin-left: 0; 3 | } 4 | 5 | .batdel-body .mw-category-generated ul li { 6 | list-style: none; 7 | } 8 | 9 | .batdel-body #batdel-control { 10 | border: 1px dashed black; 11 | padding: 0.5em; 12 | } 13 | 14 | .batdel-body #batdel-control button { 15 | margin: 0 0.5em; 16 | } 17 | 18 | .batdel-body .batdel-disabled { 19 | opacity: 0.3; 20 | } 21 | 22 | .batdel-error { 23 | color: #D32F2F; 24 | } 25 | 26 | .batdel-success { 27 | color: #388E3C; 28 | } 29 | -------------------------------------------------------------------------------- /src/gadgets/deletion/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: false 4 | 5 | default: true 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: 16 | - 14 17 | 18 | contentModels: [] 19 | 20 | type: general 21 | 22 | package: false 23 | 24 | rights: 25 | - delete 26 | 27 | peers: [] 28 | 29 | dependencies: 30 | - ext.gadget.site-lib 31 | - ext.gadget.libOOUIDialog 32 | - mediawiki.util 33 | - mediawiki.api 34 | - mediawiki.Uri 35 | 36 | _sites: 37 | - zh 38 | - commons 39 | 40 | _section: administration 41 | 42 | _files: 43 | - Gadget-deletion.css 44 | - Gadget-deletion.js 45 | -------------------------------------------------------------------------------- /src/gadgets/disable-nest-alert/Gadget-disable-nest-alert.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | // placeholder 3 | -------------------------------------------------------------------------------- /src/gadgets/disable-nest-alert/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: false 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: 24 | - patrol 25 | 26 | peers: [] 27 | 28 | dependencies: [] 29 | 30 | _sites: 31 | - zh 32 | 33 | _section: editing 34 | 35 | _files: 36 | - Gadget-disable-nest-alert.js 37 | -------------------------------------------------------------------------------- /src/gadgets/disambigLink/Gadget-disambigLink.css: -------------------------------------------------------------------------------- 1 | a.mw-disambig, 2 | body.heimu_toggle_on .heimu a.mw-disambig, 3 | body.heimu_toggle_on a.mw-disambig .heimu, 4 | .heimu:hover a.mw-disambig, 5 | a.mw-disambig:hover .heimu { 6 | color: #EF8850; 7 | } 8 | 9 | a.mw-disambig:visited, 10 | body.heimu_toggle_on .heimu a.mw-disambig:visited, 11 | body.heimu_toggle_on a.mw-disambig:visited .heimu, 12 | .heimu:hover a.mw-disambig:visited, 13 | a.mw-disambig:visited:hover .heimu { 14 | color: #D27138; 15 | } -------------------------------------------------------------------------------- /src/gadgets/disambigLink/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: false 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: styles 20 | 21 | package: false 22 | 23 | rights: [] 24 | 25 | peers: [] 26 | 27 | dependencies: [] 28 | 29 | _sites: 30 | - zh 31 | 32 | _section: browsing 33 | 34 | _files: 35 | - Gadget-disambigLink.css 36 | -------------------------------------------------------------------------------- /src/gadgets/edit/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: true 4 | 5 | default: true 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: 12 | - edit 13 | 14 | categories: [] 15 | 16 | namespaces: [] 17 | 18 | contentModels: [] 19 | 20 | type: general 21 | 22 | package: false 23 | 24 | rights: 25 | - edit 26 | 27 | peers: [] 28 | 29 | dependencies: 30 | - ext.gadget.libOOUIDialog 31 | 32 | _sites: 33 | - zh 34 | 35 | _section: system 36 | 37 | _files: 38 | - Gadget-edit.js 39 | -------------------------------------------------------------------------------- /src/gadgets/editCount/Gadget-editCount.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | $(() => { 3 | mw.loader.addStyleTag(`#pt-mycontris > a::after { 4 | content: "(${mw.config.get("wgUserEditCount")})"; 5 | margin-left: .1em; 6 | }`); 7 | }); 8 | -------------------------------------------------------------------------------- /src/gadgets/editCount/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: false 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: 10 | - vector-2022 11 | 12 | actions: [] 13 | 14 | categories: [] 15 | 16 | namespaces: [] 17 | 18 | contentModels: [] 19 | 20 | type: general 21 | 22 | package: false 23 | 24 | rights: 25 | - edit 26 | 27 | peers: [] 28 | 29 | dependencies: [] 30 | 31 | _sites: 32 | - zh 33 | 34 | _section: user 35 | 36 | _files: 37 | - Gadget-editCount.js 38 | -------------------------------------------------------------------------------- /src/gadgets/editTopSection/Gadget-editTopSection.css: -------------------------------------------------------------------------------- 1 | #ca-editTopSection .mw-editsection { 2 | font-family: inherit; 3 | font-size: inherit; 4 | font-weight: 400; 5 | margin-left: 0; 6 | vertical-align: inherit; 7 | line-height: inherit; 8 | } 9 | 10 | #ca-editTopSection .mw-editsection-divider { 11 | display: none !important; 12 | } 13 | 14 | #ca-editTopSection .Wikiplus-Edit-SectionBtn::after { 15 | content: "序言"; 16 | } -------------------------------------------------------------------------------- /src/gadgets/editTopSection/Gadget-editTopSection.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | //
     3 | $(() => {
     4 |     if ($(".mw-editsection")[0] && !$("#template-documentation, .template-documentation")[0]) {
     5 |         switch (mw.config.get("skin")) {
     6 |             case "vector-2022":
     7 |                 $("#ca-edit").after(`
  • ${wgULS("编辑序言", "編輯序言")}
  • `); 8 | break; 9 | case "moeskin": 10 | default: 11 | mw.hook("moeskin.pagetools").add(({ addPageToolsButton }) => { 12 | const $btn = addPageToolsButton("", wgULS("编辑序言", "編輯序言")); 13 | $btn.attr({ 14 | id: "ca-editTopSection", 15 | href: `${$("a.page-tool-link#ca-edit").attr("href")}§ion=0`, 16 | }); 17 | }); 18 | $(".page-tool-link#ca-editTopSection").insertAfter($(".page-tool-link#ca-edit")); 19 | break; 20 | } 21 | } 22 | }); 23 | //
    24 | -------------------------------------------------------------------------------- /src/gadgets/editTopSection/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: false 4 | 5 | default: true 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: 24 | - edit 25 | 26 | peers: [] 27 | 28 | dependencies: 29 | - ext.gadget.site-lib 30 | 31 | _sites: 32 | - zh 33 | 34 | _section: editing 35 | 36 | _files: 37 | - Gadget-editTopSection.css 38 | - Gadget-editTopSection.js 39 | -------------------------------------------------------------------------------- /src/gadgets/enable-nest-highlight/Gadget-enable-nest-highlight.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | // placeholder 3 | -------------------------------------------------------------------------------- /src/gadgets/enable-nest-highlight/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: false 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: 24 | - edit 25 | 26 | peers: [] 27 | 28 | dependencies: [] 29 | 30 | _sites: 31 | - zh 32 | 33 | _section: editing 34 | 35 | _files: 36 | - Gadget-enable-nest-highlight.js 37 | -------------------------------------------------------------------------------- /src/gadgets/extiw/Gadget-extiw.css: -------------------------------------------------------------------------------- 1 | /* 外链 */ 2 | a.extiw:not([href*=".moegirl.org.cn"]), 3 | a.extiw:not([href*=".moegirl.org.cn"]):visited, 4 | body.heimu_toggle_on span.heimu a.extiw:not([href*=".moegirl.org.cn"]), 5 | body.heimu_toggle_on a.extiw:not([href*=".moegirl.org.cn"]) span.heimu { 6 | color: #00AF89; 7 | } 8 | 9 | .heimu:hover a.extiw:not([href*=".moegirl.org.cn"]), 10 | .heimu:hover a.extiw:not([href*=".moegirl.org.cn"]):visited, 11 | a.extiw:not([href*=".moegirl.org.cn"]):hover .heimu, 12 | a.extiw:not([href*=".moegirl.org.cn"]):hover:visited .heimu { 13 | color: #00D7A8; 14 | } -------------------------------------------------------------------------------- /src/gadgets/extiw/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: false 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: styles 20 | 21 | package: false 22 | 23 | rights: [] 24 | 25 | peers: [] 26 | 27 | dependencies: [] 28 | 29 | _sites: 30 | - zh 31 | 32 | _section: browsing 33 | 34 | _files: 35 | - Gadget-extiw.css 36 | -------------------------------------------------------------------------------- /src/gadgets/flagBlocked/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: false 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: 24 | - edit 25 | - patrol 26 | 27 | peers: [] 28 | 29 | dependencies: 30 | - ext.gadget.libOOUIDialog 31 | - mediawiki.api 32 | - moment 33 | 34 | _sites: 35 | - zh 36 | 37 | _section: administration 38 | 39 | _files: 40 | - Gadget-flagBlocked.js 41 | -------------------------------------------------------------------------------- /src/gadgets/flagEditWar/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: false 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: 24 | - edit 25 | - protect 26 | 27 | peers: [] 28 | 29 | dependencies: 30 | - ext.gadget.libOOUIDialog 31 | - mediawiki.api 32 | - moment 33 | 34 | _sites: 35 | - zh 36 | 37 | _section: administration 38 | 39 | _files: 40 | - Gadget-flagEditWar.js 41 | -------------------------------------------------------------------------------- /src/gadgets/float-toc/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: false 4 | 5 | default: true 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: 10 | - vector-2022 11 | 12 | actions: 13 | - view 14 | 15 | categories: [] 16 | 17 | namespaces: 18 | - 0 19 | - 1 20 | - 2 21 | - 3 22 | - 4 23 | - 5 24 | - 9 25 | - 11 26 | - 12 27 | - 13 28 | - 15 29 | - 275 30 | - 711 31 | - 829 32 | 33 | contentModels: [] 34 | 35 | type: general 36 | 37 | package: false 38 | 39 | rights: 40 | - autoconfirmed 41 | 42 | peers: [] 43 | 44 | dependencies: 45 | - ext.gadget.LocalObjectStorage 46 | - mediawiki.toc 47 | 48 | _sites: 49 | - zh 50 | 51 | _section: browsing 52 | 53 | _files: 54 | - Gadget-float-toc.css 55 | - Gadget-float-toc.js 56 | -------------------------------------------------------------------------------- /src/gadgets/hideAutopromoteLog/Gadget-hideAutoPromoteLog.css: -------------------------------------------------------------------------------- 1 | body.mw-special-Log #mw-content-text > a:is(.mw-lastlink, .mw-nextlink, .mw-numlink):not([href*="type=rights"]) + form li.mw-logline-rights[data-mw-logaction="rights/autopromote"] { 2 | display: none; 3 | } 4 | -------------------------------------------------------------------------------- /src/gadgets/hideAutopromoteLog/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: false 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: styles 20 | 21 | package: false 22 | 23 | rights: [] 24 | 25 | peers: [] 26 | 27 | dependencies: [] 28 | 29 | _sites: 30 | - zh 31 | 32 | _section: browsing 33 | 34 | _files: 35 | - Gadget-hideAutoPromoteLog.css 36 | -------------------------------------------------------------------------------- /src/gadgets/hideFlowthreadDefaultly/Gadget-hideFlowthreadDefaultly.js: -------------------------------------------------------------------------------- 1 | //
     2 | "use strict";
     3 | $("#bodyContent").append(`
    ${wgULS("显示/隐藏评论区", "顯示/隱藏評論區")}
    `); 4 | if (location.hash !== "#flowthread") { 5 | $("#flowthread").hide(); 6 | } 7 | mw.loader.addStyleTag("#flowthread-toggle { cursor: pointer; border-radius: 5px; background-color: rgba(191, 234, 181, .2); border: 1px solid rgba(18, 152, 34, .47); padding: 1em; text-align: center; margin: 1em 0 .5em; } #bodyContent + #flowthread { margin-top: 0; }"); 8 | $("#flowthread-toggle").on("click", (e) => { 9 | e.preventDefault(); 10 | const flowthread = $("#flowthread"); 11 | if (flowthread.is(":visible")) { 12 | flowthread.slideUp(500); 13 | if (location.hash === "#flowthread") { 14 | location.replace("#/"); 15 | } 16 | } else { 17 | flowthread.slideDown(500); 18 | } 19 | }); 20 | $(window).on("hashchange", () => { 21 | if (location.hash === "#flowthread") { 22 | $("#flowthread").show(); 23 | } 24 | }); 25 | //
    26 | -------------------------------------------------------------------------------- /src/gadgets/hideFlowthreadDefaultly/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: false 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: 24 | - disabled 25 | 26 | peers: [] 27 | 28 | dependencies: 29 | - ext.gadget.site-lib 30 | - ext.flowthread 31 | 32 | _sites: 33 | - zh 34 | 35 | _section: browsing 36 | 37 | _files: 38 | - Gadget-hideFlowthreadDefaultly.js 39 | -------------------------------------------------------------------------------- /src/gadgets/hideUnpatrolledFlag/Gadget-hideUnpatrolledFlag.css: -------------------------------------------------------------------------------- 1 | abbr.unpatrolled { 2 | visibility: hidden; /* display: none 会对不齐 */ 3 | } -------------------------------------------------------------------------------- /src/gadgets/hideUnpatrolledFlag/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: false 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: styles 20 | 21 | package: false 22 | 23 | rights: 24 | - patrolmarks 25 | 26 | peers: [] 27 | 28 | dependencies: [] 29 | 30 | _sites: 31 | - zh 32 | 33 | _section: browsing 34 | 35 | _files: 36 | - Gadget-hideUnpatrolledFlag.css 37 | -------------------------------------------------------------------------------- /src/gadgets/interfaceVariantConverter/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: false 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: 12 | - view 13 | 14 | categories: [] 15 | 16 | namespaces: 17 | - 8 18 | 19 | contentModels: 20 | - wikitext 21 | 22 | type: general 23 | 24 | package: false 25 | 26 | rights: 27 | - edit 28 | - editinterface 29 | 30 | peers: [] 31 | 32 | dependencies: 33 | - mediawiki.api 34 | - mediawiki.ForeignApi 35 | - oojs-ui 36 | - ext.gadget.libPolyfill 37 | - ext.gadget.libCachedCode 38 | 39 | _sites: 40 | - zh 41 | - commons 42 | 43 | _section: interface 44 | 45 | _files: 46 | - Gadget-interfaceVariantConverter.js 47 | -------------------------------------------------------------------------------- /src/gadgets/jQueryLazyload/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: true 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: 24 | - hidden 25 | 26 | peers: [] 27 | 28 | dependencies: [] 29 | 30 | _sites: 31 | - zh 32 | - commons 33 | 34 | _section: system 35 | 36 | _files: 37 | - Gadget-jQueryLazyload.js 38 | -------------------------------------------------------------------------------- /src/gadgets/legacyMainpage/Gadget-legacyMainpage.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | $(() => { 3 | if (mw.config.get("wgPageName") === "Mainpage") { 4 | location.hash = "/legacy"; 5 | } 6 | }); 7 | -------------------------------------------------------------------------------- /src/gadgets/legacyMainpage/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: false 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: 10 | - vector-2022 11 | 12 | actions: [] 13 | 14 | categories: [] 15 | 16 | namespaces: [] 17 | 18 | contentModels: [] 19 | 20 | type: general 21 | 22 | package: false 23 | 24 | rights: [] 25 | 26 | peers: [] 27 | 28 | dependencies: [] 29 | 30 | _sites: 31 | - zh 32 | 33 | _section: browsing 34 | 35 | _files: 36 | - Gadget-legacyMainpage.js 37 | -------------------------------------------------------------------------------- /src/gadgets/libBottomRightCorner/Gadget-libBottomRightCorner.css: -------------------------------------------------------------------------------- 1 | #bottomRightCorner { 2 | display: flex; 3 | flex-direction: column; 4 | position: fixed; 5 | right: 0; 6 | bottom: 100px; 7 | cursor: pointer; 8 | z-index: 13; 9 | user-select: none; 10 | } 11 | 12 | body.overlay-scrollbars.skin-vector-2022 #bottomRightCorner { 13 | /* 因为无法计算滚动条宽度,只能使用预设值 */ 14 | right: 20px; 15 | } 16 | 17 | #bottomRightCorner>div { 18 | width: 20px; 19 | order: 0; 20 | font-size: 12px; 21 | text-align: center; 22 | padding: 5px 0; 23 | margin-top: 17px; 24 | background-color: #000; 25 | color: #FFF; 26 | opacity: 0.6; 27 | } 28 | 29 | .mw-mmv-lightbox-open #bottomRightCorner { 30 | display: none !important; 31 | } 32 | 33 | @media print { 34 | #bottomRightCorner { 35 | display: none !important; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/gadgets/libBottomRightCorner/Gadget-libBottomRightCorner.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | $(() => { 3 | const body = document.body; 4 | const bottomRightCorner = $("
    ").attr("id", "bottomRightCorner"); 5 | bottomRightCorner.appendTo(body); 6 | window.insertToBottomRightCorner = (text) => $("
    ").text(text).appendTo(bottomRightCorner); 7 | }); 8 | -------------------------------------------------------------------------------- /src/gadgets/libBottomRightCorner/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: true 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: 24 | - hidden 25 | 26 | peers: [] 27 | 28 | dependencies: [] 29 | 30 | _sites: 31 | - zh 32 | - commons 33 | 34 | _section: system 35 | 36 | _files: 37 | - Gadget-libBottomRightCorner.css 38 | - Gadget-libBottomRightCorner.js 39 | -------------------------------------------------------------------------------- /src/gadgets/libCachedCode/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: true 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: 24 | - hidden 25 | 26 | peers: [] 27 | 28 | dependencies: 29 | - ext.gadget.LocalObjectStorage 30 | 31 | _sites: 32 | - zh 33 | - commons 34 | 35 | _section: system 36 | 37 | _files: 38 | - Gadget-libCachedCode.js 39 | -------------------------------------------------------------------------------- /src/gadgets/libDiscussionUtil/Gadget-libDiscussionUtil.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | window.libDiscussionUtil = { 3 | getDiscussionHeader: (filterClassess = []) => [...document.querySelectorAll("#mw-content-text > .mw-parser-output > h2, #mw-content-text > .mw-parser-output > .discussionContainer > h2, #mw-content-text > .mw-parser-output > .mw-heading2")].map((ele) => { 4 | const self = $(ele); 5 | const content = self.nextUntil("h2, .mw-heading2").not("h2, .mw-heading2"); 6 | for (const filterClass of filterClassess) { 7 | if (content.hasClass(filterClass)) { 8 | return null; 9 | } 10 | } 11 | const sectionTitle = self.find(".mw-headline, h2[data-mw-thread-id]").attr("id"); 12 | return { self, sectionTitle }; 13 | }).filter((n) => n !== null), 14 | }; 15 | -------------------------------------------------------------------------------- /src/gadgets/libDiscussionUtil/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: true 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: 24 | - hidden 25 | 26 | peers: [] 27 | 28 | dependencies: [] 29 | 30 | _sites: 31 | - zh 32 | 33 | _section: system 34 | 35 | _files: 36 | - Gadget-libDiscussionUtil.js 37 | -------------------------------------------------------------------------------- /src/gadgets/libHashwasm/.eslintrc.yaml: -------------------------------------------------------------------------------- 1 | ignorePatterns: 2 | - Gadget-libHashwasm.js 3 | -------------------------------------------------------------------------------- /src/gadgets/libHashwasm/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: true 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: 24 | - hidden 25 | 26 | peers: [] 27 | 28 | dependencies: 29 | - ext.gadget.libPolyfill 30 | 31 | _sites: 32 | - zh 33 | 34 | _section: system 35 | 36 | _files: 37 | - Gadget-libHashwasm.js 38 | -------------------------------------------------------------------------------- /src/gadgets/libJQuery/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: true 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: 24 | - hidden 25 | 26 | peers: [] 27 | 28 | dependencies: [] 29 | 30 | _sites: 31 | - zh 32 | 33 | _section: system 34 | 35 | _files: 36 | - Gadget-libJQuery.js 37 | -------------------------------------------------------------------------------- /src/gadgets/libJSON5/.eslintrc.yaml: -------------------------------------------------------------------------------- 1 | ignorePatterns: 2 | - Gadget-libJSON5.js 3 | -------------------------------------------------------------------------------- /src/gadgets/libJSON5/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: true 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: 24 | - hidden 25 | 26 | peers: [] 27 | 28 | dependencies: [] 29 | 30 | _sites: 31 | - zh 32 | 33 | _section: system 34 | 35 | _files: 36 | - Gadget-libJSON5.js 37 | -------------------------------------------------------------------------------- /src/gadgets/libOOUIDialog/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: true 4 | 5 | default: true 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: 24 | - hidden 25 | 26 | peers: [] 27 | 28 | dependencies: 29 | - oojs-ui 30 | - oojs-ui-core 31 | - oojs-ui-core.styles 32 | - oojs-ui-widgets 33 | - oojs-ui-toolbars 34 | - oojs-ui-windows 35 | - oojs-ui.styles.indicators 36 | - oojs-ui.styles.icons-accessibility 37 | - oojs-ui.styles.icons-alerts 38 | - oojs-ui.styles.icons-content 39 | - oojs-ui.styles.icons-editing-advanced 40 | - oojs-ui.styles.icons-editing-core 41 | - oojs-ui.styles.icons-editing-list 42 | - oojs-ui.styles.icons-editing-styling 43 | - oojs-ui.styles.icons-interactions 44 | - oojs-ui.styles.icons-layout 45 | - oojs-ui.styles.icons-location 46 | - oojs-ui.styles.icons-media 47 | - oojs-ui.styles.icons-moderation 48 | - oojs-ui.styles.icons-movement 49 | - oojs-ui.styles.icons-user 50 | - oojs-ui.styles.icons-wikimedia 51 | - ext.gadget.libPolyfill 52 | 53 | _sites: 54 | - zh 55 | - commons 56 | 57 | _section: system 58 | 59 | _files: 60 | - Gadget-libOOUIDialog.js 61 | -------------------------------------------------------------------------------- /src/gadgets/libPolyfill/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: true 4 | 5 | default: true 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: [] 24 | 25 | peers: [] 26 | 27 | dependencies: [] 28 | 29 | _sites: 30 | - zh 31 | - commons 32 | 33 | _section: system 34 | 35 | _files: 36 | - Gadget-libPolyfill-Array.prototype.at.js 37 | - Gadget-libPolyfill-String.prototype.at.js 38 | - Gadget-libPolyfill-TypedArray.prototype.at.js 39 | - Gadget-libPolyfill-crypto.randomUUID.js 40 | -------------------------------------------------------------------------------- /src/gadgets/libUtil/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: true 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: 24 | - hidden 25 | 26 | peers: [] 27 | 28 | dependencies: [] 29 | 30 | _sites: 31 | - zh 32 | 33 | _section: system 34 | 35 | _files: 36 | - Gadget-libUtil.js 37 | -------------------------------------------------------------------------------- /src/gadgets/libip/.eslintrc.yaml: -------------------------------------------------------------------------------- 1 | ignorePatterns: 2 | - Gadget-libip.js 3 | -------------------------------------------------------------------------------- /src/gadgets/libip/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: true 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: 24 | - hidden 25 | 26 | peers: [] 27 | 28 | dependencies: [] 29 | 30 | _sites: 31 | - zh 32 | 33 | _section: system 34 | 35 | _files: 36 | - Gadget-libip.js 37 | -------------------------------------------------------------------------------- /src/gadgets/localforage/.eslintrc.yaml: -------------------------------------------------------------------------------- 1 | ignorePatterns: 2 | - Gadget-localforage.js 3 | -------------------------------------------------------------------------------- /src/gadgets/localforage/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: true 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: 24 | - hidden 25 | 26 | peers: [] 27 | 28 | dependencies: [] 29 | 30 | _sites: 31 | - zh 32 | 33 | _section: system 34 | 35 | _files: 36 | - Gadget-localforage.js 37 | -------------------------------------------------------------------------------- /src/gadgets/moeskin-classic/Gadget-moeskin-classic.css: -------------------------------------------------------------------------------- 1 | /* 2 | * MoeSkin Classic Edition 3 | */ 4 | 5 | body.skin-moeskin .moe-flexible-container { 6 | margin-left: 1rem; 7 | margin-right: 1rem; 8 | width: 100%; 9 | } 10 | 11 | body.skin-moeskin #moe-main-container main { 12 | flex-direction: row-reverse; 13 | } 14 | 15 | body.skin-moeskin #moe-global-footer-top { 16 | flex-direction: row; 17 | } 18 | 19 | body.skin-moeskin #moe-page-tools-container { 20 | left: 0; 21 | right: unset; 22 | } 23 | 24 | body.skin-moeskin #moe-bg-container { 25 | height: calc(20vh + 60px); 26 | } -------------------------------------------------------------------------------- /src/gadgets/moeskin-classic/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: false 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: 10 | - moeskin 11 | 12 | actions: [] 13 | 14 | categories: [] 15 | 16 | namespaces: [] 17 | 18 | contentModels: [] 19 | 20 | type: styles 21 | 22 | package: false 23 | 24 | rights: 25 | - disabled 26 | 27 | peers: [] 28 | 29 | dependencies: [] 30 | 31 | _sites: 32 | - zh 33 | 34 | _section: skin 35 | 36 | _files: 37 | - Gadget-moeskin-classic.css 38 | -------------------------------------------------------------------------------- /src/gadgets/moeskin-styles/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: true 4 | 5 | default: true 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: 10 | - moeskin 11 | 12 | actions: [] 13 | 14 | categories: [] 15 | 16 | namespaces: [] 17 | 18 | contentModels: [] 19 | 20 | type: styles 21 | 22 | package: false 23 | 24 | rights: [] 25 | 26 | peers: [] 27 | 28 | dependencies: [] 29 | 30 | _sites: 31 | - zh 32 | 33 | _section: system 34 | 35 | _files: 36 | - Gadget-moeskin-styles.css 37 | -------------------------------------------------------------------------------- /src/gadgets/moeskin-topbar/Gadget-moeskin-topbar.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable promise/catch-or-return */ 2 | "use strict"; 3 | Promise.all( 4 | ["moeskin.instance", "moeskin.stores"].map((name) => new Promise(mw.hook(name).add)), 5 | ).then((payload) => { 6 | const skin = payload[0]; 7 | const stores = payload[1]; 8 | const { topbar } = stores.useNavigationStore(skin.pinia); 9 | topbar[0].children = [ 10 | ...topbar[0].children, 11 | { 12 | href: "/Special:最新页面", 13 | text: wgULS("最新页面", "最新頁面"), 14 | }, 15 | { 16 | href: "/Special:日志", 17 | text: wgULS("所有日志", "所有日誌"), 18 | }, 19 | { 20 | href: "/Category:积压工作", 21 | text: wgULS("积压工作", "積壓工作"), 22 | }, 23 | ]; 24 | }); 25 | -------------------------------------------------------------------------------- /src/gadgets/moeskin-topbar/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: false 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: 10 | - moeskin 11 | 12 | actions: [] 13 | 14 | categories: [] 15 | 16 | namespaces: [] 17 | 18 | contentModels: [] 19 | 20 | type: general 21 | 22 | package: false 23 | 24 | rights: 25 | - patrol 26 | 27 | peers: [] 28 | 29 | dependencies: 30 | - ext.gadget.site-lib 31 | 32 | _sites: 33 | - zh 34 | 35 | _section: skin 36 | 37 | _files: 38 | - Gadget-moeskin-topbar.js 39 | -------------------------------------------------------------------------------- /src/gadgets/moveToUserSubpage/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: false 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: 16 | - 0 17 | - 10 18 | - 828 19 | 20 | contentModels: [] 21 | 22 | type: general 23 | 24 | package: false 25 | 26 | rights: 27 | - edit 28 | - patrol 29 | 30 | peers: [] 31 | 32 | dependencies: 33 | - ext.gadget.site-lib 34 | - ext.gadget.libOOUIDialog 35 | - mediawiki.api 36 | - ext.gadget.libPolyfill 37 | 38 | _sites: 39 | - zh 40 | 41 | _section: maintenance 42 | 43 | _files: 44 | - Gadget-moveToUserSubpage.js 45 | -------------------------------------------------------------------------------- /src/gadgets/mwPanel/Gadget-mwPanel.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | //
     3 | $(() => {
     4 |     const wgPageName = mw.config.get("wgRelevantPageName");
     5 |     const items = {
     6 |         "#t-upload": {
     7 |             "t-expandtemplates": `
  • ${wgULS("展开模板", "展開模板")}
  • `, 8 | "t-prefixindex": `
  • ${wgULS("前缀页面", "按詞頭查詢頁面")}
  • `, 9 | "t-pagelog": `
  • ${wgULS("页面日志", "頁面日誌")}
  • `, 10 | "t-replacetext": `
  • ${wgULS("替换文本", "取代文字")}
  • `, 11 | }, 12 | "#n-recentchanges": { 13 | "n-log": `
  • ${wgULS("所有日志", "所有日誌")}
  • `, 14 | }, 15 | }; 16 | for (const t in items) { 17 | const target = $(t); 18 | for (const i in items[t]) { 19 | if (!document.getElementById(i)) { 20 | target.after(items[t][i]); 21 | } 22 | } 23 | } 24 | mw.loader.addStyleTag("#t-expandtemplates, #t-userlog, .ns-2 #t-pagelog, .ns-3 #t-pagelog, .ns--1 #t-pagelog {display:none;}.ns-10 #t-expandtemplates, .ns-2 #t-userlog, .ns-3 #t-userlog {display:list-item!important;}"); 25 | $("#t-log a").text(wgULS("用户日志", "使用者日誌", null, null, "用戶日誌")); 26 | }); 27 | //
    28 | -------------------------------------------------------------------------------- /src/gadgets/mwPanel/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: false 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: 10 | - vector-2022 11 | 12 | actions: [] 13 | 14 | categories: [] 15 | 16 | namespaces: [] 17 | 18 | contentModels: [] 19 | 20 | type: general 21 | 22 | package: false 23 | 24 | rights: [] 25 | 26 | peers: [] 27 | 28 | dependencies: 29 | - ext.gadget.site-lib 30 | 31 | _sites: 32 | - zh 33 | 34 | _section: skin 35 | 36 | _files: 37 | - Gadget-mwPanel.js 38 | -------------------------------------------------------------------------------- /src/gadgets/noteTA/Gadget-noteTA.css: -------------------------------------------------------------------------------- 1 | /** 2 | * @source https://zh.wikipedia.org/wiki/_?oldid=22973238 3 | * 更新后请同步更新上面链接到最新版本 4 | */ 5 | /* 6 | * 引自 https://zh.wikipedia.org/wiki/MediaWiki:Gadget-noteTA.css 7 | * User:AnnAngela做了整合 8 | */ 9 | #noteTA-lang { 10 | background: #36C; 11 | color: white; 12 | text-align: center; 13 | padding: .5rem; 14 | position: fixed; 15 | top: 0; 16 | left: 0; 17 | right: 0; 18 | z-index: 9999; 19 | } 20 | 21 | [id^="mobile-noteTA-" i] { 22 | cursor: pointer; 23 | } 24 | 25 | /* 只有打开小工具才有的按钮动画, written by User:机智的小鱼君 */ 26 | .noteTAViewer-button:hover { 27 | border-color: #36ad6a; 28 | color: #36ad6a; 29 | } 30 | 31 | .noteTAViewer-button:active { 32 | border-color: #0c7a43; 33 | color: #0c7a43; 34 | } 35 | 36 | .noteTAViewer-button::after { 37 | content: ""; 38 | position: absolute; 39 | left: 0; 40 | top: 0; 41 | width: 100%; 42 | height: 100%; 43 | box-shadow: 0 0 0 6px #36ad6a; 44 | opacity: 0; 45 | transition: all 0.4s ease; 46 | border-radius: 100vw; 47 | } 48 | 49 | .noteTAViewer-button:active::after { 50 | transition: 0s; 51 | box-shadow: 0 0 0 1px #36ad6a; 52 | opacity: 1; 53 | } 54 | -------------------------------------------------------------------------------- /src/gadgets/noteTA/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: false 4 | 5 | default: true 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: [] 24 | 25 | peers: [] 26 | 27 | dependencies: 28 | - mediawiki.api 29 | - ext.gadget.site-lib 30 | - jquery.makeCollapsible 31 | - mediawiki.Uri 32 | - jquery.ui 33 | 34 | _sites: 35 | - zh 36 | 37 | _section: browsing 38 | 39 | _files: 40 | - Gadget-noteTA.css 41 | - Gadget-noteTA.js 42 | -------------------------------------------------------------------------------- /src/gadgets/noticeActivity/Gadget-noticeActivity.css: -------------------------------------------------------------------------------- 1 | #notice-activity { 2 | display: none; 3 | } -------------------------------------------------------------------------------- /src/gadgets/noticeActivity/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: false 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: 10 | - vector-2022 11 | 12 | actions: [] 13 | 14 | categories: [] 15 | 16 | namespaces: [] 17 | 18 | contentModels: [] 19 | 20 | type: styles 21 | 22 | package: false 23 | 24 | rights: [] 25 | 26 | peers: [] 27 | 28 | dependencies: [] 29 | 30 | _sites: 31 | - zh 32 | 33 | _section: browsing 34 | 35 | _files: 36 | - Gadget-noticeActivity.css 37 | -------------------------------------------------------------------------------- /src/gadgets/patrolCount/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: false 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: 10 | - vector-2022 11 | 12 | actions: 13 | - view 14 | 15 | categories: [] 16 | 17 | namespaces: [] 18 | 19 | contentModels: [] 20 | 21 | type: general 22 | 23 | package: false 24 | 25 | rights: 26 | - patrol 27 | 28 | peers: [] 29 | 30 | dependencies: 31 | - ext.gadget.site-lib 32 | 33 | _sites: 34 | - zh 35 | 36 | _section: maintenance 37 | 38 | _files: 39 | - Gadget-patrolCount.js 40 | -------------------------------------------------------------------------------- /src/gadgets/patrolPlus/Gadget-patrolPlus.css: -------------------------------------------------------------------------------- 1 | body.patrolPlusRunning .patrolLink:not(.running) { 2 | color: #aaa; 3 | text-decoration: none; 4 | } 5 | -------------------------------------------------------------------------------- /src/gadgets/patrolPlus/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: false 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: 24 | - patrol 25 | 26 | peers: [] 27 | 28 | dependencies: 29 | - mediawiki.api 30 | - mediawiki.Uri 31 | 32 | _sites: 33 | - zh 34 | 35 | _section: maintenance 36 | 37 | _files: 38 | - Gadget-patrolPlus.js 39 | - Gadget-patrolPlus.css 40 | -------------------------------------------------------------------------------- /src/gadgets/prism-core/.eslintrc.yaml: -------------------------------------------------------------------------------- 1 | ignorePatterns: 2 | - Gadget-prism-core.js 3 | - Gadget-prism-line-numbers.js 4 | - Gadget-prism-inline-color.js 5 | -------------------------------------------------------------------------------- /src/gadgets/prism-core/Gadget-prism-line-numbers.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Generated by scripts/prefetch/index.js 3 | * Options: 4 | * type: "npm" 5 | * gadget: { "name": "prism-core", "fileName": "Gadget-prism-line-numbers.css" } 6 | * moduleName: "prismjs" 7 | * distFilePath: "plugins/line-numbers/prism-line-numbers.css" 8 | * version: "1" 9 | * jsdelivrUrl: "https://cdn.jsdelivr.net/npm/prismjs@1/plugins/line-numbers/prism-line-numbers.css" 10 | */ 11 | pre[class*="language-"].line-numbers { 12 | position: relative; 13 | padding-left: 3.8em; 14 | counter-reset: linenumber; 15 | } 16 | 17 | pre[class*="language-"].line-numbers > code { 18 | position: relative; 19 | white-space: inherit; 20 | } 21 | 22 | .line-numbers .line-numbers-rows { 23 | position: absolute; 24 | pointer-events: none; 25 | top: 0; 26 | font-size: 100%; 27 | left: -3.8em; 28 | width: 3em; /* works for line-numbers below 1000 lines */ 29 | letter-spacing: -1px; 30 | border-right: 1px solid #999; 31 | 32 | -webkit-user-select: none; 33 | -moz-user-select: none; 34 | -ms-user-select: none; 35 | user-select: none; 36 | 37 | } 38 | 39 | .line-numbers-rows > span { 40 | display: block; 41 | counter-increment: linenumber; 42 | } 43 | 44 | .line-numbers-rows > span:before { 45 | content: counter(linenumber); 46 | color: #999; 47 | display: block; 48 | padding-right: 0.8em; 49 | text-align: right; 50 | } 51 | 52 | -------------------------------------------------------------------------------- /src/gadgets/prism-core/Gadget-prism-loader.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | window.Prism = { manual: true }; 3 | -------------------------------------------------------------------------------- /src/gadgets/prism-core/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: true 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: 24 | - hidden 25 | 26 | peers: [] 27 | 28 | dependencies: [] 29 | 30 | _sites: 31 | - zh 32 | - commons 33 | 34 | _section: system 35 | 36 | _files: 37 | - Gadget-prism-loader.js 38 | - Gadget-prism-core.js 39 | - Gadget-prism-coy.css 40 | 41 | - Gadget-prism-line-numbers.js 42 | - Gadget-prism-line-numbers.css 43 | -------------------------------------------------------------------------------- /src/gadgets/prism-language-bash/.eslintrc.yaml: -------------------------------------------------------------------------------- 1 | ignorePatterns: 2 | - Gadget-prism-language-bash.js 3 | -------------------------------------------------------------------------------- /src/gadgets/prism-language-bash/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: true 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: 24 | - hidden 25 | 26 | peers: [] 27 | 28 | dependencies: 29 | - ext.gadget.prism-core 30 | 31 | _sites: 32 | - zh 33 | - commons 34 | 35 | _section: system 36 | 37 | _files: 38 | - Gadget-prism-language-bash.js 39 | -------------------------------------------------------------------------------- /src/gadgets/prism-language-c/.eslintrc.yaml: -------------------------------------------------------------------------------- 1 | ignorePatterns: 2 | - Gadget-prism-language-c.js 3 | -------------------------------------------------------------------------------- /src/gadgets/prism-language-c/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: true 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: 24 | - hidden 25 | 26 | peers: [] 27 | 28 | dependencies: 29 | - ext.gadget.prism-core 30 | - ext.gadget.prism-language-clike 31 | 32 | _sites: 33 | - zh 34 | - commons 35 | 36 | _section: system 37 | 38 | _files: 39 | - Gadget-prism-language-c.js 40 | -------------------------------------------------------------------------------- /src/gadgets/prism-language-clike/.eslintrc.yaml: -------------------------------------------------------------------------------- 1 | ignorePatterns: 2 | - Gadget-prism-language-clike.js 3 | -------------------------------------------------------------------------------- /src/gadgets/prism-language-clike/Gadget-prism-language-clike.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Generated by scripts/prefetch/index.js 3 | * Options: 4 | * type: "npm" 5 | * gadget: { "name": "prism-language-clike", "fileName": "Gadget-prism-language-clike.js" } 6 | * moduleName: "prismjs" 7 | * distFilePath: "components/prism-clike.js" 8 | * version: "1" 9 | * jsdelivrUrl: "https://cdn.jsdelivr.net/npm/prismjs@1/components/prism-clike.js" 10 | */ 11 | Prism.languages.clike = { 12 | 'comment': [ 13 | { 14 | pattern: /(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/, 15 | lookbehind: true, 16 | greedy: true 17 | }, 18 | { 19 | pattern: /(^|[^\\:])\/\/.*/, 20 | lookbehind: true, 21 | greedy: true 22 | } 23 | ], 24 | 'string': { 25 | pattern: /(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/, 26 | greedy: true 27 | }, 28 | 'class-name': { 29 | pattern: /(\b(?:class|extends|implements|instanceof|interface|new|trait)\s+|\bcatch\s+\()[\w.\\]+/i, 30 | lookbehind: true, 31 | inside: { 32 | 'punctuation': /[.\\]/ 33 | } 34 | }, 35 | 'keyword': /\b(?:break|catch|continue|do|else|finally|for|function|if|in|instanceof|new|null|return|throw|try|while)\b/, 36 | 'boolean': /\b(?:false|true)\b/, 37 | 'function': /\b\w+(?=\()/, 38 | 'number': /\b0x[\da-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?/i, 39 | 'operator': /[<>]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/, 40 | 'punctuation': /[{}[\];(),.:]/ 41 | }; 42 | 43 | -------------------------------------------------------------------------------- /src/gadgets/prism-language-clike/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: true 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: 24 | - hidden 25 | 26 | peers: [] 27 | 28 | dependencies: 29 | - ext.gadget.prism-core 30 | 31 | _sites: 32 | - zh 33 | - commons 34 | 35 | _section: system 36 | 37 | _files: 38 | - Gadget-prism-language-clike.js 39 | -------------------------------------------------------------------------------- /src/gadgets/prism-language-coffeescript/.eslintrc.yaml: -------------------------------------------------------------------------------- 1 | ignorePatterns: 2 | - Gadget-prism-language-coffeescript.js 3 | -------------------------------------------------------------------------------- /src/gadgets/prism-language-coffeescript/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: true 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: 24 | - hidden 25 | 26 | peers: [] 27 | 28 | dependencies: 29 | - ext.gadget.prism-core 30 | - ext.gadget.prism-language-javascript 31 | 32 | _sites: 33 | - zh 34 | - commons 35 | 36 | _section: system 37 | 38 | _files: 39 | - Gadget-prism-language-coffeescript.js 40 | -------------------------------------------------------------------------------- /src/gadgets/prism-language-cpp/.eslintrc.yaml: -------------------------------------------------------------------------------- 1 | ignorePatterns: 2 | - Gadget-prism-language-cpp.js 3 | -------------------------------------------------------------------------------- /src/gadgets/prism-language-cpp/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: true 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: 24 | - hidden 25 | 26 | peers: [] 27 | 28 | dependencies: 29 | - ext.gadget.prism-core 30 | - ext.gadget.prism-language-c 31 | 32 | _sites: 33 | - zh 34 | - commons 35 | 36 | _section: system 37 | 38 | _files: 39 | - Gadget-prism-language-cpp.js 40 | -------------------------------------------------------------------------------- /src/gadgets/prism-language-csharp/.eslintrc.yaml: -------------------------------------------------------------------------------- 1 | ignorePatterns: 2 | - Gadget-prism-language-csharp.js 3 | -------------------------------------------------------------------------------- /src/gadgets/prism-language-csharp/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: true 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: 24 | - hidden 25 | 26 | peers: [] 27 | 28 | dependencies: 29 | - ext.gadget.prism-core 30 | - ext.gadget.prism-language-clike 31 | 32 | _sites: 33 | - zh 34 | - commons 35 | 36 | _section: system 37 | 38 | _files: 39 | - Gadget-prism-language-csharp.js 40 | -------------------------------------------------------------------------------- /src/gadgets/prism-language-css/.eslintrc.yaml: -------------------------------------------------------------------------------- 1 | ignorePatterns: 2 | - Gadget-prism-language-css.js 3 | - Gadget-prism-language-css-extras.js 4 | -------------------------------------------------------------------------------- /src/gadgets/prism-language-css/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: true 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: 24 | - hidden 25 | 26 | peers: [] 27 | 28 | dependencies: 29 | - ext.gadget.prism-core 30 | 31 | _sites: 32 | - zh 33 | - commons 34 | 35 | _section: system 36 | 37 | _files: 38 | - Gadget-prism-language-css.js 39 | - Gadget-prism-language-css-extras.js 40 | -------------------------------------------------------------------------------- /src/gadgets/prism-language-java/.eslintrc.yaml: -------------------------------------------------------------------------------- 1 | ignorePatterns: 2 | - Gadget-prism-language-java.js 3 | -------------------------------------------------------------------------------- /src/gadgets/prism-language-java/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: true 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: 24 | - hidden 25 | 26 | peers: [] 27 | 28 | dependencies: 29 | - ext.gadget.prism-core 30 | - ext.gadget.prism-language-clike 31 | 32 | _sites: 33 | - zh 34 | - commons 35 | 36 | _section: system 37 | 38 | _files: 39 | - Gadget-prism-language-java.js 40 | -------------------------------------------------------------------------------- /src/gadgets/prism-language-javascript/.eslintrc.yaml: -------------------------------------------------------------------------------- 1 | ignorePatterns: 2 | - Gadget-prism-language-javascript.js 3 | - Gadget-prism-language-javascript-extras.js 4 | -------------------------------------------------------------------------------- /src/gadgets/prism-language-javascript/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: true 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: 24 | - hidden 25 | 26 | peers: [] 27 | 28 | dependencies: 29 | - ext.gadget.prism-core 30 | - ext.gadget.prism-language-clike 31 | 32 | _sites: 33 | - zh 34 | - commons 35 | 36 | _section: system 37 | 38 | _files: 39 | - Gadget-prism-language-javascript.js 40 | - Gadget-prism-language-javascript-extras.js 41 | -------------------------------------------------------------------------------- /src/gadgets/prism-language-json/.eslintrc.yaml: -------------------------------------------------------------------------------- 1 | ignorePatterns: 2 | - Gadget-prism-language-json.js 3 | - Gadget-prism-language-json5.js 4 | -------------------------------------------------------------------------------- /src/gadgets/prism-language-json/Gadget-prism-language-json.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Generated by scripts/prefetch/index.js 3 | * Options: 4 | * type: "npm" 5 | * gadget: { "name": "prism-language-json", "fileName": "Gadget-prism-language-json.js" } 6 | * moduleName: "prismjs" 7 | * distFilePath: "components/prism-json.js" 8 | * version: "1" 9 | * jsdelivrUrl: "https://cdn.jsdelivr.net/npm/prismjs@1/components/prism-json.js" 10 | */ 11 | // https://www.json.org/json-en.html 12 | Prism.languages.json = { 13 | 'property': { 14 | pattern: /(^|[^\\])"(?:\\.|[^\\"\r\n])*"(?=\s*:)/, 15 | lookbehind: true, 16 | greedy: true 17 | }, 18 | 'string': { 19 | pattern: /(^|[^\\])"(?:\\.|[^\\"\r\n])*"(?!\s*:)/, 20 | lookbehind: true, 21 | greedy: true 22 | }, 23 | 'comment': { 24 | pattern: /\/\/.*|\/\*[\s\S]*?(?:\*\/|$)/, 25 | greedy: true 26 | }, 27 | 'number': /-?\b\d+(?:\.\d+)?(?:e[+-]?\d+)?\b/i, 28 | 'punctuation': /[{}[\],]/, 29 | 'operator': /:/, 30 | 'boolean': /\b(?:false|true)\b/, 31 | 'null': { 32 | pattern: /\bnull\b/, 33 | alias: 'keyword' 34 | } 35 | }; 36 | 37 | Prism.languages.webmanifest = Prism.languages.json; 38 | 39 | -------------------------------------------------------------------------------- /src/gadgets/prism-language-json/Gadget-prism-language-json5.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Generated by scripts/prefetch/index.js 3 | * Options: 4 | * type: "npm" 5 | * gadget: { "name": "prism-language-json", "fileName": "Gadget-prism-language-json5.js" } 6 | * moduleName: "prismjs" 7 | * distFilePath: "components/prism-json5.js" 8 | * version: "1" 9 | * jsdelivrUrl: "https://cdn.jsdelivr.net/npm/prismjs@1/components/prism-json5.js" 10 | */ 11 | (function (Prism) { 12 | 13 | var string = /("|')(?:\\(?:\r\n?|\n|.)|(?!\1)[^\\\r\n])*\1/; 14 | 15 | Prism.languages.json5 = Prism.languages.extend('json', { 16 | 'property': [ 17 | { 18 | pattern: RegExp(string.source + '(?=\\s*:)'), 19 | greedy: true 20 | }, 21 | { 22 | pattern: /(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*:)/, 23 | alias: 'unquoted' 24 | } 25 | ], 26 | 'string': { 27 | pattern: string, 28 | greedy: true 29 | }, 30 | 'number': /[+-]?\b(?:NaN|Infinity|0x[a-fA-F\d]+)\b|[+-]?(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:[eE][+-]?\d+\b)?/ 31 | }); 32 | 33 | }(Prism)); 34 | 35 | -------------------------------------------------------------------------------- /src/gadgets/prism-language-json/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: true 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: 24 | - hidden 25 | 26 | peers: [] 27 | 28 | dependencies: 29 | - ext.gadget.prism-core 30 | 31 | _sites: 32 | - zh 33 | - commons 34 | 35 | _section: system 36 | 37 | _files: 38 | - Gadget-prism-language-json.js 39 | - Gadget-prism-language-json5.js 40 | -------------------------------------------------------------------------------- /src/gadgets/prism-language-latex/.eslintrc.yaml: -------------------------------------------------------------------------------- 1 | ignorePatterns: 2 | - Gadget-prism-language-latex.js 3 | -------------------------------------------------------------------------------- /src/gadgets/prism-language-latex/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: true 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: 24 | - hidden 25 | 26 | peers: [] 27 | 28 | dependencies: 29 | - ext.gadget.prism-core 30 | 31 | _sites: 32 | - zh 33 | - commons 34 | 35 | _section: system 36 | 37 | _files: 38 | - Gadget-prism-language-latex.js 39 | -------------------------------------------------------------------------------- /src/gadgets/prism-language-lua/.eslintrc.yaml: -------------------------------------------------------------------------------- 1 | ignorePatterns: 2 | - Gadget-prism-language-lua.js 3 | -------------------------------------------------------------------------------- /src/gadgets/prism-language-lua/Gadget-prism-language-lua.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Generated by scripts/prefetch/index.js 3 | * Options: 4 | * type: "npm" 5 | * gadget: { "name": "prism-language-lua", "fileName": "Gadget-prism-language-lua.js" } 6 | * moduleName: "prismjs" 7 | * distFilePath: "components/prism-lua.js" 8 | * version: "1" 9 | * jsdelivrUrl: "https://cdn.jsdelivr.net/npm/prismjs@1/components/prism-lua.js" 10 | */ 11 | Prism.languages.lua = { 12 | 'comment': /^#!.+|--(?:\[(=*)\[[\s\S]*?\]\1\]|.*)/m, 13 | // \z may be used to skip the following space 14 | 'string': { 15 | pattern: /(["'])(?:(?!\1)[^\\\r\n]|\\z(?:\r\n|\s)|\\(?:\r\n|[^z]))*\1|\[(=*)\[[\s\S]*?\]\2\]/, 16 | greedy: true 17 | }, 18 | 'number': /\b0x[a-f\d]+(?:\.[a-f\d]*)?(?:p[+-]?\d+)?\b|\b\d+(?:\.\B|(?:\.\d*)?(?:e[+-]?\d+)?\b)|\B\.\d+(?:e[+-]?\d+)?\b/i, 19 | 'keyword': /\b(?:and|break|do|else|elseif|end|false|for|function|goto|if|in|local|nil|not|or|repeat|return|then|true|until|while)\b/, 20 | 'function': /(?!\d)\w+(?=\s*(?:[({]))/, 21 | 'operator': [ 22 | /[-+*%^&|#]|\/\/?|<[<=]?|>[>=]?|[=~]=?/, 23 | { 24 | // Match ".." but don't break "..." 25 | pattern: /(^|[^.])\.\.(?!\.)/, 26 | lookbehind: true 27 | } 28 | ], 29 | 'punctuation': /[\[\](){},;]|\.+|:+/ 30 | }; 31 | 32 | -------------------------------------------------------------------------------- /src/gadgets/prism-language-lua/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: true 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: 24 | - hidden 25 | 26 | peers: [] 27 | 28 | dependencies: 29 | - ext.gadget.prism-core 30 | 31 | _sites: 32 | - zh 33 | - commons 34 | 35 | _section: system 36 | 37 | _files: 38 | - Gadget-prism-language-lua.js 39 | -------------------------------------------------------------------------------- /src/gadgets/prism-language-markup/.eslintrc.yaml: -------------------------------------------------------------------------------- 1 | ignorePatterns: 2 | - Gadget-prism-language-markup.js 3 | -------------------------------------------------------------------------------- /src/gadgets/prism-language-markup/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: true 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: 24 | - hidden 25 | 26 | peers: [] 27 | 28 | dependencies: 29 | - ext.gadget.prism-core 30 | 31 | _sites: 32 | - zh 33 | - commons 34 | 35 | _section: system 36 | 37 | _files: 38 | - Gadget-prism-language-markup.js 39 | -------------------------------------------------------------------------------- /src/gadgets/prism-language-perl/.eslintrc.yaml: -------------------------------------------------------------------------------- 1 | ignorePatterns: 2 | - Gadget-prism-language-perl.js 3 | -------------------------------------------------------------------------------- /src/gadgets/prism-language-perl/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: true 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: 24 | - hidden 25 | 26 | peers: [] 27 | 28 | dependencies: 29 | - ext.gadget.prism-core 30 | 31 | _sites: 32 | - zh 33 | - commons 34 | 35 | _section: system 36 | 37 | _files: 38 | - Gadget-prism-language-perl.js 39 | -------------------------------------------------------------------------------- /src/gadgets/prism-language-php/.eslintrc.yaml: -------------------------------------------------------------------------------- 1 | ignorePatterns: 2 | - Gadget-prism-language-markup-templating.js 3 | - Gadget-prism-language-php.js 4 | - Gadget-prism-language-php-extras.js 5 | -------------------------------------------------------------------------------- /src/gadgets/prism-language-php/Gadget-prism-language-php-extras.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Generated by scripts/prefetch/index.js 3 | * Options: 4 | * type: "npm" 5 | * gadget: { "name": "prism-language-php", "fileName": "Gadget-prism-language-php-extras.js" } 6 | * moduleName: "prismjs" 7 | * distFilePath: "components/prism-php-extras.js" 8 | * version: "1" 9 | * jsdelivrUrl: "https://cdn.jsdelivr.net/npm/prismjs@1/components/prism-php-extras.js" 10 | */ 11 | Prism.languages.insertBefore('php', 'variable', { 12 | 'this': { 13 | pattern: /\$this\b/, 14 | alias: 'keyword' 15 | }, 16 | 'global': /\$(?:GLOBALS|HTTP_RAW_POST_DATA|_(?:COOKIE|ENV|FILES|GET|POST|REQUEST|SERVER|SESSION)|argc|argv|http_response_header|php_errormsg)\b/, 17 | 'scope': { 18 | pattern: /\b[\w\\]+::/, 19 | inside: { 20 | 'keyword': /\b(?:parent|self|static)\b/, 21 | 'punctuation': /::|\\/ 22 | } 23 | } 24 | }); 25 | 26 | -------------------------------------------------------------------------------- /src/gadgets/prism-language-php/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: true 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: 24 | - hidden 25 | 26 | peers: [] 27 | 28 | dependencies: 29 | - ext.gadget.prism-core 30 | 31 | _sites: 32 | - zh 33 | - commons 34 | 35 | _section: system 36 | 37 | _files: 38 | - Gadget-prism-language-markup-templating.js 39 | - Gadget-prism-language-php.js 40 | - Gadget-prism-language-php-extras.js 41 | -------------------------------------------------------------------------------- /src/gadgets/prism-language-python/.eslintrc.yaml: -------------------------------------------------------------------------------- 1 | ignorePatterns: 2 | - Gadget-prism-language-python.js 3 | -------------------------------------------------------------------------------- /src/gadgets/prism-language-python/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: true 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: 24 | - hidden 25 | 26 | peers: [] 27 | 28 | dependencies: 29 | - ext.gadget.prism-core 30 | 31 | _sites: 32 | - zh 33 | - commons 34 | 35 | _section: system 36 | 37 | _files: 38 | - Gadget-prism-language-python.js 39 | -------------------------------------------------------------------------------- /src/gadgets/prism-language-regex/.eslintrc.yaml: -------------------------------------------------------------------------------- 1 | ignorePatterns: 2 | - Gadget-prism-language-regex.js 3 | -------------------------------------------------------------------------------- /src/gadgets/prism-language-regex/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: true 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: 24 | - hidden 25 | 26 | peers: [] 27 | 28 | dependencies: 29 | - ext.gadget.prism-core 30 | 31 | _sites: 32 | - zh 33 | - commons 34 | 35 | _section: system 36 | 37 | _files: 38 | - Gadget-prism-language-regex.js 39 | -------------------------------------------------------------------------------- /src/gadgets/prism-language-ruby/.eslintrc.yaml: -------------------------------------------------------------------------------- 1 | ignorePatterns: 2 | - Gadget-prism-language-ruby.js 3 | -------------------------------------------------------------------------------- /src/gadgets/prism-language-ruby/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: true 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: 24 | - hidden 25 | 26 | peers: [] 27 | 28 | dependencies: 29 | - ext.gadget.prism-core 30 | - ext.gadget.prism-language-clike 31 | 32 | _sites: 33 | - zh 34 | - commons 35 | 36 | _section: system 37 | 38 | _files: 39 | - Gadget-prism-language-ruby.js 40 | -------------------------------------------------------------------------------- /src/gadgets/prism-language-typescript/.eslintrc.yaml: -------------------------------------------------------------------------------- 1 | ignorePatterns: 2 | - Gadget-prism-language-typescript.js 3 | -------------------------------------------------------------------------------- /src/gadgets/prism-language-typescript/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: true 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: 24 | - hidden 25 | 26 | peers: [] 27 | 28 | dependencies: 29 | - ext.gadget.prism-core 30 | - ext.gadget.prism-language-javascript 31 | 32 | _sites: 33 | - zh 34 | - commons 35 | 36 | _section: system 37 | 38 | _files: 39 | - Gadget-prism-language-typescript.js 40 | -------------------------------------------------------------------------------- /src/gadgets/prism-language-wiki/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: true 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: styles 20 | 21 | package: false 22 | 23 | rights: 24 | - hidden 25 | 26 | peers: [] 27 | 28 | dependencies: 29 | - ext.gadget.libCachedCode 30 | 31 | _sites: 32 | - zh 33 | - commons 34 | 35 | _section: system 36 | 37 | _files: 38 | - Gadget-prism-language-wiki.js 39 | - Gadget-prism-language-wiki.json 40 | -------------------------------------------------------------------------------- /src/gadgets/prism-language-yaml/.eslintrc.yaml: -------------------------------------------------------------------------------- 1 | ignorePatterns: 2 | - Gadget-prism-language-yaml.js 3 | -------------------------------------------------------------------------------- /src/gadgets/prism-language-yaml/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: true 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: 24 | - hidden 25 | 26 | peers: [] 27 | 28 | dependencies: 29 | - ext.gadget.prism-core 30 | 31 | _sites: 32 | - zh 33 | - commons 34 | 35 | _section: system 36 | 37 | _files: 38 | - Gadget-prism-language-yaml.js 39 | -------------------------------------------------------------------------------- /src/gadgets/prism-plugin-javadoclike/.eslintrc.yaml: -------------------------------------------------------------------------------- 1 | ignorePatterns: 2 | - Gadget-prism-plugin-javadoclike.js 3 | -------------------------------------------------------------------------------- /src/gadgets/prism-plugin-javadoclike/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: true 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: 24 | - hidden 25 | 26 | peers: [] 27 | 28 | dependencies: 29 | - ext.gadget.prism-core 30 | 31 | _sites: 32 | - zh 33 | - commons 34 | 35 | _section: system 36 | 37 | _files: 38 | - Gadget-prism-plugin-javadoclike.js 39 | -------------------------------------------------------------------------------- /src/gadgets/prism-plugin-jsdoc/.eslintrc.yaml: -------------------------------------------------------------------------------- 1 | ignorePatterns: 2 | - Gadget-prism-plugin-jsdoc.js 3 | -------------------------------------------------------------------------------- /src/gadgets/prism-plugin-jsdoc/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: true 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: 24 | - hidden 25 | 26 | peers: [] 27 | 28 | dependencies: 29 | - ext.gadget.prism-core 30 | - ext.gadget.prism-plugin-javadoclike 31 | - ext.gadget.prism-language-javascript 32 | - ext.gadget.prism-language-typescript 33 | 34 | _sites: 35 | - zh 36 | - commons 37 | 38 | _section: system 39 | 40 | _files: 41 | - Gadget-prism-plugin-jsdoc.js 42 | -------------------------------------------------------------------------------- /src/gadgets/prism-plugin-match-braces/.eslintrc.yaml: -------------------------------------------------------------------------------- 1 | ignorePatterns: 2 | - Gadget-prism-plugin-match-braces.js 3 | -------------------------------------------------------------------------------- /src/gadgets/prism-plugin-match-braces/Gadget-prism-plugin-match-braces.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Generated by scripts/prefetch/index.js 3 | * Options: 4 | * type: "npm" 5 | * gadget: { "name": "prism-plugin-match-braces", "fileName": "Gadget-prism-plugin-match-braces.css" } 6 | * moduleName: "prismjs" 7 | * distFilePath: "plugins/match-braces/prism-match-braces.css" 8 | * version: "1" 9 | * jsdelivrUrl: "https://cdn.jsdelivr.net/npm/prismjs@1/plugins/match-braces/prism-match-braces.css" 10 | */ 11 | .token.punctuation.brace-hover, 12 | .token.punctuation.brace-selected { 13 | outline: solid 1px; 14 | } 15 | 16 | .rainbow-braces .token.punctuation.brace-level-1, 17 | .rainbow-braces .token.punctuation.brace-level-5, 18 | .rainbow-braces .token.punctuation.brace-level-9 { 19 | color: #E50; 20 | opacity: 1; 21 | } 22 | .rainbow-braces .token.punctuation.brace-level-2, 23 | .rainbow-braces .token.punctuation.brace-level-6, 24 | .rainbow-braces .token.punctuation.brace-level-10 { 25 | color: #0B3; 26 | opacity: 1; 27 | } 28 | .rainbow-braces .token.punctuation.brace-level-3, 29 | .rainbow-braces .token.punctuation.brace-level-7, 30 | .rainbow-braces .token.punctuation.brace-level-11 { 31 | color: #26F; 32 | opacity: 1; 33 | } 34 | .rainbow-braces .token.punctuation.brace-level-4, 35 | .rainbow-braces .token.punctuation.brace-level-8, 36 | .rainbow-braces .token.punctuation.brace-level-12 { 37 | color: #E0E; 38 | opacity: 1; 39 | } 40 | 41 | -------------------------------------------------------------------------------- /src/gadgets/prism-plugin-match-braces/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: true 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: 24 | - hidden 25 | 26 | peers: [] 27 | 28 | dependencies: 29 | - ext.gadget.prism-core 30 | 31 | _sites: 32 | - zh 33 | - commons 34 | 35 | _section: system 36 | 37 | _files: 38 | - Gadget-prism-plugin-match-braces.js 39 | - Gadget-prism-plugin-match-braces.css 40 | -------------------------------------------------------------------------------- /src/gadgets/prism-plugin-phpdoc/.eslintrc.yaml: -------------------------------------------------------------------------------- 1 | ignorePatterns: 2 | - Gadget-prism-plugin-phpdoc.js 3 | -------------------------------------------------------------------------------- /src/gadgets/prism-plugin-phpdoc/Gadget-prism-plugin-phpdoc.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Generated by scripts/prefetch/index.js 3 | * Options: 4 | * type: "npm" 5 | * gadget: { "name": "prism-plugin-phpdoc", "fileName": "Gadget-prism-plugin-phpdoc.js" } 6 | * moduleName: "prismjs" 7 | * distFilePath: "components/prism-phpdoc.js" 8 | * version: "1" 9 | * jsdelivrUrl: "https://cdn.jsdelivr.net/npm/prismjs@1/components/prism-phpdoc.js" 10 | */ 11 | (function (Prism) { 12 | 13 | var typeExpression = /(?:\b[a-zA-Z]\w*|[|\\[\]])+/.source; 14 | 15 | Prism.languages.phpdoc = Prism.languages.extend('javadoclike', { 16 | 'parameter': { 17 | pattern: RegExp('(@(?:global|param|property(?:-read|-write)?|var)\\s+(?:' + typeExpression + '\\s+)?)\\$\\w+'), 18 | lookbehind: true 19 | } 20 | }); 21 | 22 | Prism.languages.insertBefore('phpdoc', 'keyword', { 23 | 'class-name': [ 24 | { 25 | pattern: RegExp('(@(?:global|package|param|property(?:-read|-write)?|return|subpackage|throws|var)\\s+)' + typeExpression), 26 | lookbehind: true, 27 | inside: { 28 | 'keyword': /\b(?:array|bool|boolean|callback|double|false|float|int|integer|mixed|null|object|resource|self|string|true|void)\b/, 29 | 'punctuation': /[|\\[\]()]/ 30 | } 31 | } 32 | ], 33 | }); 34 | 35 | Prism.languages.javadoclike.addSupport('php', Prism.languages.phpdoc); 36 | 37 | }(Prism)); 38 | 39 | -------------------------------------------------------------------------------- /src/gadgets/prism-plugin-phpdoc/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: true 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: 24 | - hidden 25 | 26 | peers: [] 27 | 28 | dependencies: 29 | - ext.gadget.prism-core 30 | - ext.gadget.prism-plugin-javadoclike 31 | - ext.gadget.prism-language-php 32 | 33 | _sites: 34 | - zh 35 | - commons 36 | 37 | _section: system 38 | 39 | _files: 40 | - Gadget-prism-plugin-phpdoc.js 41 | -------------------------------------------------------------------------------- /src/gadgets/prism-plugin-previewers/.eslintrc.yaml: -------------------------------------------------------------------------------- 1 | ignorePatterns: 2 | - Gadget-prism-plugin-previewers.js 3 | -------------------------------------------------------------------------------- /src/gadgets/prism-plugin-previewers/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: true 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: 24 | - hidden 25 | 26 | peers: [] 27 | 28 | dependencies: 29 | - ext.gadget.prism-core 30 | 31 | _sites: 32 | - zh 33 | - commons 34 | 35 | _section: system 36 | 37 | _files: 38 | - Gadget-prism-plugin-previewers.js 39 | - Gadget-prism-plugin-previewers.css 40 | -------------------------------------------------------------------------------- /src/gadgets/prism/Gadget-prism.css: -------------------------------------------------------------------------------- 1 | .line-numbers span.line-numbers-rows { 2 | pointer-events: all; 3 | } 4 | 5 | .line-numbers-rows > span:hover { 6 | background-color: rgb(128 128 128 / 20%); 7 | } 8 | 9 | pre[class*="language-"] { 10 | display: flow-root; 11 | } 12 | -------------------------------------------------------------------------------- /src/gadgets/prism/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: false 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: [] 24 | 25 | peers: [] 26 | 27 | dependencies: 28 | - ext.gadget.prism-core 29 | - ext.gadget.libCachedCode 30 | 31 | _sites: 32 | - zh 33 | - commons 34 | 35 | _section: browsing 36 | 37 | _files: 38 | - Gadget-prism.js 39 | - Gadget-prism.css 40 | -------------------------------------------------------------------------------- /src/gadgets/queryContributions/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: false 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: 24 | - patrol 25 | 26 | peers: [] 27 | 28 | dependencies: 29 | - mediawiki.api 30 | - mediawiki.user 31 | - jquery.tablesorter 32 | - ext.gadget.libPolyfill 33 | - ext.gadget.libCachedCode 34 | 35 | _sites: 36 | - zh 37 | - commons 38 | 39 | _section: user 40 | 41 | _files: 42 | - Gadget-queryContributions.js 43 | -------------------------------------------------------------------------------- /src/gadgets/queryWhatlinkshere/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: false 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: [] 24 | 25 | peers: [] 26 | 27 | dependencies: 28 | - mediawiki.api 29 | 30 | _sites: 31 | - zh 32 | 33 | _section: browsing 34 | 35 | _files: 36 | - Gadget-queryWhatlinkshere.js 37 | -------------------------------------------------------------------------------- /src/gadgets/quickMoveThread/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: false 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: 24 | - edit 25 | - patrol 26 | 27 | peers: [] 28 | 29 | dependencies: 30 | - ext.gadget.libOOUIDialog 31 | - mediawiki.api 32 | - mediawiki.Uri 33 | - ext.gadget.site-lib 34 | - ext.gadget.LocalObjectStorage 35 | - ext.gadget.libPolyfill 36 | 37 | _sites: 38 | - zh 39 | 40 | _section: maintenance 41 | 42 | _files: 43 | - Gadget-quickMoveThread.js 44 | -------------------------------------------------------------------------------- /src/gadgets/quickSave/Gadget-quickSave.css: -------------------------------------------------------------------------------- 1 | .AnnTools_bolb { 2 | font-weight: bold; 3 | } 4 | 5 | .AnnTools_paragraphs { 6 | text-indent: 2em; 7 | } 8 | 9 | .AnnTools_log { 10 | display: flex; 11 | } 12 | 13 | 14 | .AnnTools_log_message { 15 | flex-grow: 1; 16 | } 17 | 18 | .AnnTools_log_status { 19 | flex-shrink: 0; 20 | width: 3em; 21 | text-align: center; 22 | } 23 | 24 | .AnnTools_log-success .AnnTools_log_status { 25 | color: #67CA75; 26 | } 27 | 28 | .AnnTools_log-failed { 29 | color: #FF7272; 30 | } 31 | -------------------------------------------------------------------------------- /src/gadgets/quickSave/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: false 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: 24 | - edit 25 | - patrol 26 | 27 | peers: [] 28 | 29 | dependencies: 30 | - mediawiki.api 31 | - ext.gadget.libPolyfill 32 | - ext.gadget.libOOUIDialog 33 | - ext.gadget.site-lib 34 | 35 | _sites: 36 | - zh 37 | 38 | _section: maintenance 39 | 40 | _files: 41 | - Gadget-quickSave.css 42 | - Gadget-quickSave.js 43 | -------------------------------------------------------------------------------- /src/gadgets/registerToDelete/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: false 4 | 5 | default: true 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: 24 | - edit 25 | - patrol 26 | 27 | peers: [] 28 | 29 | dependencies: 30 | - ext.gadget.libOOUIDialog 31 | - ext.gadget.site-lib 32 | - ext.gadget.LocalObjectStorage 33 | - ext.gadget.libPolyfill 34 | 35 | _sites: 36 | - zh 37 | - commons 38 | 39 | _section: maintenance 40 | 41 | _files: 42 | - Gadget-registerToDelete.js 43 | -------------------------------------------------------------------------------- /src/gadgets/report/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: false 4 | 5 | default: true 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: [] 24 | 25 | peers: [] 26 | 27 | dependencies: 28 | - mediawiki.api 29 | - ext.gadget.libOOUIDialog 30 | - ext.gadget.libBottomRightCorner 31 | - mediawiki.util 32 | - ext.gadget.site-lib 33 | 34 | _sites: 35 | - zh 36 | 37 | _section: browsing 38 | 39 | _files: 40 | - Gadget-report.js 41 | -------------------------------------------------------------------------------- /src/gadgets/rollback-summary/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: false 4 | 5 | default: true 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: 24 | - rollback 25 | 26 | peers: [] 27 | 28 | dependencies: 29 | - ext.gadget.libOOUIDialog 30 | - mediawiki.api 31 | - mediawiki.Uri 32 | - ext.gadget.site-lib 33 | 34 | _sites: 35 | - zh 36 | - commons 37 | 38 | _section: maintenance 39 | 40 | _files: 41 | - Gadget-rollback-summary.js 42 | -------------------------------------------------------------------------------- /src/gadgets/shortlink/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: false 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: 24 | - read 25 | 26 | peers: [] 27 | 28 | dependencies: 29 | - ext.gadget.site-lib 30 | - mediawiki.widgets 31 | 32 | _sites: 33 | - zh 34 | - commons 35 | 36 | _section: browsing 37 | 38 | _files: 39 | - Gadget-shortlink.js 40 | -------------------------------------------------------------------------------- /src/gadgets/sidebarHidden/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: false 4 | 5 | default: true 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: 10 | - vector-2022 11 | 12 | actions: [] 13 | 14 | categories: [] 15 | 16 | namespaces: [] 17 | 18 | contentModels: [] 19 | 20 | type: general 21 | 22 | package: false 23 | 24 | rights: 25 | - disabled 26 | 27 | peers: [] 28 | 29 | dependencies: 30 | - ext.gadget.LocalObjectStorage 31 | 32 | _sites: 33 | - zh 34 | 35 | _section: skin 36 | 37 | _files: 38 | - Gadget-sidebarHidden.css 39 | - Gadget-sidebarHidden.js 40 | -------------------------------------------------------------------------------- /src/gadgets/site-js/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: true 4 | 5 | default: true 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: [] 24 | 25 | peers: [] 26 | 27 | dependencies: 28 | - ext.gadget.libOOUIDialog 29 | - user 30 | - mediawiki.api 31 | - mediawiki.Uri 32 | 33 | _sites: 34 | - zh 35 | 36 | _section: system 37 | 38 | _files: 39 | - Gadget-site-js.js 40 | -------------------------------------------------------------------------------- /src/gadgets/site-lib/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: true 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: 24 | - hidden 25 | 26 | peers: [] 27 | 28 | dependencies: 29 | - mediawiki.util 30 | - ext.gadget.libCachedCode 31 | 32 | _sites: 33 | - zh 34 | - commons 35 | 36 | _section: system 37 | 38 | _files: 39 | - Gadget-site-lib.js 40 | -------------------------------------------------------------------------------- /src/gadgets/site-styles/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: true 4 | 5 | default: true 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: styles 20 | 21 | package: false 22 | 23 | rights: [] 24 | 25 | peers: [] 26 | 27 | dependencies: [] 28 | 29 | _sites: 30 | - zh 31 | 32 | _section: system 33 | 34 | _files: 35 | - Gadget-site-styles.css 36 | -------------------------------------------------------------------------------- /src/gadgets/temp-editcheck/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: false 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: 24 | - edit 25 | - autoconfirmed 26 | - disabled 27 | 28 | peers: [] 29 | 30 | dependencies: 31 | - mediawiki.api 32 | - mediawiki.notification 33 | - mediawiki.notify 34 | 35 | _sites: 36 | - zh 37 | 38 | _section: editing 39 | 40 | _files: 41 | - Gadget-temp-editcheck.js 42 | -------------------------------------------------------------------------------- /src/gadgets/temp-svgFix/Gadget-temp-svgFix.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | $(() => { 3 | // 临时修复svg缩略图损坏 4 | /** 5 | * @type { HTMLImageElement[] } 6 | */ 7 | const svgs = Array.from(document.querySelectorAll('img[src$=".svg.png"], img[data-lazy-src$=".svg.png"]')); 8 | for (const img of svgs) { 9 | try { 10 | const src = img.src || img.dataset.lazySrc; 11 | const url = new mw.Uri(src); 12 | if (url.host !== "img.moegirl.org.cn") { 13 | continue; 14 | } 15 | img.src = src.replace("/thumb/", "/").replace(/\.svg\/[^/]+\.svg\.png$/, ".svg"); 16 | img.removeAttribute("srcset"); 17 | img.removeAttribute("data-lazy-src"); 18 | img.removeAttribute("data-lazy-srcset"); 19 | img.removeAttribute("data-lazy-state"); 20 | img.classList.remove("lazyload"); 21 | img.after(img.cloneNode(true)); 22 | img.remove(); 23 | } catch { } 24 | } 25 | }); 26 | -------------------------------------------------------------------------------- /src/gadgets/temp-svgFix/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: false 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: 24 | - disabled 25 | 26 | peers: [] 27 | 28 | dependencies: 29 | - mediawiki.Uri 30 | 31 | _sites: 32 | - zh 33 | - commons 34 | 35 | _section: browsing 36 | 37 | _files: 38 | - Gadget-temp-svgFix.js 39 | -------------------------------------------------------------------------------- /src/gadgets/uploader/Gadget-uploader.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | $(() => { 3 | if (document.getElementById("wpSave")) { 4 | mw.util.addPortletLink("p-cactions", "https://commons.moegirl.org.cn/MediaWiki:Uploader", wgULS("上传文件", "上傳檔案", null, null, "上載檔案"), "btn-fileUploader", "批量上传文件"); 5 | } 6 | mw.util.addPortletLink("p-tb", "https://commons.moegirl.org.cn/MediaWiki:Uploader", wgULS("批量上传文件", "批次上傳檔案", null, null, "批次上載檔案"), "t-uploader", "批量上传文件", null, "#t-specialpages"); 7 | }); 8 | -------------------------------------------------------------------------------- /src/gadgets/uploader/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: true 4 | 5 | default: true 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: 24 | - upload 25 | 26 | peers: [] 27 | 28 | dependencies: 29 | - mediawiki.util 30 | - ext.gadget.site-lib 31 | 32 | _sites: 33 | - zh 34 | - commons 35 | 36 | _section: editing 37 | 38 | _files: 39 | - Gadget-uploader.js 40 | -------------------------------------------------------------------------------- /src/gadgets/userLinkAvatarMagnifier/Gadget-UserLinkAvatarMagnifier.css: -------------------------------------------------------------------------------- 1 | /* 由UserLinkAvatar实现 */ -------------------------------------------------------------------------------- /src/gadgets/userLinkAvatarMagnifier/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: false 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: [] 24 | 25 | peers: [] 26 | 27 | dependencies: 28 | - ext.gadget.UserLinkAvatar 29 | - ext.gadget.jQueryLazyload 30 | 31 | _sites: 32 | - zh 33 | - commons 34 | 35 | _section: user 36 | 37 | _files: 38 | - Gadget-UserLinkAvatarMagnifier.css 39 | -------------------------------------------------------------------------------- /src/gadgets/usergroup/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: false 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: [] 24 | 25 | peers: [] 26 | 27 | dependencies: 28 | - moment 29 | - mediawiki.api 30 | - mediawiki.Uri 31 | - mediawiki.user 32 | - ext.gadget.LocalObjectStorage 33 | - ext.gadget.site-lib 34 | - ext.gadget.libPolyfill 35 | 36 | _sites: 37 | - zh 38 | - commons 39 | 40 | _section: user 41 | 42 | _files: 43 | - Gadget-usergroup.js 44 | -------------------------------------------------------------------------------- /src/gadgets/userpageCat/Gadget-userpagecat.css: -------------------------------------------------------------------------------- 1 | body.ns-2 div#catlinks:not(.catlinks-allhidden) { 2 | display: revert !important; 3 | } -------------------------------------------------------------------------------- /src/gadgets/userpageCat/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: false 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: styles 20 | 21 | package: false 22 | 23 | rights: 24 | - patrol 25 | 26 | peers: [] 27 | 28 | dependencies: [] 29 | 30 | _sites: 31 | - zh 32 | 33 | _section: maintenance 34 | 35 | _files: 36 | - Gadget-userpagecat.css 37 | -------------------------------------------------------------------------------- /src/gadgets/userpageDelete/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: false 4 | 5 | default: true 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: 16 | - 2 17 | 18 | contentModels: [] 19 | 20 | type: general 21 | 22 | package: false 23 | 24 | rights: 25 | - edit 26 | 27 | peers: [] 28 | 29 | dependencies: 30 | - ext.gadget.libOOUIDialog 31 | - ext.gadget.site-lib 32 | - ext.gadget.libPolyfill 33 | 34 | _sites: 35 | - zh 36 | 37 | _section: user 38 | 39 | _files: 40 | - Gadget-userpageDelete.js 41 | -------------------------------------------------------------------------------- /src/gadgets/vector-2022-styles/Gadget-vector-2022-styles.css: -------------------------------------------------------------------------------- 1 | /* 2 | * 放置于这里的CSS将应用于vector-2022皮肤 3 | * 请尊重萌娘百科版权,以下代码除非注明均是管理员手敲出来的!!!复制需要注明源自萌娘百科,并且附上URL地址 https://zh.moegirl.org.cn/MediaWiki:Gadget-vector-2022-styles.css 4 | * 版权协定:知识共享 署名-非商业性使用-相同方式共享 3.0 5 | * 复制之后请把图片换成自己网站上URL地址! 6 | */ 7 | 8 | /* 调整顶栏 logo,第一次压扁成这样的我 */ 9 | .mw-logo-icon { 10 | width: auto; 11 | height: 50px; 12 | } 13 | 14 | 15 | @media (width >= 768px) { 16 | .mobileonly { 17 | display: none !important; 18 | position: absolute; 19 | left: -999vw 20 | } 21 | } 22 | 23 | @media (width <= 768px) { 24 | .nomobile { 25 | display: none !important; 26 | position: absolute; 27 | left: -999vw 28 | } 29 | } 30 | 31 | #p-personal li { 32 | margin-top: 0.2em; 33 | } 34 | 35 | /* 页脚 */ 36 | #footer-info-copyright { 37 | background: url("//img.moegirl.org.cn/weixin_mengbai.png") 0 15px no-repeat; 38 | padding: 15px 0 30px; 39 | font-family: sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; 40 | min-height: 165px; 41 | } 42 | 43 | #footer-moegirl { 44 | padding-left: 160px; 45 | color: #2F2F2F; 46 | } 47 | 48 | #footer-moegirl h4 { 49 | color: #243C4A; 50 | font-family: AllerBold, "Helvetica Neue", Arial, Helvetica, Geneva, sans-serif; 51 | margin-bottom: 8px; 52 | } 53 | 54 | #footer-moegirl ul { 55 | float: left; 56 | margin: 0 100px 20px 0; 57 | line-height: 1.7; 58 | width: 120px; 59 | font-size: 12pt; 60 | } 61 | 62 | #footer-moegirl ul.lastlist { 63 | margin-right: 0; 64 | } 65 | 66 | #footer-moegirl ul a { 67 | color: #2F2F2F; 68 | } 69 | 70 | #footer-moegirl .copyright { 71 | clear: left; 72 | display: block; 73 | line-height: 1.3; 74 | color: #999; 75 | } 76 | 77 | /* 标题下划线增强 700 = bold */ 78 | h1 { 79 | font-weight: 700; 80 | border-bottom: 2px solid #0074F9; 81 | } 82 | 83 | h2 { 84 | font-weight: 700; 85 | border-bottom: 1px solid #0074F9; 86 | } 87 | 88 | -------------------------------------------------------------------------------- /src/gadgets/vector-2022-styles/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: true 4 | 5 | default: true 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: 10 | - vector-2022 11 | 12 | actions: [] 13 | 14 | categories: [] 15 | 16 | namespaces: [] 17 | 18 | contentModels: [] 19 | 20 | type: styles 21 | 22 | package: false 23 | 24 | rights: [] 25 | 26 | peers: [] 27 | 28 | dependencies: [] 29 | 30 | _sites: 31 | - zh 32 | 33 | _section: system 34 | 35 | _files: 36 | - Gadget-vector-2022-styles.css 37 | -------------------------------------------------------------------------------- /src/gadgets/vector-styles/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: true 4 | 5 | default: true 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: 10 | - vector-2022 11 | 12 | actions: [] 13 | 14 | categories: [] 15 | 16 | namespaces: [] 17 | 18 | contentModels: [] 19 | 20 | type: styles 21 | 22 | package: false 23 | 24 | rights: 25 | - disabled 26 | 27 | peers: [] 28 | 29 | dependencies: [] 30 | 31 | _sites: 32 | - zh 33 | 34 | _section: system 35 | 36 | _files: 37 | - Gadget-vector-styles.css 38 | -------------------------------------------------------------------------------- /src/gadgets/widgetPreload/Gadget-widgetPreload.css: -------------------------------------------------------------------------------- 1 | /* 禁止空widget使用Wikiplus创建 */ 2 | .noWidget #Wikiplus-Edit-TopBtn { 3 | display: none; 4 | } -------------------------------------------------------------------------------- /src/gadgets/widgetPreload/Gadget-widgetPreload.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | $(() => { 3 | const toUpperFirstCase = (t) => `${`${t[0]}`.substring(0, 1).toUpperCase()}${`${t}`.substring(1)}`; 4 | if (!mw.config.get("wgCurRevisionId")) { 5 | const regex = /[-_,./\\]/; 6 | if (regex.test(mw.config.get("wgPageName"))) { 7 | window.onbeforeunload = undefined; 8 | $(window).off("beforeunload"); 9 | location.replace(`${mw.config.get("wgServer")}${mw.config.get("wgScriptPath")}/index.php?action=edit&title=${mw.config.get("wgPageName").replace(/ |_/g, "").replace(/^([^/]*)[/\\].*$/i, "$1").split(regex).map((n) => toUpperFirstCase(n)).join("")}`); 10 | return; 11 | } 12 | const flag = `wg${mw.config.get("wgTitle")}`.replace(/ /g, ""); 13 | $("#wpTextbox1").val(` `); 14 | 15 | if ($("#mw-content-text > .mw-parser-output > .noarticletext")[0]) { 16 | $(document.body).addClass("noWidget"); 17 | } 18 | } 19 | }); 20 | -------------------------------------------------------------------------------- /src/gadgets/widgetPreload/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: true 4 | 5 | default: true 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: 12 | - edit 13 | 14 | categories: [] 15 | 16 | namespaces: 17 | - 274 18 | 19 | contentModels: [] 20 | 21 | type: general 22 | 23 | package: false 24 | 25 | rights: 26 | - edit 27 | - editwidgets 28 | 29 | peers: [] 30 | 31 | dependencies: [] 32 | 33 | _sites: 34 | - zh 35 | - commons 36 | 37 | _section: maintenance 38 | 39 | _files: 40 | - Gadget-widgetPreload.css 41 | - Gadget-widgetPreload.js 42 | -------------------------------------------------------------------------------- /src/gadgets/wikiBlame/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: false 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: 24 | - edit 25 | - patrol 26 | 27 | peers: [] 28 | 29 | dependencies: 30 | - oojs 31 | - oojs-ui 32 | - oojs-ui-core 33 | - mediawiki.diff.styles 34 | 35 | _sites: 36 | - zh 37 | 38 | _section: maintenance 39 | 40 | _files: 41 | - Gadget-wikiBlame.js 42 | -------------------------------------------------------------------------------- /src/gadgets/wikiplus-highlight/Gadget-wikiplus-highlight.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | (async () => { 3 | if (mw.config.get("wgIsArticle") && mw.config.get("wgAction") === "view") { 4 | await libCachedCode.injectCachedCode("https://testingcf.jsdelivr.net/npm/wikiplus-highlight@latest", "script"); 5 | } 6 | })(); 7 | -------------------------------------------------------------------------------- /src/gadgets/wikiplus-highlight/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: false 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: general 20 | 21 | package: false 22 | 23 | rights: 24 | - edit 25 | 26 | peers: [] 27 | 28 | dependencies: 29 | - ext.gadget.libOOUIDialog 30 | - ext.gadget.libPolyfill 31 | - mediawiki.util 32 | 33 | _sites: 34 | - zh 35 | 36 | _section: editing 37 | 38 | _files: 39 | - Gadget-wikiplus-highlight.js 40 | -------------------------------------------------------------------------------- /src/gadgets/zeroFill/Gadget-zerofill.css: -------------------------------------------------------------------------------- 1 | body span.zero-fill { 2 | display: inline !important; 3 | } 4 | -------------------------------------------------------------------------------- /src/gadgets/zeroFill/definition.yaml: -------------------------------------------------------------------------------- 1 | ResourceLoader: true 2 | 3 | hidden: false 4 | 5 | default: false 6 | 7 | supportsUrlLoad: false 8 | 9 | skins: [] 10 | 11 | actions: [] 12 | 13 | categories: [] 14 | 15 | namespaces: [] 16 | 17 | contentModels: [] 18 | 19 | type: styles 20 | 21 | package: false 22 | 23 | rights: [] 24 | 25 | peers: [] 26 | 27 | dependencies: [] 28 | 29 | _sites: 30 | - zh 31 | 32 | _section: browsing 33 | 34 | _files: 35 | - Gadget-zerofill.css 36 | -------------------------------------------------------------------------------- /src/global/commons/Common.css: -------------------------------------------------------------------------------- 1 | /* 2 | * 放置于这里的CSS将应用于所有皮肤 3 | * 请尊重萌娘百科版权,以下代码除非注明均是管理员手敲出来的!!!复制需要注明源自萌娘百科,并且附上URL地址http://commons.moegirl.org.cn/MediaWiki:Common.css 4 | * 版权协定:知识共享 署名-非商业性使用-相同方式共享 3.0 5 | * 如果复制css,复制后之后请把图片换成自己网站上的图片!!!!!!!!!!!!! 6 | */ 7 | /* 返回上一页 */ 8 | #back { 9 | cursor: pointer; 10 | } 11 | 12 | /* 通用圆角框 */ 13 | .common-box { 14 | padding: .2em .4em; 15 | border: 1px solid #ddd; 16 | -moz-border-radius: 10px; 17 | -webkit-border-radius: 10px; 18 | -khtml-border-radius: 10px; 19 | -o-border-radius: 10px; 20 | -webkit-box-shadow: #666 0 2px 3px; 21 | -moz-box-shadow: #666 0 2px 3px; 22 | border-radius: 10px; 23 | box-shadow: #666 0 2px 3px; 24 | } 25 | 26 | /* 在非主命名空间里隐藏编辑上传接口 */ 27 | body:not(.ns-0) #upload-div { 28 | display: none; 29 | } 30 | 31 | /* 隐藏只供维护人员查看的内容 */ 32 | .patroller-show, 33 | .checkuser-show, 34 | .suppress-show, 35 | .sysop-show, 36 | .interface-admin-show { 37 | display: none !important; 38 | } 39 | 40 | /* 数据表格 */ 41 | .mw-datatable.TablePager { 42 | width: 100%; 43 | table-layout: fixed; 44 | overflow-wrap: break-word; 45 | } 46 | -------------------------------------------------------------------------------- /src/groups/commons/checkuser/Group-checkuser.css: -------------------------------------------------------------------------------- 1 | .checkuser-show { 2 | display: revert !important; 3 | } 4 | 5 | div.vectorMenu li.checkuser-show { 6 | order: 1000; 7 | } 8 | 9 | .vectorMenu .checkuser-show::before { 10 | content: " "; 11 | display: block; 12 | height: 1px; 13 | color: #A2A9B1; 14 | background-color: #A2A9B1; 15 | border: 0; 16 | margin: 7px; 17 | } 18 | 19 | .vectorMenu .checkuser-show ~ .checkuser-show::before { 20 | display: none; 21 | } 22 | 23 | .vectorMenu .checkuser-show { 24 | cursor: default; 25 | } 26 | 27 | .vectorMenu .checkuser-show ~ .checkuser-show, 28 | .vectorMenu .checkuser-show a { 29 | cursor: pointer; 30 | } 31 | -------------------------------------------------------------------------------- /src/groups/commons/interface-admin/Group-interface-admin.css: -------------------------------------------------------------------------------- 1 | .interface-admin-show { 2 | display: revert !important; 3 | } 4 | 5 | div.vectorMenu li.interface-admin-show { 6 | order: 997; 7 | } 8 | 9 | .vectorMenu .interface-admin-show::before { 10 | content: " "; 11 | display: block; 12 | height: 1px; 13 | color: #A2A9B1; 14 | background-color: #A2A9B1; 15 | border: 0; 16 | margin: 7px; 17 | } 18 | 19 | .vectorMenu .interface-admin-show ~ .interface-admin-show::before { 20 | display: none; 21 | } 22 | 23 | .vectorMenu .interface-admin-show { 24 | cursor: default; 25 | } 26 | 27 | .vectorMenu .interface-admin-show ~ .interface-admin-show, 28 | .vectorMenu .interface-admin-show a { 29 | cursor: pointer; 30 | } 31 | -------------------------------------------------------------------------------- /src/groups/commons/patroller/Group-patroller.css: -------------------------------------------------------------------------------- 1 | .patroller-show { 2 | display: revert !important; 3 | } 4 | 5 | div.vectorMenu li.patroller-show { 6 | order: 998; 7 | } 8 | 9 | .vectorMenu .patroller-show::before { 10 | content: " "; 11 | display: block; 12 | height: 1px; 13 | color: #A2A9B1; 14 | background-color: #A2A9B1; 15 | border: 0; 16 | margin: 7px; 17 | } 18 | 19 | .vectorMenu .patroller-show ~ .patroller-show::before { 20 | display: none; 21 | } 22 | 23 | .vectorMenu .patroller-show { 24 | cursor: default; 25 | } 26 | 27 | .vectorMenu .patroller-show ~ .patroller-show, 28 | .vectorMenu .patroller-show a { 29 | cursor: pointer; 30 | } 31 | -------------------------------------------------------------------------------- /src/groups/commons/staff/Group-staff.css: -------------------------------------------------------------------------------- 1 | .patroller-show, 2 | .sysop-show { 3 | display: revert !important; 4 | } 5 | 6 | div.vectorMenu li.patroller-show { 7 | order: 998; 8 | } 9 | 10 | div.vectorMenu li.sysop-show { 11 | order: 999; 12 | } 13 | 14 | .vectorMenu .patroller-show::before, 15 | .vectorMenu .sysop-show::before { 16 | content: " "; 17 | display: block; 18 | height: 1px; 19 | color: #A2A9B1; 20 | background-color: #A2A9B1; 21 | border: 0; 22 | margin: 7px; 23 | } 24 | 25 | .vectorMenu .patroller-show ~ .patroller-show::before, 26 | .vectorMenu .sysop-show ~ .sysop-show::before { 27 | display: none; 28 | } 29 | 30 | .vectorMenu .patroller-show, 31 | .vectorMenu .sysop-show { 32 | cursor: default; 33 | } 34 | 35 | .vectorMenu .patroller-show ~ .patroller-show, 36 | .vectorMenu .patroller-show a, 37 | .vectorMenu .sysop-show ~ .sysop-show, 38 | .vectorMenu .sysop-show a { 39 | cursor: pointer; 40 | } 41 | -------------------------------------------------------------------------------- /src/groups/commons/staff/Group-staff.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | $(() => { 3 | // 自授权管理员增加更短的时间选项 4 | if (mw.config.get("wgCanonicalSpecialPageName") === "Userrights") { 5 | const wpExpiry = document.querySelector("#mw-input-wpExpiry-sysop"); 6 | Array.from(wpExpiry.options).filter((ele) => ele.value === "1 day")[0].before(new Option("30分钟", "30 minutes"), new Option("2小时", "2 hours"), new Option("6小时", "6 hours")); 7 | } 8 | // 替换文本默认不勾选「通过Special:最近更改和监视列表通知这些编辑」 9 | if (mw.config.get("wgCanonicalSpecialPageName") === "ReplaceText" && $("#powersearch")[0]) { 10 | $("#mw-search-ns0").prop("checked", false); 11 | $('input[name="botEdit"], #mw-search-ns6').prop("checked", true); 12 | } 13 | }); 14 | -------------------------------------------------------------------------------- /src/groups/commons/suppress/Group-suppress.css: -------------------------------------------------------------------------------- 1 | .suppress-show { 2 | display: revert !important; 3 | } 4 | 5 | div.vectorMenu li.suppress-show { 6 | order: 1001; 7 | } 8 | 9 | .vectorMenu .suppress-show::before { 10 | content: " "; 11 | display: block; 12 | height: 1px; 13 | color: #A2A9B1; 14 | background-color: #A2A9B1; 15 | border: 0; 16 | margin: 7px; 17 | } 18 | 19 | .vectorMenu .suppress-show ~ .suppress-show::before { 20 | display: none; 21 | } 22 | 23 | .vectorMenu .suppress-show { 24 | cursor: default; 25 | } 26 | 27 | .vectorMenu .suppress-show ~ .suppress-show, 28 | .vectorMenu .suppress-show a { 29 | cursor: pointer; 30 | } 31 | -------------------------------------------------------------------------------- /src/groups/commons/suppress/Group-suppress.js: -------------------------------------------------------------------------------- 1 | //
     2 | "use strict";
     3 | (async () => {
     4 |     /* 函数定义块 */
     5 |     const isNewVersion = +mw.config.get("wgVersion").slice(0, 4) >= 1.35;
     6 |     // 添加监督原因链接
     7 |     const addLink = ($obj, act) => {
     8 |         const href = $obj.css("margin-left", "1em")[0].href,
     9 |             reasonPageName = href.slice(href.indexOf("title=") + 6, href.indexOf("&action"));
    10 |         $obj.before(`浏览${act}原因`);
    11 |     };
    12 |     // 滥用日志
    13 |     const hideAbuselogLink = () => {
    14 |         const reasonpage = isNewVersion ? "MediaWiki:Revdelete-reason-dropdown-suppress" : "MediaWiki:Revdelete-reason-dropdown";
    15 |         const link = $("
    ", { 16 | id: "hideAbuselogLink", 17 | "class": "mw-revdel-editreasons", 18 | css: { 19 | "font-size": "90%", 20 | "text-align": "right", 21 | }, 22 | }).append(`编辑隐藏原因`); 23 | $("form[action='/Special:%E6%BB%A5%E7%94%A8%E6%97%A5%E5%BF%97']").append(link); 24 | }; 25 | /* 函数执行块 */ 26 | await $.ready; 27 | // 隐藏滥用日志原因浏览链接(预留其他接口) 28 | if (mw.config.get("wgCanonicalSpecialPageName") === "AbuseLog" && window.location.href.includes("&hide=")) { 29 | hideAbuselogLink(); 30 | addLink($(".mw-revdel-editreasons > a"), "隐藏"); 31 | } 32 | })(); 33 | //
    34 | -------------------------------------------------------------------------------- /src/groups/commons/sysop/Group-sysop.css: -------------------------------------------------------------------------------- 1 | .patroller-show, 2 | .sysop-show { 3 | display: revert !important; 4 | } 5 | 6 | div.vectorMenu li.patroller-show { 7 | order: 998; 8 | } 9 | 10 | div.vectorMenu li.sysop-show { 11 | order: 999; 12 | } 13 | 14 | .vectorMenu .patroller-show::before, 15 | .vectorMenu .sysop-show::before { 16 | content: " "; 17 | display: block; 18 | height: 1px; 19 | color: #A2A9B1; 20 | background-color: #A2A9B1; 21 | border: 0; 22 | margin: 7px; 23 | } 24 | 25 | .vectorMenu .patroller-show ~ .patroller-show::before, 26 | .vectorMenu .sysop-show ~ .sysop-show::before { 27 | display: none; 28 | } 29 | 30 | .vectorMenu .patroller-show, 31 | .vectorMenu .sysop-show { 32 | cursor: default; 33 | } 34 | 35 | .vectorMenu .patroller-show ~ .patroller-show, 36 | .vectorMenu .patroller-show a, 37 | .vectorMenu .sysop-show ~ .sysop-show, 38 | .vectorMenu .sysop-show a { 39 | cursor: pointer; 40 | } 41 | 42 | /* poll-id显示 */ 43 | .ajaxpoll .ajaxpoll-info .ajaxpoll-id-info { 44 | color: inherit; 45 | float: none; 46 | } 47 | 48 | /* 滥用过滤器表格 */ 49 | .mw-special-AbuseFilter .mw-datatable.TablePager { 50 | table-layout: auto; 51 | } 52 | 53 | .mw-special-AbuseFilter .mw-datatable.TablePager .TablePager_col_af_id { 54 | width: 6em; 55 | } 56 | 57 | .mw-special-AbuseFilter .mw-datatable.TablePager tbody .TablePager_col_af_id, 58 | .mw-special-AbuseFilter .mw-datatable.TablePager tbody .TablePager_col_af_enabled, 59 | .mw-special-AbuseFilter .mw-datatable.TablePager tbody .TablePager_col_af_hidden { 60 | padding-left: 0.5em !important; 61 | } 62 | 63 | .mw-special-AbuseFilter .mw-datatable.TablePager .TablePager_col_af_enabled, 64 | .mw-special-AbuseFilter .mw-datatable.TablePager .TablePager_col_af_hidden { 65 | width: 4em; 66 | } 67 | 68 | /* 过滤器历史优化(只是强迫症) */ 69 | .TablePager_col_afh_id { 70 | text-align: center; 71 | } 72 | 73 | /* 防止误删 */ 74 | .page-Category_即将删除的页面 #ca-delete { 75 | display: none; 76 | } 77 | -------------------------------------------------------------------------------- /src/groups/commons/sysop/Group-sysop.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | (async () => { 3 | /* 函数定义块 */ 4 | // 添加删除原因链接 5 | const addLink = ($obj, act) => { 6 | const href = $obj.css("margin-left", "1em")[0].href, 7 | reasonPageName = href.slice(href.indexOf("title=") + 6, href.indexOf("&action")); 8 | $obj.before(`浏览${act}原因`); 9 | }; 10 | /* 函数执行块 */ 11 | await $.ready; 12 | // 删除、保护、版本删除原因浏览链接 13 | if (mw.config.get("wgAction") === "delete") { 14 | if ($(".mw-delete-editreasons")[0]) { 15 | addLink($(".mw-delete-editreasons > a"), "删除"); 16 | } 17 | if ($(".mw-filedelete-editreasons")[0]) { 18 | addLink($(".mw-filedelete-editreasons > a"), "删除"); 19 | } 20 | } 21 | if (/protect$/.test(mw.config.get("wgAction")) && $(".mw-protect-editreasons")[0]) { 22 | addLink($(".mw-protect-editreasons > a"), "保护"); 23 | } 24 | if (mw.config.get("wgCanonicalSpecialPageName") === "Revisiondelete" && $(".mw-revdel-editreasons")[0]) { 25 | addLink($(".mw-revdel-editreasons > a"), "删除"); 26 | } 27 | // 替换文本默认不勾选「通过Special:最近更改和监视列表通知这些编辑」 28 | if (mw.config.get("wgCanonicalSpecialPageName") === "ReplaceText" && $("#powersearch")[0]) { 29 | $("#mw-search-ns0").prop("checked", false); 30 | $('input[name="botEdit"], #mw-search-ns6').prop("checked", true); 31 | } 32 | // 批量删除默认选择运行者为「you」 33 | if (mw.config.get("wgCanonicalSpecialPageName") === "DeleteBatch" && $("#wpMode")[0]) { 34 | $("#wpMode").val("you"); 35 | } 36 | })(); 37 | // 38 | -------------------------------------------------------------------------------- /src/groups/zh/checkuser/Group-checkuser.css: -------------------------------------------------------------------------------- 1 | /* 这里放置的CSS将只影响用户查核员 */ 2 | /* 显示仅供用户查核查看的内容 */ 3 | .checkuser-show { 4 | display: revert !important; 5 | } 6 | 7 | div.vectorMenu li.checkuser-show { 8 | order: 1000; 9 | } 10 | 11 | .vectorMenu .checkuser-show::before { 12 | content: " "; 13 | display: block; 14 | height: 1px; 15 | color: #A2A9B1; 16 | background-color: #A2A9B1; 17 | border: 0; 18 | margin: 7px; 19 | } 20 | 21 | .vectorMenu .checkuser-show~.checkuser-show::before { 22 | display: none; 23 | } 24 | 25 | .vectorMenu .checkuser-show { 26 | cursor: default; 27 | } 28 | 29 | .vectorMenu .checkuser-show~.checkuser-show, 30 | .vectorMenu .checkuser-show a { 31 | cursor: pointer; 32 | } 33 | 34 | .copyUsername { 35 | margin-left: 0.5rem; 36 | user-select: none; 37 | } 38 | -------------------------------------------------------------------------------- /src/groups/zh/interface-admin/Group-interface-admin.css: -------------------------------------------------------------------------------- 1 | /* 显示仅供界面管理员查看的内容 */ 2 | .interface-admin-show { 3 | display: revert !important; 4 | } 5 | 6 | div.vectorMenu li.interface-admin-show { 7 | order: 997; 8 | } 9 | 10 | .vectorMenu .interface-admin-show::before { 11 | content: " "; 12 | display: block; 13 | height: 1px; 14 | color: #A2A9B1; 15 | background-color: #A2A9B1; 16 | border: 0; 17 | margin: 7px; 18 | } 19 | 20 | .vectorMenu .interface-admin-show~.interface-admin-show::before { 21 | display: none; 22 | } 23 | 24 | .vectorMenu .interface-admin-show { 25 | cursor: default; 26 | } 27 | 28 | .vectorMenu .interface-admin-show~.interface-admin-show, 29 | .vectorMenu .interface-admin-show a { 30 | cursor: pointer; 31 | } -------------------------------------------------------------------------------- /src/groups/zh/patroller/Group-patroller.css: -------------------------------------------------------------------------------- 1 | /* 显示仅供巡查姬查看的内容 */ 2 | .patroller-show { 3 | display: revert !important; 4 | } 5 | 6 | div.vectorMenu li.patroller-show { 7 | order: 998; 8 | } 9 | 10 | .vectorMenu .patroller-show::before { 11 | content: " "; 12 | display: block; 13 | height: 1px; 14 | color: #A2A9B1; 15 | background-color: #A2A9B1; 16 | border: 0; 17 | margin: 7px; 18 | } 19 | 20 | .vectorMenu .patroller-show ~ .patroller-show::before { 21 | display: none; 22 | } 23 | 24 | .vectorMenu .patroller-show { 25 | cursor: default; 26 | } 27 | 28 | .vectorMenu .patroller-show ~ .patroller-show, 29 | .vectorMenu .patroller-show a { 30 | cursor: pointer; 31 | } 32 | 33 | /* Template:User */ 34 | body[class*="page-萌娘百科_talk_讨论版_"] .userlink .userlink-menu { 35 | column-count: 2; 36 | column-gap: 1px; 37 | column-rule: 1px solid #A2A9B1; 38 | } 39 | 40 | /* poll-id显示 */ 41 | .ajaxpoll .ajaxpoll-info .ajaxpoll-id-info { 42 | color: inherit; 43 | float: none; 44 | } 45 | -------------------------------------------------------------------------------- /src/groups/zh/staff/Group-staff.css: -------------------------------------------------------------------------------- 1 | /* 放置于这里的CSS将只影响STAFF */ 2 | /* 显示内容 */ 3 | .patroller-show, 4 | .sysop-show { 5 | display: revert !important; 6 | } 7 | 8 | div.vectorMenu li.patroller-show { 9 | order: 998; 10 | } 11 | 12 | div.vectorMenu li.sysop-show { 13 | order: 999; 14 | } 15 | 16 | .vectorMenu .patroller-show::before, 17 | .vectorMenu .sysop-show::before { 18 | content: " "; 19 | display: block; 20 | height: 1px; 21 | color: #A2A9B1; 22 | background-color: #A2A9B1; 23 | border: 0; 24 | margin: 7px; 25 | } 26 | 27 | .vectorMenu .patroller-show~.patroller-show::before, 28 | .vectorMenu .sysop-show~.sysop-show::before { 29 | display: none; 30 | } 31 | 32 | .vectorMenu .patroller-show, 33 | .vectorMenu .sysop-show { 34 | cursor: default; 35 | } 36 | 37 | .vectorMenu .patroller-show~.patroller-show, 38 | .vectorMenu .patroller-show a, 39 | .vectorMenu .sysop-show~.sysop-show, 40 | .vectorMenu .sysop-show a { 41 | cursor: pointer; 42 | } 43 | 44 | /* poll-id显示 */ 45 | .ajaxpoll .ajaxpoll-info .ajaxpoll-id-info { 46 | color: inherit; 47 | float: none; 48 | } 49 | -------------------------------------------------------------------------------- /src/groups/zh/staff/Group-staff.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | /* JS placed here will affect staffs only */ 3 | /* 函数执行体 */ 4 | $(() => { 5 | // 自授权管理员增加更短的时间选项 6 | if (mw.config.get("wgCanonicalSpecialPageName") === "Userrights") { 7 | const wpExpiry = document.querySelector("#mw-input-wpExpiry-sysop"); 8 | Array.from(wpExpiry.options).filter((ele) => ele.value === "1 day")[0].before(new Option("30分钟", "30 minutes"), new Option("2小时", "2 hours"), new Option("6小时", "6 hours")); 9 | } 10 | // 替换文本默认不勾选「通过Special:最近更改和监视列表通知这些编辑」 11 | if (mw.config.get("wgCanonicalSpecialPageName") === "ReplaceText" && $("#powersearch")[0]) { 12 | $('input[name="botEdit"]').prop("checked", true); 13 | } 14 | 15 | // 顶部警告框 16 | const $staffWarning = $(` 17 |
    22 |
    23 |
    ⚠️
    24 |
    25 |
    26 | 27 | 警告:当前登录的是萌娘百科 STAFF 账号! 28 | 29 | 我知道了 30 |
    31 |
    32 |
    33 |
    34 | `); 35 | $("#mw-body").prepend($staffWarning); 36 | $staffWarning.find("a").on("click", () => { 37 | $staffWarning.hide(150); 38 | }); 39 | }); 40 | -------------------------------------------------------------------------------- /src/groups/zh/suppress/Group-suppress.css: -------------------------------------------------------------------------------- 1 | /* 这里放置的CSS将只影响监督员 */ 2 | /* 显示仅供监督员查看的内容 */ 3 | .suppress-show { 4 | display: revert !important; 5 | } 6 | 7 | div.vectorMenu li.suppress-show { 8 | order: 1001; 9 | } 10 | 11 | .vectorMenu .suppress-show::before { 12 | content: " "; 13 | display: block; 14 | height: 1px; 15 | color: #A2A9B1; 16 | background-color: #A2A9B1; 17 | border: 0; 18 | margin: 7px; 19 | } 20 | 21 | .vectorMenu .suppress-show~.suppress-show::before { 22 | display: none; 23 | } 24 | 25 | .vectorMenu .suppress-show { 26 | cursor: default; 27 | } 28 | 29 | .vectorMenu .suppress-show~.suppress-show, 30 | .vectorMenu .suppress-show a { 31 | cursor: pointer; 32 | } -------------------------------------------------------------------------------- /src/groups/zh/suppress/Group-suppress.js: -------------------------------------------------------------------------------- 1 | //
     2 | "use strict";
     3 | (async () => {
     4 |     /* 函数定义块 */
     5 |     const isNewVersion = +mw.config.get("wgVersion").slice(0, 4) >= 1.35;
     6 |     // 添加监督原因链接
     7 |     const addLink = ($obj, act) => {
     8 |         const href = $obj.css("margin-left", "1em")[0].href,
     9 |             reasonPageName = href.slice(href.indexOf("title=") + 6, href.indexOf("&action"));
    10 |         $obj.before(`浏览${act}原因`);
    11 |     };
    12 |     // 滥用日志
    13 |     const hideAbuselogLink = () => {
    14 |         const reasonpage = isNewVersion ? "MediaWiki:Revdelete-reason-dropdown-suppress" : "MediaWiki:Revdelete-reason-dropdown";
    15 |         const link = $("
    ", { 16 | id: "hideAbuselogLink", 17 | "class": "mw-revdel-editreasons", 18 | css: { 19 | "font-size": "90%", 20 | "text-align": "right", 21 | }, 22 | }).append(`编辑隐藏原因`); 23 | $("form[action='/Special:%E6%BB%A5%E7%94%A8%E6%97%A5%E5%BF%97']").append(link); 24 | }; 25 | /* 函数执行块 */ 26 | await $.ready; 27 | // 隐藏滥用日志原因浏览链接(预留其他接口) 28 | if (mw.config.get("wgCanonicalSpecialPageName") === "AbuseLog" && window.location.href.includes("&hide=")) { 29 | hideAbuselogLink(); 30 | addLink($(".mw-revdel-editreasons > a"), "隐藏"); 31 | } 32 | })(); 33 | //
    34 | -------------------------------------------------------------------------------- /src/groups/zh/user/Group-user.css: -------------------------------------------------------------------------------- 1 | /* 这里放置的CSS将只影响注册用户 */ 2 | -------------------------------------------------------------------------------- /src/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "commonjs" 3 | } 4 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | // "@annangela/eslint-packages/tsconfig.browser.json", 4 | "./node_modules/@annangela/eslint-config/dist/tsconfigs/tsconfig.browser.json" 5 | ], 6 | "compilerOptions": { 7 | "outDir": "./dist/", 8 | "baseUrl": ".", 9 | "lib": [ 10 | "ESNext", 11 | "DOM" 12 | ], 13 | }, 14 | "include": [ 15 | "src", 16 | "scripts", 17 | "node_modules/types-mediawiki", 18 | ], 19 | "exclude": [ 20 | "dist", 21 | ], 22 | } 23 | -------------------------------------------------------------------------------- /tsconfig.production.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "./dist/_compiled", 5 | "baseUrl": "./", 6 | "rootDir": "./src/", 7 | "target": "es2020", 8 | }, 9 | "exclude": [ 10 | "scripts", 11 | ], 12 | } 13 | --------------------------------------------------------------------------------