Instantly share code, notes, and snippets.
Last active
February 25, 2021 03:08
-
Star
0
(0)
You must be signed in to star a gist -
Fork
0
(0)
You must be signed in to fork a gist
-
Save 0xlane/c068ebc33981df7d5bdfee55ffaaf7f5 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==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