extension for axure

axure 原型页面辅助

// ==UserScript==
// @name         extension for axure
// @namespace    http://tampermonkey.net/
// @version      1.1.3
// @description  axure 原型页面辅助
// @author       gkeeno
// @match        http://192.168.1.5:30032/*
// @grant        none
// @run-at       document-idle
// @noframes
// ==/UserScript==

setTimeout(()=>{
    if(self != top) return; // 不是顶层页面

    if(!RP_VERSION || RP_VERSION > 9) {
        console.warn('非axure页面或axure版本过高')
        return;
    };

    loadFoldBtn(); // 折叠功能
    loadFolderTextClick(); // 给文件夹的整个元素加上点击即toggle的功能
},1000)


function loadFolderTextClick(){
    // 所有文件夹元素
    const sitemapPageLinkContainers = document.querySelectorAll("div.sitemapPageLinkContainer");
    for (const div of sitemapPageLinkContainers){
        const toggleBtn = div.querySelector(".sitemapPlusMinusLink")
        if (toggleBtn) {

            // 判断是可折叠的页面,可以不用处理(原本点击页面三角仅触发加载页面和折叠)
            //const toggleSibling = toggleBtn.nextElementSibling
            //if(toggleSibling && toggleSibling.querySelector('.sitemapPageIcon')) continue;

            // 给整个文件夹元素添加点击事件,点击时触发左边三角形按钮的点击
            div.addEventListener("click", function(e) {
                console.log("clicked")
                // 如果点击的是三角按钮本身,不需要处理,避免触发两次
                if (e.target === toggleBtn || toggleBtn.contains(e.target)) {
                    return;
                }
                e.stopPropagation();
                // 模拟点击三角形按钮
                toggleBtn.click();
            });

            // 设置鼠标样式为指针,提示用户可以点击
            div.style.cursor = "pointer";
        }
    }
}
function loadFoldBtn(){

    const headerBtnMenu = document.querySelector("#sitemapToolbar"); // tips: 等1s后再添加较为安全(依据菜单数量)

    const foldMenuBtn = document.createElement("div");
    foldMenuBtn.title = "折叠菜单";
    foldMenuBtn.classList.add('sitemapToolbarButton');
    foldMenuBtn.textContent = '🧺';
    foldMenuBtn.onclick = function() {
        const userRes = prompt("从几级开始折叠?(最小为1级)", 2);
        if(!userRes) return;

        const level = Math.floor(Number(userRes));
        if(isNaN(level) || level < 0) return alert("必须输入正整数");
        foldLeftMenu(level);
    };

    console.log('fold btn add begin.')
    if(headerBtnMenu) {
        headerBtnMenu.insertBefore(foldMenuBtn, headerBtnMenu.firstChild);
        console.log('fold btn add complete.')
    }
}

function foldLeftMenu(level) {
    const leftMenuTree = document.querySelector("#sitemapTreeContainer > ul.sitemapTree");
    const levelFlag = {
        lvMax: 10,
        lvMin: level || 1,
        lvCur: 1,
        isExceed: function() {
            return this.lvCur > this.lvMax;
        },
        completeFold: function() {
            this.lvCur++;
        }
    };

    const nodeList = Array.from(leftMenuTree.querySelectorAll(":scope > .sitemapNode"));
    foldAllNodeByNodeList(nodeList, levelFlag, []);
}

function foldAllNodeByNodeList(nodeList, flag, foldCallBacks) {
    if(flag.isExceed()) {
        executedAllCallBacks(foldCallBacks);
        return;
    }

    const nextFoldNodeList = [];
    const needSkipLevel = isSkipLevel(flag);

    nodeList.forEach(node => {
        const subNodes = Array.from(node.querySelectorAll(":scope > ul > .sitemapNode"));
        nextFoldNodeList.push(...subNodes);

        if(!needSkipLevel) {
            foldCallBacks.push(() => foldNode(node));
        }
    });

    flag.completeFold();

    if(nextFoldNodeList.length === 0) {
        executedAllCallBacks(foldCallBacks);
        return;
    }

    foldAllNodeByNodeList(nextFoldNodeList, flag, foldCallBacks);
}

function foldNode(node) {
    const foldBtn = node.querySelector(":scope > div > div.sitemapPageLinkContainer .sitemapPlusMinusLink");
    if(!foldBtn) return;

    const isFolded = foldBtn.querySelector(".sitemapPlus");
    if(isFolded) return;

    foldBtn.click();
}

function executedAllCallBacks(arrCallBacks) {
    arrCallBacks.reverse().forEach(cb => cb());
}

function isSkipLevel(flag) {
    return flag.lvCur < flag.lvMin;
}