Add Text to Search Field in GHES and jump to lines with specific keywords

Adds text to the search field on GHES pages

θα χρειαστεί να εγκαταστήσετε μια επέκταση όπως το Tampermonkey, το Greasemonkey ή το Violentmonkey για να εγκαταστήσετε αυτόν τον κώδικα.

θα χρειαστεί να εγκαταστήσετε μια επέκταση όπως το Tampermonkey ή το Violentmonkey για να εγκαταστήσετε αυτόν τον κώδικα.

θα χρειαστεί να εγκαταστήσετε μια επέκταση όπως το Tampermonkey ή το Violentmonkey για να εγκαταστήσετε αυτόν τον κώδικα.

θα χρειαστεί να εγκαταστήσετε μια επέκταση όπως το Tampermonkey ή το Userscripts για να εγκαταστήσετε αυτόν τον κώδικα.

You will need to install an extension such as Tampermonkey to install this script.

Θα χρειαστεί να εγκαταστήσετε μια επέκταση διαχείρισης κώδικα χρήστη για να εγκαταστήσετε αυτόν τον κώδικα.

(Έχω ήδη έναν διαχειριστή κώδικα χρήστη, επιτρέψτε μου να τον εγκαταστήσω!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(Έχω ήδη έναν διαχειριστή στυλ χρήστη, επιτρέψτε μου να τον εγκαταστήσω!)

// ==UserScript==
// @name         Add Text to Search Field in GHES and jump to lines with specific keywords
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  Adds text to the search field on GHES pages
// @author       chaoscreater
// @match        https://github.asbbank.co.nz/*/*/actions/runs/*/job/*
// @match        https://github.com/*/*/actions/runs/*/job/*
// @grant        none
// ==/UserScript==

(function() {
	'use strict';

	// Function to get the search field (works for both ADO and GHES)
	function getSearchField() {
		// Try GHES GitHub Actions selector first
		let searchField = document.querySelector('.CheckRun-search-input');
		// Fall back to ADO selector
		if (!searchField) {
			searchField = document.querySelector('.find-box input.bolt-textfield-input');
		}
		return searchField;
	}

	// Function to add text to the search field
	function addTextToSearchField() {
		// Try ADO search button
		const searchButton = document.querySelector('button#__bolt-log-search');
		if (searchButton) {
			searchButton.click(); // Click on the search button
			// Wait for a short delay to ensure the search field is fully populated
			setTimeout(() => {
				const searchField = getSearchField();

				if (searchField) {
					// set the input value using the native setter
					const nativeInputValueSetter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, 'value').set;
					nativeInputValueSetter.call(searchField, 'to add');

					// Dispatch an input event to simulate user input
					searchField.dispatchEvent(new Event('input', {
						bubbles: true
					}));
				}
			}, 1000); // Adjust delay time as needed
		}
	}

	// Function to append the buttons with CSS styling
	function appendButtons() {
		const button = createButton('Jump to Terraform action start', 'green', Terraform_action_start_handleButtonClick, 'jumpToTerraformActionStart', '990px');
		const button2 = createButton('Jump to Plan line', 'orange', Terraform_plan_line_handleButtonClick, 'jumpToPlanLine', '1213px');
		const button3 = createButton('Jump to No Changes', 'orange', Terraform_plan_no_changes_line_handleButtonClick, 'jumpToNoChanges', '1350px');
		document.body.appendChild(button);
		document.body.appendChild(button2);
		document.body.appendChild(button3);
	}

	// Function to create a button with specified properties
	function createButton(text, color, clickHandler, id, left) {
		const button = document.createElement('button');
		button.textContent = text;
		button.style.position = 'fixed';
		button.style.top = '100px'; // Adjusted top position
		button.style.left = left;
		button.style.zIndex = '9999';
		button.style.backgroundColor = color;
		button.setAttribute('data-button-id', id);
		button.addEventListener('click', clickHandler);
		return button;
	}

	// Function to remove the appended buttons
	function removeButtons() {
		const buttons = document.querySelectorAll('button[data-button-id="jumpToTerraformActionStart"], button[data-button-id="jumpToPlanLine"], button[data-button-id="jumpToNoChanges"]');
		buttons.forEach(button => button.remove());
	}

	// Function to expand the search button
	function expandSearchButton() {
		const searchButton = document.querySelector('button[data-is-focusable="true"][aria-label="Search phrases"]');
		if (searchButton) {
			setTimeout(() => {
				searchButton.click(); // Click on the search button to expand it
			}, 1200);
		}
	}

	// Function to handle button click event
	function Terraform_action_start_handleButtonClick() {
		const searchField = getSearchField();
		if (searchField) {
			searchField.focus(); // Focus on the search field
			const nativeInputValueSetter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, 'value').set;
			nativeInputValueSetter.call(searchField, 'Terraform will perform the following actions:');

			// Dispatch an input event to simulate user input
			searchField.dispatchEvent(new Event('input', {
				bubbles: true
			}));
		}
	}

	// Function to handle button click event
	function Terraform_plan_line_handleButtonClick() {
		const searchField = getSearchField();
		if (searchField) {
			searchField.focus(); // Focus on the search field
			const nativeInputValueSetter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, 'value').set;
			nativeInputValueSetter.call(searchField, 'to add');

			// Dispatch an input event to simulate user input
			searchField.dispatchEvent(new Event('input', {
				bubbles: true
			}));
		}
	}

	// Function to handle button click event
	function Terraform_plan_no_changes_line_handleButtonClick() {
		const searchField = getSearchField();
		if (searchField) {
			searchField.focus(); // Focus on the search field
			const nativeInputValueSetter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, 'value').set;
			nativeInputValueSetter.call(searchField, 'No changes.');

			// Dispatch an input event to simulate user input
			searchField.dispatchEvent(new Event('input', {
				bubbles: true
			}));
		}
	}

	// Function to check if current URL matches the @match patterns
	function isMatchingUrl() {
		const pathname = window.location.pathname;
		// Match pattern: /*/*/actions/runs/*/job/*
		const pattern = /^\/[^/]+\/[^/]+\/actions\/runs\/[^/]+\/job\/[^/]+/;
		return pattern.test(pathname);
	}

	// Initialize: Wait for page to load, then append buttons
	function init() {
		// Check if we're on a matching GitHub Actions job page
		if (isMatchingUrl()) {
			// Wait a bit for the page to fully load
			setTimeout(() => {
				appendButtons();
			}, 1500);
		} else {
			// Remove buttons if they exist but we're not on a matching page
			removeButtons();
		}
	}

	// Monitor URL changes for single-page navigation
	let lastUrl = window.location.href;
	const urlObserver = new MutationObserver(() => {
		const currentUrl = window.location.href;
		if (currentUrl !== lastUrl) {
			lastUrl = currentUrl;
			// Re-run init when URL changes
			init();
		}
	});

	// Start observing URL changes
	urlObserver.observe(document.body, {
		childList: true,
		subtree: true
	});

	// Run initialization when DOM is ready
	if (document.readyState === 'loading') {
		document.addEventListener('DOMContentLoaded', init);
	} else {
		init();
	}

})();