Logs and highlights entries
// ==UserScript==
// @name THE HIGHLIGHTER
// @namespace http://tampermonkey.net/
// @version 0.9
// @description Logs and highlights entries
// @author Moxsee
// @match https://www.neopets.com/*
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_deleteValue
// @run-at document-end
// ==/UserScript==
(function() {
'use strict';
const containerId = 'neopets-text-container';
const entryListId = 'entry-list';
// Create the container element
const container = document.createElement('div');
container.style.position = 'fixed';
container.style.bottom = '20px';
container.style.left = '20px';
container.style.backgroundColor = 'rgba(255, 255, 255, 0.8)';
container.style.border = '1px solid black';
container.style.padding = '10px';
container.style.zIndex = '9999';
container.id = containerId;
// Text input for adding entries
const textInput = document.createElement('input');
textInput.type = 'text';
textInput.placeholder = 'Enter text to highlight...';
textInput.style.width = '180px';
// Button to add the text to the list
const addButton = document.createElement('button');
addButton.innerText = 'Add';
// Button to clear the list
const clearButton = document.createElement('button');
clearButton.innerText = 'Clear';
// Button to clear the last entry
const clearLastButton = document.createElement('button');
clearLastButton.innerText = 'Clear Last Entry';
// List to display the entries
const entryList = document.createElement('div');
entryList.id = entryListId;
entryList.style.maxHeight = '150px';
entryList.style.overflowY = 'auto';
// Append elements to the container
container.appendChild(textInput);
// Create a div to hold the buttons, and append it to the container
const buttonContainer = document.createElement('div');
buttonContainer.appendChild(addButton);
buttonContainer.appendChild(clearButton);
buttonContainer.appendChild(clearLastButton);
container.appendChild(buttonContainer);
container.appendChild(entryList);
document.body.appendChild(container);
// Load entries from storage
let entries = GM_getValue('entries', []);
entries.forEach(entry => addEntryToList(entry));
highlightText(entries);
// Add entry to the list
function addEntryToList(entry) {
const listItem = document.createElement('div');
listItem.innerText = entry;
entryList.appendChild(listItem);
}
// Highlight text function
function highlightText(entries) {
// Remove any previous highlights
const highlightedElements = document.querySelectorAll('span.highlighted');
highlightedElements.forEach(el => {
const parent = el.parentNode;
while (el.firstChild) {
parent.insertBefore(el.firstChild, el);
}
parent.removeChild(el);
});
// If there are no entries, return early
if (!entries.length) {
return;
}
// Create a single regex pattern from all entries
const regexPattern = entries.map(entry => entry.replace(/[-\/\\^$.*+?()[\]{}|]/g, '\\$&')).join('|');
const regex = new RegExp(`(${regexPattern})`, 'gi');
// Function to replace text nodes with highlighted spans
function replaceTextNodes(node) {
if (node.nodeType === Node.TEXT_NODE) {
const originalText = node.nodeValue;
const newText = originalText.replace(regex, `<span class="highlighted" style="background-color: yellow;">$1</span>`);
if (newText !== originalText) {
const newNode = document.createElement('span');
newNode.innerHTML = newText;
node.parentNode.replaceChild(newNode, node);
}
} else if (node.nodeType === Node.ELEMENT_NODE) {
let child = node.firstChild;
while (child) {
const nextChild = child.nextSibling;
replaceTextNodes(child);
child = nextChild;
}
}
}
// Start replacing text nodes from the body
replaceTextNodes(document.body);
}
// Add button click event
addButton.addEventListener('click', function() {
const text = textInput.value.trim();
if (text && !entries.includes(text)) {
entries.push(text);
GM_setValue('entries', entries);
addEntryToList(text);
highlightText(entries);
textInput.value = '';
}
});
// Clear button click event
clearButton.addEventListener('click', function() {
entries = [];
GM_deleteValue('entries');
entryList.innerHTML = '';
highlightText([]);
});
// Clear last entry button click event
clearLastButton.addEventListener('click', function() {
if (entries.length > 0) {
entries.pop(); // Remove the last entry
GM_setValue('entries', entries); // Update the stored entries
entryList.innerHTML = ''; // Clear the display
entries.forEach(entry => addEntryToList(entry)); // Re-add remaining entries
highlightText(entries); // Update highlights
}
});
})();