打开/关闭菜单
打开/关闭外观设置菜单
打开/关闭个人菜单
未登录
未登录用户的IP地址会在进行任意编辑后公开展示。

MediaWiki:Gadget-RCSidebar.js

MediaWiki界面页面
deltarune>KumkiTAT2025年10月13日 (一) 00:48的版本
(差异) ←上一版本 | 最后版本 (差异) | 下一版本→ (差异)

注意:在发布之后,您可能需要清除浏览器缓存才能看到所作出的更改的影响。

  • Firefox或Safari:按住Shift的同时单击刷新,或按Ctrl-F5Ctrl-R(Mac为⌘-R
  • Google Chrome:Ctrl-Shift-R(Mac为⌘-Shift-R
  • Edge:按住Ctrl的同时单击刷新,或按Ctrl-F5
const RECENT_CHANGES_MAX = 5;
const RECENT_CHANGES_NS = 0;
const RECENT_CHANGES_TYPES = ['new', 'edit'];
const RECENT_CHANGES_PROPS = ['title', 'ids', 'user', 'userid', 'timestamp'];

const THUMBNAIL_PLACEHOLDER_HTML = '<span class="cdx-thumbnail__placeholder"><span class="cdx-icon cdx-icon--medium cdx-thumbnail__placeholder__icon--vue"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="20" height="20" viewBox="0 0 20 20" aria-hidden="true"><g><path d="M19 3H1v14h18zM3 14l3.5-4.5 2.5 3L12.5 8l4.5 6z"></path><path d="M19 5H1V3h18zm0 12H1v-2h18z"></path></g></svg></span></span>';

const {timeSince} = mw.loader.require('ext.gadget.Util');
const api = new mw.Api();

Promise.all([
	api.get({
		action: 'query',
		list: 'recentchanges',
		rcprop: RECENT_CHANGES_PROPS,
		// In case of duplicates, we fetch 10 times more entries than we display
		rclimit: RECENT_CHANGES_MAX * 10,
		rcshow: '!bot',
		rctype: RECENT_CHANGES_TYPES,
		rcnamespace: RECENT_CHANGES_NS,
	}),
	api.get({
		action: 'query',
		generator: 'recentchanges',
		grcnamespace: RECENT_CHANGES_NS,
		grclimit: RECENT_CHANGES_MAX * 10,
		grcshow: '!bot',
		prop: 'pageimages|info',
		inprop: 'displaytitle',
	}),
]).then(([recentChanges, recentChangesPageProps]) => {
	const seenPages = new Set();
	const recentChangeItems = [];
	for (const recentChange of recentChanges.query.recentchanges) {
		if (seenPages.size >= RECENT_CHANGES_MAX) {
			break;
		}
		if (seenPages.has(recentChange.pageid)) {
			continue;
		}
		seenPages.add(recentChange.pageid);
		const pageProps = recentChangesPageProps.query.pages[recentChange.pageid];
		const thumbnail = pageProps && pageProps.thumbnail ?
			$('<span>', {
				class: 'cdx-thumbnail__image',
				css: {
					backgroundImage: `url("${pageProps.thumbnail.source}")`,
				},
			}) :
			THUMBNAIL_PLACEHOLDER_HTML;
		const userLink = mw.Title.makeTitle(2, recentChange.user).getUrl();
		recentChangeItems.push($('<li>', {
			class: 'mw-list-item rc-sidebar-item',
			html: [
				$('<span>', {
					class: 'cdx-thumbnail rc-sidebar-item-thumbnail',
					html: thumbnail,
				}),
				$('<span>', {
					class: 'rc-sidebar-item-body',
					html: [
						$('<a>', {
							class: 'rc-sidebar-item-title',
							href: mw.util.getUrl(recentChange.title),
							html: $('<span>', {
								class: 'rc-sidebar-item-title-text',
								text: pageProps ?
									pageProps.displaytitle
										.replace(/<[^>]*>?/gm, ''):
									recentChange.title,
							}),
						}),
						$('<span>' , {
							class: 'rc-sidebar-item-description',
							html: [
								$('<a>', {
									class: 'rc-sidebar-item-description-link',
									href: mw.util.getUrl(recentChange.title, {
										diff: recentChange.revid
									}),
									text: timeSince(recentChange.timestamp),
								}),
								'&bull;',
								$('<a>', {
									class: 'rc-sidebar-item-description-link',
									href: userLink,
									text: recentChange.user,
								}),
							],
						}),
					],
				}),
			],
		}));
	}
	$('.vector-sticky-pinned-container').append($('<div>', {
		class: 'vector-menu',
		html: [
			$('<div>', {
				class: 'vector-menu-heading',
				html: $('<a>', {
					href: mw.util.getUrl('Special:RecentChanges'),
					text: mw.msg('gadget-rcsidebar-title'),
				}),
			}),
			$('<div>', {
				class: 'vector-menu-content',
				html: $('<ul>', {
					class: 'vector-menu-content-list',
					html: recentChangeItems,
				}),
			}),
		],
	}));
}).catch(err => console.error('Failed to fetch RC data for RCSidebar:', err));