Redirect BGM Search to cityhunter.me

将 bgm.tv bangumi.tv 和 chii.in 的顶栏分类搜索替换为 cityhunter.me 多标签搜索

// ==UserScript==
// @name         Redirect BGM Search to cityhunter.me
// @namespace    http://tampermonkey.net/
// @version      1.1
// @description  将 bgm.tv bangumi.tv 和 chii.in 的顶栏分类搜索替换为 cityhunter.me 多标签搜索
// @author       oscardoudou
// @include      /https?:\/\/(bgm\.tv|bangumi\.tv|chii\.in).*/
// @grant        GM_addElement
// @grant        GM.xmlHttpRequest
// @require      https://code.jquery.com/jquery-3.6.0.min.js
// @require      https://code.jquery.com/ui/1.12.1/jquery-ui.min.js
// ==/UserScript==

(function() {
    'use strict';
    // 替换搜索类别
    const catMapping = {
        '2': 'anime',
        '1': 'book',
        '4': 'game',
        '3': 'music',
        '6': 'real',
    };

    // 添加搜索表单提交事件监听器
    document.querySelector('#headerSearch form').addEventListener('submit', function(event) {

        // 获取选择的搜索类别和搜索关键词
        var catValue = document.getElementById('siteSearchSelect').value;
        var searchTextValue = document.getElementById('search_text').value;

        // 阻止默认的表单提交行为(只对以上分类,全部和人物沿用bangumi搜索)
        if(catValue in catMapping)  {
                event.preventDefault();
        }
        var catReplacement = catMapping[catValue];

        // 构造跳转的 URL
        var redirectURL = 'https://cityhunter.me/'+catReplacement+'/tags/?q=' + encodeURIComponent(searchTextValue);

        // 跳转到指定的 URL
        window.location.href = redirectURL;
    });

    // 添加搜索栏标签补全
    // Wait for the page to load
    $(document).ready(function() {
        // Ensure the jQuery UI CSS is loaded
        GM_addElement('link', {
            href: 'https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css',
            rel: 'stylesheet',
            type: 'text/css'
        });

        // global request terms to keep track old input, prevent being overwrite when select option
        var request_terms = []
        // Initialize autocomplete
        $('#search_text').autocomplete({
            source: function(request, response) {
                let cat = $('#siteSearchSelect').val();
                if (!(cat in catMapping)){
                    response([]); // No suggestions for disallowed categories(all|person)
                    return;
                }
                // Get the last tag (the part after the last space)
                request_terms = request.term.split(' ')
                let lastTerm = request_terms.pop();
                let apiUrl = `https://cityhunter.me/api/tags/?size=20&cat=${cat}&prefix=${lastTerm}`;

                GM.xmlHttpRequest({
                    method: 'GET',
                    url: apiUrl,
                    responseType: 'json',
                    onload: function(res) {
                        if (res.status === 200) {
                            var suggestions = res.response['results'].map(function(item) {
                                return {
                                    label: item['name'],
                                    value: item['name'],
                                    count: item['count']
                                };
                            });
                            response(suggestions);
                        } else {
                            response([]);
                            console.log('res.status not 200');
                        }
                    },
                    onerror: function() {
                        response([]);
                    }
                });
            },

            minLength: 1,
            select: function(event, ui) {
                request_terms.push(ui.item.value);
                this.value = request_terms.join(' ')
                return false;
            }
        });
    });

})();