查看“︁MediaWiki:Common.js”︁的源代码
←
MediaWiki:Common.js
跳转到导航
跳转到搜索
因为以下原因,您没有权限编辑该页面:
此页面为本wiki上的软件提供界面文本,并受到保护以防止滥用。如欲修改所有wiki的翻译,请访问
translatewiki.net
上的MediaWiki本地化项目。
您无权编辑此JavaScript页面,因为编辑此页面可能会影响所有访问者。
您可以查看和复制此页面的源代码。
/* 虾仁维基 - 自定义侧边栏导航 */ /* 作者: 虾仁维基团队 */ /* 最后更新: 2026-07-26 */ (function($, mw) { 'use strict'; var COLLAPSE_KEY = 'xiarenwiki-nav-v2'; var WORKS = ['我在大明那些年', '彼岸轮回', '一品布衣']; var WORK_DIRECT = ['宇宙层', '人物', '世界观', '设定']; function init() { if (!mw.config.get('wgIsArticle') && mw.config.get('wgCanonicalSpecialPageName')) { return; } waitForPanel(function($panel) { buildNav($panel); }); } function waitForPanel(cb) { var $panel = $('#mw-panel'); if ($panel.length) return cb($panel); var tries = 0; var timer = setInterval(function() { $panel = $('#mw-panel'); if ($panel.length || ++tries > 50) { clearInterval(timer); if ($panel.length) cb($panel); } }, 100); } /* ========== BUILD ========== */ function buildNav($panel) { var html = ''; // 搜索框 html += '<div class="xn-search">'; html += '<form action="' + mw.util.getUrl('Special:Search') + '" method="get">'; html += '<input type="text" name="search" class="xn-search-input" placeholder="搜索虾仁维基..." />'; html += '</form></div>'; html += section('Wiki', [ ['首页', '首页'], ['Wiki简介', 'Wiki简介'], ['管理员告示', '管理员告示'], ['随机页面', 'Special:Random'], ['快速搜索', 'Special:Search'], ['相关平台', '相关平台'], ['Wiki源站点', 'Wiki源站点'] ]); html += section('虾仁简介', [ ['虾仁?', '虾仁?'], ['虾仁共创收录规则', '虾仁共创收录规则'], ['虾仁宇宙结构介绍', '虾仁宇宙结构介绍'] ]); html += '<div class="xn-section">'; html += '<div class="xn-header xn-expandable" data-sid="universe">虾仁宇宙</div>'; html += '<div class="xn-body" id="xn-universe"><div class="xn-loading">加载中...</div></div>'; html += '</div>'; html += '<div class="xn-section">'; html += '<div class="xn-header xn-expandable" data-sid="literature">虾仁文学</div>'; html += '<div class="xn-body" id="xn-literature">'; html += link('创始宣言', '创始宣言'); html += link('虾仁六章', '虾仁六章'); html += link('虾仁异志', '虾仁异志'); html += link('虾仁诗作', '虾仁诗作'); html += link('虾仁音乐', '虾仁音乐'); html += '<div class="xn-subsection">'; html += '<div class="xn-subheader xn-expandable" data-sid="papers">虾仁论文 ' + plus('虾仁论文') + '</div>'; html += '<div class="xn-subbody" id="xn-papers">'; html += link('去中心化创作模式的研究', '去中心化创作模式的研究'); html += link('数字时代的孙悟空', '数字时代的孙悟空'); html += '</div></div></div></div>'; html += section('虾仁历史', [ ['起源', '虾仁历史/起源'], ['传播', '虾仁历史/传播'], ['转折', '虾仁历史/转折'], ['爆发', '虾仁历史/爆发'], ['危机', '虾仁历史/危机'], ['转型', '虾仁历史/转型'] ]); html += '<div class="xn-single"><a href="' + url('共创入口') + '">共创入口</a></div>'; $panel.html(html); restoreCollapse(); bindEvents(); highlightCurrent(); loadUniverse(); } /* ========== HTML HELPERS ========== */ function section(title, items) { var sid = title.replace(/[^a-z0-9\u4e00-\u9fff]/gi, '').toLowerCase(); var h = '<div class="xn-section">'; h += '<div class="xn-header xn-expandable" data-sid="' + sid + '">' + title + '</div>'; h += '<div class="xn-body" id="xn-' + sid + '">'; for (var i = 0; i < items.length; i++) { h += link(items[i][0], items[i][1]); } h += '</div></div>'; return h; } function link(label, page, cls) { return '<div class="xn-link' + (cls ? ' ' + cls : '') + '"><a href="' + url(page) + '">' + label + '</a></div>'; } function url(page) { return mw.util.getUrl(page); } function plus(page) { return '<a class="xn-plus" href="' + url(page) + '?action=edit" title="编辑/新增">+</a>'; } /* ========== UNIVERSE DYNAMIC LOAD ========== */ async function loadUniverse() { var $body = $('#xn-universe'); if (!$body.length) return; try { var api = new mw.Api(); var html = ''; for (var i = 0; i < WORKS.length; i++) { var work = WORKS[i]; var workSid = 'work' + i; var subpages = []; try { var result = await api.get({ action: 'query', list: 'allpages', apprefix: work + '/', aplimit: 100 }); subpages = result.query.allpages || []; } catch(e) { console.error('API error for ' + work, e); } html += '<div class="xn-work">'; html += '<div class="xn-header xn-expandable" data-sid="' + workSid + '">' + work + '</div>'; html += '<div class="xn-body" id="xn-' + workSid + '">'; // Direct subpages under work var directSet = {}; for (var j = 0; j < subpages.length; j++) { var rel = subpages[j].title.substring(work.length + 1); if (rel.indexOf('/') === -1) directSet[rel] = true; } for (var k = 0; k < WORK_DIRECT.length; k++) { var item = WORK_DIRECT[k]; var exists = directSet[item]; html += link(item, work + '/' + item, exists ? '' : 'xn-missing'); } // 剧情层 var plotSegs = []; for (j = 0; j < subpages.length; j++) { rel = subpages[j].title.substring(work.length + 1); var parts = rel.split('/'); if (parts.length === 2 && parts[0] === '剧情层') { plotSegs.push(parts[1]); } } var plotSid = workSid + 'plot'; html += '<div class="xn-subsection">'; html += '<div class="xn-subheader xn-expandable" data-sid="' + plotSid + '">剧情层 ' + plus(work + '/剧情层') + '</div>'; html += '<div class="xn-subbody" id="xn-' + plotSid + '">'; for (k = 0; k < plotSegs.length; k++) { var seg = plotSegs[k]; var segSid = workSid + 'seg' + k; var segPage = work + '/剧情层/' + seg; // Fetch 金集 for this segment var jinji = []; try { var segResult = await api.get({ action: 'query', list: 'allpages', apprefix: segPage + '/', aplimit: 50 }); var segPages = segResult.query.allpages || []; for (var m = 0; m < segPages.length; m++) { jinji.push(segPages[m].title.substring(segPage.length + 1)); } } catch(e2) {} html += '<div class="xn-subsubsection">'; html += '<div class="xn-subsubheader xn-expandable" data-sid="' + segSid + '">' + seg + ' ' + plus(segPage) + '</div>'; html += '<div class="xn-subsubbody" id="xn-' + segSid + '">'; for (m = 0; m < jinji.length; m++) { html += link(jinji[m], segPage + '/' + jinji[m]); } html += '</div></div>'; } html += '</div></div>'; // close 剧情层 html += '</div></div>'; // close work } // Add new work link html += '<div class="xn-link xn-add-work"><a href="' + url('Special:Search') + '" title="搜索已有作品">+ 发现更多作品</a></div>'; $body.html(html); restoreCollapse(); bindEvents(); highlightCurrent(); } catch(e) { console.error('Failed to load universe nav', e); $body.html('<div class="xn-link">(加载失败,请刷新)</div>'); } } /* ========== CURRENT PAGE HIGHLIGHT ========== */ function highlightCurrent() { var currentTitle = mw.config.get('wgPageName'); $('#mw-panel .xn-link a').each(function() { var href = $(this).attr('href'); if (!href) return; var match = false; if (href.indexOf('title=') > 0) { var m = href.match(/title=([^&]+)/); if (m) match = decodeURIComponent(m[1]) === currentTitle; } else { var parts = href.split('/'); var last = parts[parts.length - 1]; match = decodeURIComponent(last) === currentTitle; } if (match) { $(this).addClass('xn-active'); $(this).closest('.xn-link').addClass('xn-active-link'); $(this).parents('.xn-body, .xn-subbody, .xn-subsubbody').each(function() { $(this).show(); var sid = $(this).attr('id'); if (sid && sid.indexOf('xn-') === 0) { sid = sid.substring(3); $('[data-sid="' + sid + '"]').removeClass('xn-collapsed'); } }); } }); } /* ========== EVENTS & STATE ========== */ function bindEvents() { $(document).off('click.xn').on('click.xn', '.xn-expandable', function(e) { if ($(e.target).closest('.xn-plus').length) return; // don't toggle when clicking [+] var sid = $(this).data('sid'); var $body = $('#xn-' + sid); if (!$body.length) $body = $(this).next('.xn-body,.xn-subbody,.xn-subsubbody'); if (!$body.length) return; $body.slideToggle(150); $(this).toggleClass('xn-collapsed', !$body.is(':visible')); var state = loadState(); state[sid] = $body.is(':visible'); saveState(state); }); } function restoreCollapse() { var state = loadState(); var defaults = { 'universe': true }; for (var key in defaults) { if (!(key in state)) state[key] = defaults[key]; } Object.keys(state).forEach(function(sid) { var $header = $('[data-sid="' + sid + '"]'); var $body = $('#xn-' + sid); if (!$body.length) $body = $header.next('.xn-body,.xn-subbody,.xn-subsubbody'); if (!$body.length) return; if (state[sid]) { $body.show(); $header.removeClass('xn-collapsed'); } else { $body.hide(); $header.addClass('xn-collapsed'); } }); } function loadState() { try { return JSON.parse(localStorage.getItem(COLLAPSE_KEY) || '{}'); } catch(e) { return {}; } } function saveState(s) { try { localStorage.setItem(COLLAPSE_KEY, JSON.stringify(s)); } catch(e) {} } /* ========== START ========== */ mw.loader.using('mediawiki.api').then(function() { $(init); }); })(jQuery, mediaWiki);
返回
MediaWiki:Common.js
。
导航菜单
个人工具
未登录
讨论
贡献
创建账号
登录
associated-pages
系统消息
讨论
English
查看
阅读
查看源代码
查看历史
更多
搜索
虾仁维基
首页
作品总录
三部奠基作品
我在大明那些年
彼岸轮回
一品布衣
文献典藏
虾仁六章
虾仁·传播史
共创入口
工具
最近更改
随机页面
搜索
工具
链入页面
相关更改
页面信息