// ==UserScript== // @name 空框批量删除工具 lite // @namespace https://aze.local/bdlpk // @version 2.1.1 // @description 统计并批量删除 pointNum < 5 的低点数空框 // @author Aze // @match https://baidu.hellorobotaxi.com/* // @run-at document-idle // @grant none // ==/UserScript== (function() { 'use strict'; void function () { var TOOL_NAME = "__BDLowPointKiller_Aze_Lite"; if (window[TOOL_NAME] && typeof window[TOOL_NAME].restore === "function") { try { window[TOOL_NAME].restore(); } catch (e) {} } var tool = { version: "1.0.0-lite", originalCheckFor420312: null, badRows: [], kernel: null, deleteElements: null, deleteElementsRun: null, retryTimer: null, globalKeydown: null }; function getCheckPage() { return window.validation && window.validation.page; } function isBadLabel(label) { return label && label.pointNum !== undefined && Number(label.pointNum) < 5; } function unique(arr) { var map = {}; var out = []; arr.forEach(function (x) { if (x && !map[x]) { map[x] = true; out.push(x); } }); return out; } function parseFramesFromMarkedData(markedData) { var selectText = markedData && markedData[1] && markedData[1].answer && markedData[1].answer[101] && markedData[1].answer[101].select_text; if (!selectText) return []; var outer = JSON.parse(selectText); var extra = outer.extra; if (typeof extra !== "string") return []; var rawFrames = extra.indexOf("@_@") >= 0 ? extra.split("@_@") : [extra]; return rawFrames.map(function (raw, index) { return { frameIndex: index + 1, data: JSON.parse(raw) }; }); } function installDetector() { var page = getCheckPage(); if (!page || typeof page.checkFor420312 !== "function") { return false; } if (!tool.originalCheckFor420312) { tool.originalCheckFor420312 = page.checkFor420312; } page.checkFor420312 = function (markedData, data, extraInfo) { try { if (!data) { var parsedFrames = parseFramesFromMarkedData(markedData); var badRows = []; parsedFrames.forEach(function (frame) { var labels3D = frame.data && frame.data.label && frame.data.label["3D"] ? frame.data.label["3D"] : []; labels3D.forEach(function (label, labelIndex) { if (isBadLabel(label)) { badRows.push({ frameIndex: frame.frameIndex, labelIndex: labelIndex, uuid: label.uuid, pointNum: label.pointNum }); } }); }); tool.badRows = badRows; } } catch (e) {} return tool.originalCheckFor420312.apply(this, arguments); }; return true; } function installDetectorWithRetry() { if (installDetector()) return; var count = 0; tool.retryTimer = setInterval(function () { count++; if (installDetector() || count >= 20) { clearInterval(tool.retryTimer); tool.retryTimer = null; } }, 500); } function isKernelLike(obj) { return !!( obj && typeof obj === "object" && obj.lifecycle && obj.lifecycle.running && obj.lifecycle.running.deleteElements && typeof obj.lifecycle.running.deleteElements.run === "function" ); } function captureKernel(obj) { tool.kernel = obj; tool.deleteElements = obj.lifecycle.running.deleteElements; tool.deleteElementsRun = tool.deleteElements.run.bind(tool.deleteElements); window.__kernel = tool.kernel; window.__deleteElements = tool.deleteElements; window.__deleteElementsRun = tool.deleteElementsRun; return true; } function scanKernel() { if (isKernelLike(tool.kernel)) return true; if (isKernelLike(window.__kernel)) return captureKernel(window.__kernel); var roots = []; try { Object.keys(window).forEach(function (key) { if (/kernel|app|mark|label|annot|tool|store|plugin|scene|task|root|react|mobx/i.test(key)) { try { roots.push({ value: window[key], depth: 0 }); } catch (e) {} } }); } catch (e) {} try { var nodes = Array.prototype.slice.call(document.querySelectorAll("*"), 0, 600); nodes.forEach(function (node) { Object.keys(node).forEach(function (key) { if (/^__react|^_react|fiber|Fiber|props|Props/i.test(key)) { try { roots.push({ value: node[key], depth: 0 }); } catch (e) {} } }); }); } catch (e) {} var seen = typeof WeakSet !== "undefined" ? new WeakSet() : null; var queue = roots.slice(); var maxDepth = 7; var maxVisit = 30000; var visited = 0; while (queue.length && visited < maxVisit) { var item = queue.shift(); var obj = item.value; var depth = item.depth || 0; if (!obj || typeof obj !== "object") continue; if (seen) { if (seen.has(obj)) continue; seen.add(obj); } visited++; if (isKernelLike(obj)) { return captureKernel(obj); } if (depth >= maxDepth) continue; var keys = []; try { keys = Object.keys(obj).slice(0, 120); } catch (e) { continue; } keys.forEach(function (key) { try { var value = obj[key]; if (value && typeof value === "object") { queue.push({ value: value, depth: depth + 1 }); } } catch (e) {} }); } return false; } async function waitAndClickYes(timeout) { var start = Date.now(); while (Date.now() - start < timeout) { var buttons = Array.prototype.slice.call( document.querySelectorAll("button, [role='button']") ); var yesButton = buttons.find(function (btn) { var text = (btn.innerText || btn.textContent || "").trim(); var rect = btn.getBoundingClientRect(); var style = getComputedStyle(btn); return ( text === "是" && rect.width > 0 && rect.height > 0 && style.display !== "none" && style.visibility !== "hidden" ); }); if (yesButton) { yesButton.click(); return true; } await new Promise(function (resolve) { setTimeout(resolve, 100); }); } return false; } async function deleteBadBoxes() { if (typeof tool.deleteElementsRun !== "function") { scanKernel(); } if (typeof tool.deleteElementsRun !== "function") return; var uuids = unique( (tool.badRows || []) .map(function (row) { return row && row.uuid; }) .filter(Boolean) ); if (!uuids.length) return; try { var deletePromise = Promise.resolve( tool.deleteElementsRun( { uuids: uuids }, "shortcut-delete-empty-boxes-by-Aze-lite" ) ); await waitAndClickYes(5000); await deletePromise; } catch (e) {} } function isTypingTarget(target) { if (!target) return false; var tag = (target.tagName || "").toUpperCase(); return tag === "INPUT" || tag === "TEXTAREA" || tag === "SELECT" || !!target.isContentEditable; } function isCtrlMinus(e) { return ( e.ctrlKey && !e.altKey && !e.shiftKey && !e.metaKey && (e.key === "-" || e.key === "_" || e.code === "Minus" || e.code === "NumpadSubtract") ); } function bindHotkey() { if (tool.globalKeydown) { document.removeEventListener("keydown", tool.globalKeydown, true); } tool.globalKeydown = function (e) { if (isTypingTarget(e.target)) return; if (isCtrlMinus(e)) { e.preventDefault(); e.stopPropagation(); deleteBadBoxes(); } }; document.addEventListener("keydown", tool.globalKeydown, true); } tool.installDetector = installDetector; tool.scanKernel = scanKernel; tool.deleteBadBoxes = deleteBadBoxes; tool.restore = function () { var page = getCheckPage(); if (page && tool.originalCheckFor420312) { page.checkFor420312 = tool.originalCheckFor420312; } if (tool.retryTimer) { clearInterval(tool.retryTimer); tool.retryTimer = null; } if (tool.globalKeydown) { document.removeEventListener("keydown", tool.globalKeydown, true); tool.globalKeydown = null; } }; window[TOOL_NAME] = tool; installDetectorWithRetry(); scanKernel(); setTimeout(scanKernel, 1200); setTimeout(scanKernel, 3000); bindHotkey(); }(); })();