Modao Menu Parser

modao menu parser

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install a user script manager extension to install this script.

(I already have a user script manager, let me install it!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

// ==UserScript==
// @name         Modao Menu Parser
// @namespace    http://tampermonkey.net/
// @version      1.0.1
// @description  modao menu parser
// @author       飞天小猪
// @match        http*://modao.cc/*
// @icon https://gongjux.com/files/3/4453uhm5937m/32/favicon.ico
// @grant        none
// @require https://greasyfork.org/scripts/453166-jquery/code/jquery.js?version=1105525
// @license MIT
// ==/UserScript==


// 判断modao版本
function parserVersion() {
    return location.href.includes('proto')
}

// 解析函数
function parser() {
    const res = parserVersion()
    !res && layer.load(2, {shade: [0.5, '#393D49']})
    // 1. 获取ul元素
    const liElArr = findUlElememt()
    // 2. 整理数据
    if (!liElArr) return res ? alert('解析失败!') :layer.msg('解析失败!')
    const nodeList = getNodeList(liElArr)
    const result = toContent(flattenTreeWithLevels(nodeList))
    // 3. 将整理好的数据复制到剪贴板
    copyTextToClipboard(result)
    !res && layer.closeAll('loading');
}
function findUlElememt() {
    const res = parserVersion()
    return res ? ($('ul').children().toArray() || undefined) : ($('ul[class*="iAsEgD"]').children().toArray() || undefined)
}
function getNodeList(li) {
    const arr = []
    li.forEach(i => {
        const temp = {}
        const children = Array.from(i.children)
        temp.name = children.find(j => j.className.includes('rn-list-item')).innerText
        const list = Array.from(children.find(j => j.className.includes('child-screens'))?.children || [])
        if (list.length) {
            temp.children = getNodeList(list)
        } else {
            temp.children = []
        }
        arr.push(temp)
    })
    return arr
}

function flattenTreeWithLevels(tree, levels = [], arr = []) {
    for (const node of tree) {
        const item = { ...levels };
        item[levels.length] = node.name;
        arr.push(item);
        if (node.children) {
            flattenTreeWithLevels(node.children, [...levels, node.name], arr);
        }
    }
    return arr;
}
function toContent(arr) {
    let str = ''
    const strArr = arr.map(i => {
        const itemArr = Object.values(i)
        return itemArr.join('\t')
    })
    str = strArr.join('\n')
    return str
}
async function copyTextToClipboard(text) {
    const res = parserVersion()
    if (navigator.clipboard && navigator.clipboard.writeText) {
        try {
            await navigator.clipboard.writeText(text);
            res ? alert('复制成功') :layer.msg('复制成功');
            return;
        } catch (err) {
            console.error('使用 Clipboard API 复制失败: ', err);
        }
    }

    // 如果 Clipboard API 不可用,尝试使用 execCommand 方法
    const textArea = document.createElement('textarea');
    document.body.appendChild(textArea);
    textArea.value = text;
    textArea.select();
    try {
        const successful = document.execCommand('copy');
        if (successful) {
            console.log('使用 execCommand 复制成功');
        } else {
            console.log('使用 execCommand 复制失败');
        }
    } catch (err) {
        console.error('使用 execCommand 复制失败: ', err);
    } finally {
        document.body.removeChild(textArea);
    }
}
(function() {
    'use strict';

    function setButton() {
        // 创建一个新的button元素
        var button = document.createElement('button');
        button.textContent = '解析菜单'; // 设置按钮文字

        // 设置按钮的基本样式(包括固定定位与默认透明度)
        button.style.cssText = `
position: fixed; /* 或者 absolute,取决于您的布局需求 */
top: 88px; /* 举例位置,您可以自定义 */
right: 10px; /* 举例位置,您可以自定义 */
z-index: 999;
background-color: #007bff;
color: white;
padding: 6px 12px;
border: none;
border-radius: 5px;
cursor: pointer;
opacity: 0.3;
transition: opacity 0.3s ease;
`;


        // 添加鼠标悬浮时的透明度变化
        button.addEventListener('mouseover', function () {
            this.style.opacity = 1;
        });

        // 添加鼠标离开时的透明度变化
        button.addEventListener('mouseout', function () {
            this.style.opacity = 0.3;
        });
        button.addEventListener('click', parser)
        // 将按钮添加到文档中
        document.body.appendChild(button);
    }
    function sleep(time) {
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                resolve()
            }, time * 1000)
        })
    }
    async function init() {
        const res = parserVersion()
        if (res) {
            setButton()
        } else {
            $('head').append($('<link rel="stylesheet" href="https://www.layuicdn.com/layui/css/layui.css">')) // 名称:layui,版本:2.7.6,原始地址:https://www.layuicdn.com/#Layui
            if (typeof layer == 'undefined') {
                $('head').append('<script src="https://www.layuicdn.com/layer-v3.5.1/layer.js"></script>') // 名称:layer,版本:3.5.1,原始地址:https://www.layuicdn.com/#Layer
            }
            // 等待layer加载成功
            while (true) {
                const loadEl = document.getElementById('loading')
                const loadElStyle = loadEl && window.getComputedStyle(loadEl)
                if (typeof layer != 'undefined' && loadElStyle && loadElStyle.display === 'none') {
                    break
                }
                await sleep(0.5)
            }
            setButton()

        }
    }
    init()
})();