您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Adds a button to open verification bugs in new windows on Launchpad bug pages, excluding the current bug ID
// ==UserScript== // @name Open Launchpad Kernel SRU Verification Bugs // @namespace http://anthonywong.net/ // @version 1.2 // @description Adds a button to open verification bugs in new windows on Launchpad bug pages, excluding the current bug ID // @author Grok // @match https://bugs.launchpad.net/kernel-sru-workflow/+bug/* // @grant GM_openInTab // @license GPLv2 // ==/UserScript== (function() { 'use strict'; console.log('Tampermonkey script started'); // Extract current bug ID from URL const url = window.location.href; const urlRegex = /\+bug\/(\d+)/; const urlMatch = url.match(urlRegex); const currentBugId = urlMatch ? urlMatch[1] : null; console.log('Current bug ID from URL:', currentBugId); // Find the div with class yui3-editable_text-text const div = document.querySelector('div.yui3-editable_text-text'); if (!div) { console.log('No div with class yui3-editable_text-text found'); return; } console.log('Found div with class yui3-editable_text-text'); // Find the p element inside the div const pElements = div.getElementsByTagName('p'); console.log(`Found ${pElements.length} p elements in div`); let targetP; let bugNumbers = []; // Iterate through p elements to find the one with verification-bugs for (let p of pElements) { if (p.textContent.includes('verification-bugs')) { console.log('Found verification-bugs in p element'); console.log('P element content (first 200 chars):', p.textContent.substring(0, 200)); targetP = p; // Extract bug numbers using regex const bugsRegex = /verification-bugs:\s*\[([\d,\s]*)\]/; const match = p.textContent.match(bugsRegex); if (match && match[1]) { bugNumbers = match[1].split(',').map(num => num.trim()).filter(num => num); console.log('Extracted bug numbers:', bugNumbers); } else { console.log('No bug numbers matched in regex'); } break; } } if (!targetP) { console.log('No p element with verification-bugs found in div'); return; } if (bugNumbers.length === 0) { console.log('No bug numbers extracted'); return; } // Check if button already exists const existingButtons = div.querySelectorAll('button'); for (let btn of existingButtons) { if (btn.textContent === 'Open bugs in new window') { console.log('Button already exists, skipping'); return; } } // Create button console.log('Creating button'); const button = document.createElement('button'); button.textContent = 'Open bugs in new window'; button.style.marginLeft = '10px'; button.style.cursor = 'pointer'; button.style.padding = '5px 10px'; button.style.backgroundColor = '#007bff'; button.style.color = 'white'; button.style.border = 'none'; button.style.borderRadius = '4px'; button.style.display = 'inline-block'; button.style.verticalAlign = 'middle'; // Add click event listener, excluding current bug ID button.addEventListener('click', () => { console.log('Button clicked, processing bug numbers:', bugNumbers); const filteredBugNumbers = bugNumbers.filter(num => num !== currentBugId); console.log('Filtered bug numbers (excluding current bug ID):', filteredBugNumbers); filteredBugNumbers.forEach(bugNumber => { const url = `http://launchpad.net/bugs/${bugNumber}`; console.log(`Opening tab for bug ${bugNumber}: ${url}`); GM_openInTab(url, { active: false }); }); }); // Insert button inline after verification-bugs line console.log('Modifying p element to insert button'); const innerHTML = targetP.innerHTML; // Log a snippet of innerHTML around verification-bugs for debugging const verificationIndex = innerHTML.toLowerCase().indexOf('verification-<wbr>bugs'); if (verificationIndex !== -1) { const snippetStart = Math.max(0, verificationIndex - 100); const snippetEnd = verificationIndex + 200; console.log('innerHTML snippet around verification-bugs:', innerHTML.substring(snippetStart, snippetEnd)); } else { console.log('verification-bugs not found in innerHTML'); } // Find the verification-bugs text node (search for 'verification-' due to <wbr>) const textNodes = document.evaluate( ".//text()[contains(., 'verification-')]", targetP, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null ); if (textNodes.snapshotLength > 0) { console.log(`Found ${textNodes.snapshotLength} text nodes containing 'verification-'`); const verificationNode = textNodes.snapshotItem(0); let currentNode = verificationNode; let foundBracket = false; // Traverse until we find the closing ] while (currentNode && !foundBracket) { if (currentNode.nodeType === Node.TEXT_NODE && currentNode.textContent.includes(']')) { foundBracket = true; // Split the text node at ] const textContent = currentNode.textContent; const bracketIndex = textContent.indexOf(']'); if (bracketIndex !== -1) { const beforeBracket = textContent.substring(0, bracketIndex + 1); const afterBracket = textContent.substring(bracketIndex + 1); currentNode.textContent = beforeBracket; if (afterBracket) { const newTextNode = document.createTextNode(afterBracket); currentNode.parentNode.insertBefore(newTextNode, currentNode.nextSibling); } // Insert button after the ] console.log('Inserting button after closing ] of bug list'); currentNode.parentNode.insertBefore(button, currentNode.nextSibling); } } currentNode = currentNode.nextSibling; } if (!foundBracket) { console.log('No closing ] found, appending to p'); targetP.appendChild(button); } } else { console.log('No verification- text node found, appending button after p'); targetP.insertAdjacentElement('afterend', button); } console.log('Button insertion complete'); })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址