Greasy Fork 还支持 简体中文。

esxi_web_cum_with_Specific_propSet_Trigger

仅对包含特定 propSet 内容的 SOAP 请求触发排序和高度调整

  1. // ==UserScript==
  2. // @name esxi_web_cum_with_Specific_propSet_Trigger
  3. // @license MIT
  4. // @namespace http://tampermonkey.net/
  5. // @version 3.7
  6. // @description 仅对包含特定 propSet 内容的 SOAP 请求触发排序和高度调整
  7. // @match https://192.168.3.50/*
  8. // ==/UserScript==
  9.  
  10. (function() {
  11. 'use strict';
  12.  
  13. // 定义需要匹配的 propSet XML 片段
  14. const TARGET_PROPSET_SNIPPET = `
  15. <propSet><type>VirtualMachine</type><all>false</all>
  16. <pathSet>name</pathSet><pathSet>config.annotation</pathSet>
  17. <pathSet>config.defaultPowerOps</pathSet><pathSet>config.extraConfig</pathSet>
  18. <pathSet>config.hardware.memoryMB</pathSet><pathSet>config.hardware.numCPU</pathSet>
  19. <pathSet>config.hardware.numCoresPerSocket</pathSet><pathSet>config.guestId</pathSet>
  20. <pathSet>config.guestFullName</pathSet><pathSet>config.version</pathSet>
  21. <pathSet>config.template</pathSet><pathSet>datastore</pathSet>
  22. <pathSet>guest</pathSet><pathSet>runtime</pathSet>
  23. <pathSet>summary.storage</pathSet><pathSet>summary.runtime</pathSet>
  24. <pathSet>summary.quickStats</pathSet><pathSet>effectiveRole</pathSet></propSet>
  25. `.replace(/\s+/g, ''); // 去除空白字符便于匹配
  26.  
  27. // 检查请求数据是否包含目标 propSet 片段
  28. const containsTargetPropSet = (data) => {
  29. return data && data.replace(/\s+/g, '').includes(TARGET_PROPSET_SNIPPET);
  30. };
  31.  
  32. // 监听表格数据加载完成
  33. const observeTableDataLoad = () => {
  34. return new Promise((resolve) => {
  35. const tableObserver = new MutationObserver(() => {
  36. const table = document.querySelector('table.k-selectable');
  37. const rows = table ? table.querySelectorAll('tbody tr') : [];
  38.  
  39. if (rows.length > 0) {
  40. console.log("表格数据已加载完成,准备触发排序...");
  41. tableObserver.disconnect(); // 停止观察
  42. resolve(); // 表格数据加载完成
  43. }
  44. });
  45. tableObserver.observe(document.body, { childList: true, subtree: true });
  46. });
  47. };
  48.  
  49. // 点击箭头图标展开下拉菜单
  50. const triggerArrowheadClick = () => {
  51. const arrowheadIcon = document.querySelector('span.k-icon.k-i-arrowhead-s');
  52. if (arrowheadIcon) {
  53. console.log("找到箭头图标,正在触发点击展开下拉菜单...");
  54. arrowheadIcon.click();
  55. }
  56. };
  57.  
  58. // 触发排序按钮点击事件
  59. const triggerSortAscButton = () => {
  60. const sortAscButton = document.querySelector('span.k-sprite.k-i-sort-asc');
  61. if (sortAscButton) {
  62. console.log("找到 '按升序排序' 按钮,尝试触发排序事件...");
  63.  
  64. // 触发完整的排序事件序列
  65. sortAscButton.dispatchEvent(new MouseEvent('mouseover', { bubbles: true, cancelable: true }));
  66. sortAscButton.dispatchEvent(new FocusEvent('focus', { bubbles: true, cancelable: true }));
  67. sortAscButton.dispatchEvent(new MouseEvent('mousedown', { bubbles: true, cancelable: true }));
  68. sortAscButton.dispatchEvent(new MouseEvent('mouseup', { bubbles: true, cancelable: true }));
  69. sortAscButton.click(); // 触发 click 事件
  70.  
  71. setTimeout(setContentHeight, 500); // 延迟 500 毫秒以确保排序完成
  72. }
  73. };
  74.  
  75. // 设置容器高度
  76. const setContentHeight = () => {
  77. const gridContainer = document.querySelector('div.ui-resizable.k-grid.k-widget.k-reorderable.k-grid-scroll');
  78. const gridContent = document.querySelector('div.k-grid-content');
  79.  
  80. if (gridContainer) {
  81. console.log("排序完成,强制设置 gridContainer 高度为 855px...");
  82. gridContainer.style.setProperty("height", "855px", "important");
  83.  
  84. if (gridContent) {
  85. const adjustedHeight = `${gridContainer.offsetHeight - 98}px`;
  86. console.log(`设置 gridContent 高度为: ${adjustedHeight}...`);
  87. gridContent.style.setProperty("height", adjustedHeight, "important");
  88. }
  89. }
  90. };
  91.  
  92. // 拦截并检测 XMLHttpRequest 请求内容
  93. const interceptXMLHttpRequest = () => {
  94. const originalSend = XMLHttpRequest.prototype.send;
  95.  
  96. XMLHttpRequest.prototype.send = function(data) {
  97. // 检查请求数据是否包含目标 propSet 内容
  98. if (typeof data === "string" && containsTargetPropSet(data)) {
  99. console.log("匹配到指定的 propSet 内容,准备触发排序和高度调整...");
  100.  
  101. // 顺序执行:等待表格加载 -> 点击箭头 -> 触发排序
  102. observeTableDataLoad()
  103. .then(() => {
  104. triggerArrowheadClick();
  105. setTimeout(triggerSortAscButton, 100); // 100ms 延迟以确保菜单展开
  106. });
  107. }
  108. return originalSend.apply(this, [data]);
  109. };
  110. };
  111.  
  112. // 初始化拦截
  113. interceptXMLHttpRequest();
  114.  
  115. console.log("XML 拦截已初始化,仅对包含特定 propSet 内容的请求触发排序和高度调整。");
  116. })();