1C distributives grouper

Groups distributive links into OS-specific containers

目前为 2023-10-04 提交的版本。查看 最新版本

// ==UserScript==
// @name         1C distributives grouper
// @description  Groups distributive links into OS-specific containers
// @version      0.5
// @author       Akpaev E.A.
// @grant        none
// @namespace    https://github.com/akpaevj
// @license      MIT
// @match        https://releases.1c.ru/version_files?nick=Platform83*
// ==/UserScript==

(function() {
    'use strict';
    const container = document.createElement('div');
    container.className = 'container tabbale';

    const ul = document.createElement('ul');
    ul.className = 'nav nav-tabs';
    container.append(ul);

    const filesContainer = document.querySelector('.files-container');
    filesContainer.append(container);

    const tabContent = document.createElement('div');
    tabContent.className = 'tab-content';
    container.append(tabContent);

    function addTab(id, title, active = false) {
        const li = document.createElement('li');
        if (active) {
            li.className = 'active';
        }
        ul.append(li);

        const a = document.createElement('a');
        a.setAttribute('href', `#${id}`);
        a.dataset.toggle = 'tab';
        a.textContent = title;
        li.append(a);
    }

    function addPane(id, active = false, addSelectorRow = false) {
        const div = document.createElement('div');
        if (active) {
            div.className = 'tab-pane active';
        } else {
            div.className = 'tab-pane';
        }
        div.setAttribute('id', id);
        tabContent.append(div);

        if (addSelectorRow) {
            const row = document.createElement('div');
            row.className = 'row-fluid';
            div.append(row);
        }

        return div;
    }

    function addTabAndPane(id, title, active = false, addSelectorRow = false) {
        addTab(id, title, active);
        return addPane(id, active, addSelectorRow);
    }

    function addOption(select, value, title) {
        const option = document.createElement('option');
        option.setAttribute('value', value);
        option.textContent = title;
        select.append(option);
    }

    function addSelector(pane, id, title, onChangeCallback) {
        const row = pane.querySelector('.row-fluid');

        const span = document.createElement('div');
        span.className = 'span3';
        if (row === null) {
            pane.append(span);
        } else {
            row.append(span);
        }

        const label = document.createElement('label');
        label.setAttribute('for', `${id}-select`);
        label.textContent = title;
        span.append(label);

        const select = document.createElement('select');
        select.setAttribute('id', `${id}-select`);
        span.append(select);

        select.onchange = _ => onChangeCallback(select.selectedOptions[0].value, pane);

        return select;
    }

    function showHideLink(e, show, filterId) {
        const filteredBy = new Set(JSON.parse(e.dataset.filteredBy));

        if (show) {
            filteredBy.delete(filterId);
        } else {
            filteredBy.add(filterId);
        }

        if (filteredBy.size > 0) {
            e.style.display = "none";
        } else {
            e.style.display = "block";
        }

        e.dataset.filteredBy = JSON.stringify(Array.from(filteredBy));
    }

    function showHideLinkByRegex(e, regex, filterId) {
        showHideLink(e, regex.test(e.querySelector('a').innerText), filterId);
    }

    function addArchSelector(pane) {
        const filterId = 'arch'
        const select = addSelector(pane, 'arch', 'Arch', (value, pane) => {
            if (value === 'all') {
                pane.querySelectorAll('.formLine').forEach((e) => {
                    showHideLink(e, true, filterId);
                });
            } else if (value === '86') {
                pane.querySelectorAll('.formLine').forEach((e) => {
                    showHideLinkByRegex(e, /^(?:(?!64-bit).)*$/i, filterId);
                });
            } else {
                pane.querySelectorAll('.formLine').forEach((e) => {
                    showHideLinkByRegex(e, /.*64-bit.*/i, filterId);
                });
            }
        });

        addOption(select, 'all', 'All');
        addOption(select, '86', 'x86');
        addOption(select, '64', 'x64');
    }

    function addPackageManagerSelector(pane) {
        const filterId = 'pm'
        const select = addSelector(pane, 'pm', 'Package manager', (value, pane) => {
            if (value === 'all') {
                pane.querySelectorAll('.formLine').forEach((e) => {
                    showHideLink(e, true, filterId);
                });
            } else if (value === 'deb') {
                pane.querySelectorAll('.formLine').forEach((e) => {
                    showHideLink(e, /.*DEB.*/i.test(e.querySelector('a').innerText), filterId);
                });
            } else {
                pane.querySelectorAll('.formLine').forEach((e) => {
                    showHideLink(e, /.*RPM.*/i.test(e.querySelector('a').innerText), filterId);
                });
            }
        });

        addOption(select, 'all', 'All');
        addOption(select, 'deb', 'DEB');
        addOption(select, 'rpm', 'RPM');
    }

    function addApplicationTypeSelector(pane) {
        const filterId = 'type'
        const select = addSelector(pane, 'type', 'Type', (value, pane) => {
            if (value === 'all') {
                pane.querySelectorAll('.formLine').forEach((e) => {
                    showHideLink(e, true, filterId);
                });
            } else if (value === 'full') {
                pane.querySelectorAll('.formLine').forEach((e) => {
                    showHideLink(e, /.*Технологическая платформа.*/i.test(e.querySelector('a').innerText), filterId);
                });
            } else if (value === 'server') {
                pane.querySelectorAll('.formLine').forEach((e) => {
                    showHideLink(e, /.*Сервер.*/i.test(e.querySelector('a').innerText), filterId);
                });
            } else if (value === 'client') {
                pane.querySelectorAll('.formLine').forEach((e) => {
                    showHideLink(e, /^Клиент.*/i.test(e.querySelector('a').innerText), filterId);
                });
            } else {
                pane.querySelectorAll('.formLine').forEach((e) => {
                    showHideLink(e, /.*Тонкий клиент.*/i.test(e.querySelector('a').innerText), filterId);
                });
            }
        });

        addOption(select, 'all', 'All');
        addOption(select, 'full', 'Full');
        addOption(select, 'server', 'Server');
        addOption(select, 'client', 'Client');
        addOption(select, 'thinClient', 'Thin client');
    }

    const cCont = addTabAndPane('common', 'Common', true, true);
    addArchSelector(cCont);

    const wCont = addTabAndPane('windows', 'Windows', false, true);
    addApplicationTypeSelector(wCont);
    addArchSelector(wCont);

    const lCont = addTabAndPane('linux', 'Linux', false, true);
    addApplicationTypeSelector(lCont);
    addArchSelector(lCont);
    addPackageManagerSelector(lCont);

    const mCont = addTabAndPane('mac', 'Mac');
    const oCont = addTabAndPane('other', 'Other');

    document.querySelectorAll(".formLine").forEach((e) => {
        e.dataset.filteredBy = JSON.stringify([]);
        const a = e.querySelector('a');

        if (/.*Windows.*/i.test(a.innerText) && (/.*Linux.*/i.test(a.innerText) || /.*MacOS.*/i.test(a.innerText))) {
            cCont.append(e)
        } else if (/.*Windows.*/i.test(a.innerText)) {
            wCont.append(e)
        } else if (/.*Linux.*/i.test(a.innerText)) {
            lCont.append(e)
        } else if (/.*MacOS.*/i.test(a.innerText)) {
            mCont.append(e)
        } else {
            oCont.append(e)
        }
    });
})();