Skip to content

Instantly share code, notes, and snippets.

@0xlane
Last active February 25, 2021 03:08
Show Gist options
  • Save 0xlane/c068ebc33981df7d5bdfee55ffaaf7f5 to your computer and use it in GitHub Desktop.
Save 0xlane/c068ebc33981df7d5bdfee55ffaaf7f5 to your computer and use it in GitHub Desktop.
// ==UserScript==
// @name QT-显示隐藏的前端模块
// @name:zh QT-显示隐藏的前端模块
// @name:zh-CN QT-显示隐藏的前端模块
// @name:en QT-ShowHiddendFrontendModule
// @namespace http:///
// @version 0.3
// @license GPL-3.0-only
// @create 2020-03-18
// @description This is a simple thing!
// @author Techliu
// @include /^https?://c.*e\.q.*gt.*g\.cn/(v3|next)/.*$/
// @run-at document-idle
// @note 2020.03.22-V0.3 修复next中访问隐藏模块后菜单不能高亮
// @note 2020.03.19-V0.2 完成自动展开左侧菜单的功能
// @note 2020.03.18-V0.1 完成next和v3显示Web命令执行菜单的功能
// @grant GM_getValue
// @grant GM.getValue
// @grant GM_setValue
// @grant GM.setValue
// @grant GM_registerMenuCommand
// ==/UserScript==
(function () {
'use strict';
// Your code here...
// 声明
var auto_collapse, url_path = window.location.pathname;
var FindReact = function (dom, traverseUp = 0) {
// from https://stackoverflow.com/questions/29321742/react-getting-a-component-from-a-dom-element-for-debugging
const key = Object.keys(dom).find(key => key.startsWith("__reactInternalInstance$"));
const domFiber = dom[key];
if (domFiber == null) return null;
// react <16
if (domFiber._currentElement) {
let compFiber = domFiber._currentElement._owner;
for (let i = 0; i < traverseUp; i++) {
compFiber = compFiber._currentElement._owner;
}
return compFiber._instance;
}
// react 16+
const GetCompFiber = fiber => {
//return fiber._debugOwner; // this also works, but is __DEV__ only
let parentFiber = fiber.return;
while (typeof parentFiber.type == "string") {
parentFiber = parentFiber.return;
}
return parentFiber;
};
let compFiber = GetCompFiber(domFiber);
for (let i = 0; i < traverseUp; i++) {
compFiber = GetCompFiber(compFiber);
}
return compFiber.stateNode;
}
var Navtigation = class {
constructor(e) {
this.navList = [],
this.navigations = {},
this.sideMenu = [],
this.accessList = [],
this.hasPermission = (e => this.isActive(this.navigations[e])),
this.navList = e.sort((e, t) => e.order - t.order).map(e => {
let t = {
id: e.key,
name: e.display,
level: parseInt(e.degree),
access: e.access,
active: parseInt(e.active),
type: parseInt(e.type),
order: parseInt(e.order),
icon: this.getIconSetting(e.icon)
};
if (e.route && 1 === t.type) {
let n = JSON.parse(e.route);
Array.isArray(n) && (n = n[0]);
try {
if (e.memo && JSON.parse(e.memo).outlink) {
let n = JSON.parse(e.memo)
, { protocol: i, hostname: o, port: s, pathname: r, hash: a } = window.location
, l = n.protocol
, c = n.hostname
, u = n.port
, d = n.hash
, h = i
, v = o
, f = s
, g = r + a;
t.url = `${l || h}//${c || v}:${u || f}${d || g}`
} else
t.url = n.href
} catch (e) {
console.log("备注格式错误")
}
t.route = n.name
}
return t
}
),
this.navList.forEach(e => {
this.navigations[e.id] = e
}
),
this.accessList = this.navList.filter(e => (this.isActive(e) || !1 !== e.access) && e.url)
//this.accessList = this.navList.filter(e => (this.isActive(e) || !1 !== e.access && 2 === e.active) && e.url)
}
generateSideMenu() {
let e, t = [];
for (let n = 0, o = this.navList.length; n < o; n++) {
let o = this.navList[n];
if (this.isMenu(o) && this.isActive(o)) {
let s = Object.assign({}, this.navList[n]);
if (e || (e = o),
s.level > e.level ? t.push(e) : e.level > s.level && t.pop(),
1 === s.level)
this.sideMenu.push(s);
else {
let e = t[t.length - 1];
e.subMenu ? e.subMenu.push(s) : e.subMenu = [s]
}
e = s
}
}
}
getSideMenu() {
return this.sideMenu && 0 !== this.sideMenu.length || (this.extendsPermission(),
this.generateSideMenu()),
this.sideMenu
}
isActive(e) {
//return e && 1 === e.active && !1 !== e.access
return e && e.active > 0 && !1 !== e.access
}
isMenu(e) {
return 1 === e.type
}
isUrlAccessible(e) {
let t = 0
, n = e.split("/");
return n.splice(0, 1),
this.accessList.map(e => {
let i = e.url.indexOf("/#/") > -1 ? e.url.split("#/")[1].split("/") : e.url
, o = !0;
for (let e = 0; e < n.length && (n[e] !== i[e] && (o = !1),
void 0 !== i[e + 1] || void 0 === n[e + 1]); e++)
;
o && t < n.length && (t = n.length)
}
),
!!t
}
extendsPermission() {
let e = null;
this.navList.forEach(t => {
if (this.isMenu(t)) {
if (e && t.level > e.level)
return t.access = e.access,
void (t.active = e.active);
e = null,
this.isActive(t) || (e = t)
}
}
)
}
getIconSetting(e) {
if (e) {
let t = e.split(" ");
return {
name: t[0],
size: t[1]
}
}
}
}
// 兼容性检查
if (typeof (GM) == "undefined") {
// 这个是ViolentMonkey的支持选项
GM = {};
GM.setValue = GM_setValue;
GM.getValue = GM_getValue;
}
// 注册扩展菜单
Promise.all([GM.getValue("auto_collapse")]).then(function (data) {
console.log("+ 菜单自动折叠功能当前状态:", (data[0]) ? "打开" : "关闭");
GM.setValue('auto_collapse', data[0] ? true : false);
auto_collapse = data[0] ? true : false;
});
try {
GM_registerMenuCommand('打开或关闭菜单自动折叠', function () {
//GM_setValue('auto_collapse', false);
Promise.all([GM.getValue("auto_collapse")]).then(function (data) {
GM.setValue('auto_collapse', !data[0]);
console.warn("- 菜单自动折叠功能已经 ", (data[0]) ? "打开!" : "关闭!");
})
});
} catch (e) {
console.log(e);
}
// 主要逻辑,判断是v3与next
if (url_path.indexOf("v3/") >= 0) {
var timer = window.setInterval(function () {
// 检测DOM是否加载完成
if ($("li[ng-repeat='item2 in item1.children']").length > 0) {
// 移除隐藏的模块
$("li[ng-repeat='item2 in item1.children']").removeClass("ng-hide");
// 自动展开菜单
var a = angular.element(".side-logo a");
var b = a.scope();
b.appCtrl.layout.sideMenuExpand = auto_collapse ? b.appCtrl.layout.sideMenuExpand : true;
// 清楚定时器
clearInterval(timer);
} else {
// nothing
}
}, 1000);
} else {
var timer1 = window.setInterval(function () {
// 检测DOM是否加载完成
if (typeof (webpackJsonp) == "function" && document.querySelector("aside")) {
//webpackJsonp = function(a, n, r) {};
//console.log(webpackJsonp);
// 找到react对象
var sideMenuDom = document.querySelector("aside");
var sideMenu = FindReact(sideMenuDom);
// 打开或关闭自动折叠功能
if (!auto_collapse && sideMenu.store.isSideMenuCollapsed){
sideMenu.store.toggleSideMenu();
}
// 显示隐藏模块
var navs = sideMenu.store.navs;
var nav = new Navtigation(navs);
var navRouterMap = {};
nav.navList.forEach(e=>{
if (e.url && e.access && e.active){
navRouterMap[e.url] = e.id;
}
});
console.log(nav.navList);
console.log(navRouterMap);
let updateNavMenu = (e,f) => {
return function(){
e.props.menu = f.getSideMenu();
e.forceUpdate();
let g = window.location.pathname + window.location.hash;
let h = g.split('/');
for (var i = h.length; i > 1; i--) {
if (navRouterMap[h.slice(0, i).join('/')]) {
e.setState({ "subMenuId": navRouterMap[h.slice(0, i).join('/')] });
}
}
}
};
window.addEventListener('hashchange', updateNavMenu(sideMenu, nav));
updateNavMenu(sideMenu, nav)();
// 清楚定时器
clearInterval(timer1);
} else {
// nothing
}
}, 1000);
}
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment