Widget:Calculator/HighLite/Nameplates
<style> /* General widget container styling */
- widget-main-container {
max-width: 600px; margin: 20px auto; padding: 15px; background-color: var(--bg-main, #1e1f22); color: var(--text-main, #b6b4b2); border: 1px solid var(--border-color-base, #2d2d2d); border-radius: 5px; font-family: sans-serif;
}
- widget-main-container h2, #widget-main-container h3 {
color: var(--text-heading, #d1ccc6); margin-top: 10px; margin-bottom: 10px;
}
- loading-indicator, #error-message {
padding: 10px; text-align: center;
}
/* Styles for search input */
- item-search {
width: calc(100% - 20px); padding: 8px 10px; margin-bottom: 15px; background-color: var(--bg-secondary, #28292d); color: var(--text-main, #b6b4b2); border: 1px solid var(--border-color-base, #3d3d3d); border-radius: 4px;
}
/* Styles for output textarea */
- output-list {
width: 100%; background-color: var(--bg-secondary, #28292d); color: var(--text-main, #b6b4b2); border: 1px solid var(--border-color-base, #2d2d2d); border-radius: 4px; padding: 10px; font-family: monospace; resize: vertical;
}
/* Styles for copy button */
- copy-button {
background-color: #007bff; color: white; border: none; border-radius: 4px; padding: 10px 15px; cursor: pointer; font-size: 16px; margin-top: 10px;
}
- copy-button:hover {
background-color: #0056b3;
}
- copy-feedback {
margin-left: 10px; color: green;
}
/* Styles for the main table headers and cells */
- item-display-table {
border-collapse: collapse; margin-top: 20px; background-color: var(--bg-secondary, #28292d); border: 1px solid var(--border-color-base, #2d2d2d); border-radius: 5px;
}
- item-display-table th, #item-display-table td {
border: 1px solid var(--border-color-light, #3a3b3e); padding: 8px; text-align: left;
}
- item-display-table th {
background-color: var(--bg-dark, #1a1b1e); color: var(--text-heading, #d1ccc6);
}
/* Styles for the buttons within table cells */ .nameplate-buttons-cell {
white-space: nowrap;
}
.item-status-buttons {
display: flex; gap: 5px;
}
/* Base style for ALL buttons - ULTIMATE SPECIFICITY */ /* Using multiple IDs and classes to ensure these styles win */
- item-display-table td.nameplate-buttons-cell div.item-status-buttons button {
flex-grow: 1 !important; /* Ensure consistent width distribution */ border-radius: 4px !important; text-align: center !important; font-weight: bold !important; white-space: nowrap !important; cursor: pointer !important; transition: background-color 0.2s, color 0.2s, border-color 0.2s !important;
/* Default INACTIVE styling (gray) */ background-color: #2a2c2f !important; border: 1px solid #444 !important; color: #b6b4b2 !important;
/* Consistent Sizing */ padding: 4px 8px !important; font-size: 0.85em !important; min-width: 60px !important; height: auto !important; /* Let content dictate height, prevent fixed height */ line-height: normal !important; /* Standard line height */
}
/* Hover state for inactive buttons */
- item-display-table td.nameplate-buttons-cell div.item-status-buttons button:not(.active):hover {
background-color: #3a3a3a !important; border-color: #0fc065 !important; color: #0fc065 !important;
}
/* ACTIVE button style (green) */
- item-display-table td.nameplate-buttons-cell div.item-status-buttons button.active {
background-color: #0fc065 !important; border-color: #0fc065 !important; color: #000 !important; /* Black text for contrast */
/* Ensure consistent sizing for active state too */ padding: 4px 8px !important; font-size: 0.85em !important; min-width: 60px !important; height: auto !important; line-height: normal !important;
} </style>
<script> (function() {
'use strict';
// Global variables for elements let itemSearchInput; let itemDisplayTable; // This refers to the table on the main page where Cargo outputs let outputListTextarea; let copyButton; let copyFeedback; let allItems = []; // To store all fetched items and their current states
// Store a reference to the tbody element where event listeners will be attached let tableTbodyElement = null;
const DEFAULT_ITEM_LIST = "Acorn:0,Alchemy Scroll:0,Amethyst Gem:0,Amethyst Necklace:-1,Archer's Boots:1,Archer's Cape:1,Archer's Gloves:1,Armoury Key:0,Arrow Shafts:0,Aruba Root:-1,Baked Potato:-1,Bandit Mask:1,Barbarian Helm:0,Basic Rod:-1,Bass:-1,Beer:-1,Black Bear Paw:-1,Black Cape:-1,Black Leather Boots:0,Black Leather Gloves:-1,Blood Gloves:1,Blood Hat:1,Blood Hood:1,Blood Robe Bottoms:1,Blood Robe Top:1,Blood Scroll:0,Blue Cape:-1,Blue Headband:0,Blue Santa Hat:1,Blue Wizard's Boots:1,Blue Wizard's Bottoms:0,Blue Wizard's Gloves:1,Blue Wizard's Hat:0,Blue Wizard's Top:0,Bluegill:-1,Bone Meal:-1,Bones:-1,Bottle Of Rum:-1,Bronze Arrowheads:0,Bronze Arrows:0,Bronze Bar:0,Bronze Battleaxe:-1,Bronze Chainmail Body:-1,Bronze Chestplate:-1,Bronze Full Helm:-1,Bronze Gloves:-1,Bronze Great Sword:-1,Bronze Hatchet:-1,Bronze Helm:-1,Bronze Longsword:-1,Bronze Pickaxe:-1,Bronze Platelegs:-1,Bronze Scimitar:-1,Bronze Shield:-1,Brown Bear Paw:-1,Burnt Food:-1,Calcium Brew:-1,Carbonado Gem:1,Carbonado Necklace:0,Carp:-1,Carrot:-1,Cave Bear Paw:-1,Celadium Bar:1,Celadium Ore:1,Celadon Arrowheads:0,Celadon Arrows:0,Celadon Battleaxe:1,Celadon Chainmail Body:1,Celadon Chainmail Body (Gold Plating):1,Celadon Chainmail Body (Silver Plating):1,Celadon Chestplate:1,Celadon Chestplate (Gold Plating):1,Celadon Chestplate (Silver Plating):1,Celadon Full Helm:1,Celadon Full Helm (Gold Plating And Gold Plume):1,Celadon Full Helm (Gold Plating):1,Celadon Full Helm (Gold Plume):1,Celadon Full Helm (Purple Plume):1,Celadon Full Helm (Silver Plating And Gold Plume):1,Celadon Full Helm (Silver Plating):1,Celadon Gloves:1,Celadon Gloves (Gold Plating):1,Celadon Gloves (Silver Plating):1,Celadon Great Sword:1,Celadon Hatchet:1,Celadon Helm:1,Celadon Helm (Gold Plating):1,Celadon Helm (Silver Plating):1,Celadon Longsword:1,Celadon Orb (Dim Glow):1,Celadon Orb (Extremely Bright):1,Celadon Orb (Barely Glowing):1,Celadon Orb (Fairly Bright):1,Celadon Orb (Dull):1,Celadon Orb (Faint Glow):1,Celadon Pickaxe:1,Celadon Platelegs:1,Celadon Platelegs (Gold Plating):1,Celadon Platelegs (Silver Plating):1,Celadon Scimitar:1,Celadon Shield:1,Celadon Shield (Gold Plating And Gold Trim):1,Celadon Shield (Gold Plating):1,Celadon Shield (Gold Trim):1,Celadon Shield (Silver Plating And Gold Trim):1,Celadon Shield (Silver Plating):1,Champion's Cape:1,Charred Bone Meal:-1,Charred Bones:-1,Chef's Hat:-1,Cherry Blossom:0,Cherry Bow:0,Cherry Logs:0,Chicken (Cooked):-1,Chisel:-1,Christmas Present (Green):1,Christmas Present (Red):1,Christmas Present (Blue):1,Christmas Present (White):1,Citrine Gem:0,Citrine Necklace:-1,Clownfish:-1,Coal:0,Coconut:0,Coins:0,Conch:-1,Copper Ore:0,Corn:-1,Coronium Arrowheads:0,Coronium Arrows:0,Coronium Bar:0,Coronium Battleaxe:0,Coronium Chainmail Body:0,Coronium Chainmail Body (Gold Plating):1,Coronium Chainmail Body (Silver Plating):1,Coronium Chestplate:0,Coronium Chestplate (Gold Plating):1,Coronium Chestplate (Silver Plating):1,Coronium Full Helm:0,Coronium Full Helm (Gold Plating And Gold Plume):1,Coronium Full Helm (Gold Plating):1,Coronium Full Helm (Gold Plume):1,Coronium Full Helm (Purple Plume):1,Coronium Full Helm (Silver Plating And Gold Plume):1,Coronium Full Helm (Silver Plating):1,Coronium Gloves:0,Coronium Gloves (Gold Plating):1,Coronium Gloves (Silver Plating):1,Coronium Great Sword:0,Coronium Hatchet:0,Coronium Helm:0,Coronium Helm (Gold Plating):1,Coronium Helm (Silver Plating):1,Coronium Longsword:0,Coronium Ore:0,Coronium Pickaxe:0,Coronium Platelegs:0,Coronium Platelegs (Gold Plating):1,Coronium Platelegs (Silver Plating):1,Coronium Scimitar:0,Coronium Shield:0,Coronium Shield (Gold Plating And Gold Trim):1,Coronium Shield (Gold Plating):1,Coronium Shield (Gold Trim):1,Coronium Shield (Silver Plating And Gold Trim):1,Coronium Shield (Silver Plating):1,Crab:0,Cyclops Eye:0,Damogui's Staff:1,Dark Hood:-1,Deadwood Bow:0,Deadwood Logs:0,Deadwood Scroll:0,Dew Beer:-1,Diamond Gem:1,Diamond Necklace:0,Driftwood:-1,Druid's Hood:-1,Elf Ears:0,Ember Staff:1,Emerald Gem:0,Emerald Necklace:-1,Empty Bottle:-1,Empty Glass:-1,Empty Turtle Shell:-1,Energy Scroll:0,Feathers:0,Fiji Root:-1,Fire Dragonleather:0,Fire Dragonleather Bracers:0,Fire Dragonleather Chaps:0,Fire Scroll:0,Flax:-1,Flour:-1,Forest Staff:1,Frog:-1,Fury Scroll:0,Game Meat:-1,Giant Bones:-1,Giant Gnome's Hat:0,Giant Gnome's Top:0,Giant's Milk:-1,Glass Of Water:-1,Gnome Jail Key:0,Gnome's Hat:-1,Goblin Banker's Key:0,Goblin Whistle:1,Gold Amethyst Necklace:1,Gold Bar:0,Gold Carbonado Necklace:1,Gold Citrine Necklace:0,Gold Diamond Necklace:1,Gold Emerald Necklace:1,Gold Nugget:0,Gold Ruby Necklace:1,Gold Sapphire Necklace:0,Gold Topaz Necklace:1,Gold Warrior Helm:1,Golden Acorn:1,Golden Blossom:1,Golden Coconut:1,Golden Leaf:1,Golden Pinecone:1,Grapes:0,Great Rod:-1,Green Cape:-1,Green Headband:0,Green Santa Hat:1,Grenada Root:-1,Grilled Corn:-1,Half Glass Of Beer:-1,Half Glass Of Calcium Brew:-1,Half Glass Of Dew Beer:-1,Half Glass Of Giant's Milk:-1,Halo:1,Hammer:-1,Headless Arrows:0,Helmet Of Magic:1,Helmet Of Melee:1,Helmet Of Ranging:1,Hydro Staff:1,Iron Arrowheads:0,Iron Arrows:0,Iron Bar:0,Iron Battleaxe:-1,Iron Chainmail Body:-1,Iron Chestplate:-1,Iron Full Helm:-1,Iron Gloves:-1,Iron Great Sword:-1,Iron Hatchet:-1,Iron Helm:-1,Iron Longsword:-1,Iron Ore:0,Iron Pickaxe:-1,Iron Platelegs:-1,Iron Scimitar:-1,Iron Shield:-1,Kitchen Key:0,Knife:-1,Knight's Cape:1,Koi:-1,Leaf:0,Leather:-1,Leather Body Armour:-1,Leather Boots:-1,Leather Bracers:-1,Leather Chaps:-1,Leather Gloves:-1,Legendary Battleaxe:1,Legendary Gloves:1,Legendary Longsword:1,Legendary Scimitar:1,Legendary Shield:1,Leprechaun Flute:1,Leprechaun Hat:1,Leprechaun Sketch:1,Logs:0,Lucky Logs:0,Lucky Scroll:0,Magic Scroll:0,Magician's Cape:1,Mansion Key:0,Mariana Root:0,Marlin:0,Master Rod:1,Maui Root:-1,Message In A Bottle:1,Money Bag:0,Monk's Necklace:-1,Monk's Necklace Mould:-1,Mt. Tan Dew:-1,Nature Scroll:0,Nauru Root:-1,Necklace Mould:-1,Oak Bow:-1,Oak Logs:0,Oak Scroll:0,Octopus:0,Old Hood:-1,Onion:-1,Orange Cape:-1,Palladium Arrowheads:0,Palladium Arrows:0,Palladium Bar:0,Palladium Battleaxe:0,Palladium Chainmail Body:0,Palladium Chestplate:0,Palladium Full Helm:0,Palladium Gloves:0,Palladium Great Sword:0,Palladium Hatchet:0,Palladium Helm:0,Palladium Longsword:0,Palladium Ore:0,Palladium Pickaxe:0,Palladium Platelegs:-1,Palladium Scimitar:0,Palladium Shield:0,Palm Bow:0,Palm Logs:0,Palm Scroll:0,Pestle And Mortar:-1,Pig Iron Bar:-1,Pine Bow:-1,Pine Logs:0,Pine Scroll:0,Pinecone:0,Piranha:-1,Pirate's Bandana:-1,Pirate's Key:1,Plains Dragonleather:0,Plains Dragonleather Bracers:0,Plains Dragonleather Chaps:0,Potato:-1,Potion Of Accuracy (1):-1,Potion Of Accuracy (2):0,Potion Of Defense (1):-1,Potion Of Defense (2):0,Potion Of Fishing (1):-1,Potion Of Fishing (2):0,Potion Of Forestry (1):0,Potion Of Forestry (2):0,Potion Of Magic (1):-1,Potion Of Magic (2):0,Potion Of Mining (1):-1,Potion Of Mining (2):0,Potion Of Mischief (1):-1,Potion Of Mischief (2):0,Potion Of Restoration (1):-1,Potion Of Restoration (2):0,Potion Of Smithing (1):-1,Potion Of Smithing (2):0,Potion Of Strength (1):-1,Potion Of Strength (2):0,Pumpkin:-1,Purple Cape:-1,Rage Scroll:0,Rat Tail:-1,Raw Bass:-1,Raw Beef:-1,Raw Bluegill:-1,Raw Carp:-1,Raw Chicken:-1,Raw Clownfish:0,Raw Crab:0,Raw Frog:-1,Raw Game Meat:-1,Raw Koi:-1,Raw Marlin:0,Raw Octopus:0,Raw Piranha:-1,Raw Rodent Meat:-1,Raw Salmon:-1,Raw Stingray:-1,Raw Tuna:0,Raw Turtle:-1,Raw Walleye:-1,Raw Whaleshark:0,Red Cape:-1,Red Headband:0,Red Mushroom:-1,Red Santa Hat:1,Robe Bottoms:-1,Robe Top:-1,Rodent Meat:-1,Rose:0,Rough Amethyst:0,Rough Carbonado:1,Rough Citrine:0,Rough Diamond:1,Rough Emerald:0,Rough Ruby:0,Rough Sapphire:0,Rough Topaz:0,Royal Cape:1,Ruby Gem:0,Ruby Necklace:0,Sage's Bottoms:-1,Sage's Top:-1,Sakura Scroll:0,Salmon:-1,Samoan Root:-1,Sand Dollar:-1,Sapphire Gem:0,Sapphire Necklace:-1,Sardinian Root:-1,Scallop Shell:-1,Scroll:0,Seashell Shores Bank Key:0,Seaweed:-1,Sewer Key:0,Shovel:-1,Silver Bar:0,Silver Nugget:0,Silver Warrior Helm:1,Squirrel Pelt:-1,Staff:-1,Starfish:-1,Steak:-1,Steel Arrowheads:0,Steel Arrows:0,Steel Bar:0,Steel Battleaxe:0,Steel Chainmail Body:0,Steel Chestplate:-1,Steel Full Helm:-1,Steel Gloves:-1,Steel Great Sword:0,Steel Hatchet:-1,Steel Helm:-1,Steel Longsword:-1,Steel Pickaxe:-1,Steel Platelegs:0,Steel Scimitar:-1,Steel Shield:0,Stingray:0,Strawberry:-1,String:0,Tattered Skirt:-1,Tin Ore:0,Tomato:-1,Tonga Root:-1,Topaz Gem:0,Topaz Necklace:-1,Treasure Map:1,Trumpet:1,Tuna:0,Turtle:0,Ultra Rod:0,Undercroft Key:0,Unheated Dew Mash:-1,Unheated Mash:-1,Unstrung Bow:-1,Unstrung Cherry Bow:0,Unstrung Deadwood Bow:0,Unstrung Oak Bow:-1,Unstrung Palm Bow:0,Unstrung Pine Bow:-1,Unstrung Wizard's Bow:0,Uranium Ore:1,Vanua Root:0,Vial:-1,Vial Of Water:-1,Walleye:-1,Warp Scroll:0,Water Dragonleather:0,Water Dragonleather Bracers:0,Water Dragonleather Chaps:0,Water Scroll:0,Watermelon:-1,Whaleshark:0,Wheat:-1,Witch's Bottoms:-1,Witch's Hat:-1,Witch's Top:-1,Wizard Logs:0,Wizard Scroll:0,Wizard's Boots:0,Wizard's Bottoms:0,Wizard's Bow:0,Wizard's Gloves:0,Wizard's Hat:0,Wizard's Top:0,Wooden Bow:-1,Yellow Cape:-1";
/** * Strips disambiguation from item names like "(Tier X)" or "(Room Name)". * @param {string} name The original item name. * @returns {string} The consolidated item name. */ function getConsolidatedItemName(name) { if (name.startsWith("Treasure Map (Tier")) { return "Treasure Map"; } if (name.startsWith("Undercroft Key (")) { return "Undercroft Key"; } return name; }
/** * Injects the calculator's control HTML into the designated wrapper. */ function injectCalculatorControls() { const wrapper = document.getElementById('nameplate-calculator-wrapper'); if (!wrapper) { console.error('Error: #nameplate-calculator-wrapper not found on the page. Widget cannot initialize.'); return; }
// Inject the control HTML including search, output, and copy button wrapper.innerHTML = `
Initializing calculator...
`;
// Assign elements to global variables AFTER they are injected itemSearchInput = document.getElementById('item-search'); outputListTextarea = document.getElementById('output-list'); copyButton = document.getElementById('copy-button'); copyFeedback = document.getElementById('copy-feedback'); itemDisplayTable = document.getElementById('item-display-table'); // Get reference to the table on the main page }
/** * Initializes the interactive buttons and state for each item in the table. */ function initializeItemRows() { const loadingIndicator = document.getElementById('loading-indicator'); const errorMessage = document.getElementById('error-message'); const calculatorControls = document.getElementById('calculator-controls');
if (!itemDisplayTable || !itemDisplayTable.tBodies[0] || itemDisplayTable.tBodies[0].rows.length === 0) { errorMessage.textContent = 'Error: Item data table not found or empty. Please ensure your Cargo query is correct and populating the table correctly.'; errorMessage.style.display = 'block'; if (loadingIndicator) loadingIndicator.style.display = 'none'; console.error('Item display table (ID: item-display-table) not found or has no tbody/rows after waiting.'); return; }
// Store the tbody element once it's confirmed to exist tableTbodyElement = itemDisplayTable.tBodies[0]; const rows = Array.from(tableTbodyElement.rows); // Convert to array for easier manipulation
// Temporary map to hold consolidated items and their determined state // Key: consolidated item name, Value: { name, state, rowElement (primary one), buttonsCell (primary one) } const consolidatedItemsMap = new Map();
rows.forEach(row => { const itemNameLinkCell = row.cells[1]; const itemNameLink = itemNameLinkCell ? itemNameLinkCell.querySelector('a') : null; const originalItemName = itemNameLink ? itemNameLink.textContent.trim() : ;
if (!originalItemName) { console.warn('Skipping row due to missing original item name:', row); row.style.display = 'none'; // Hide rows without a name return; }
const consolidatedName = getConsolidatedItemName(originalItemName); const buttonsCell = row.querySelector('.nameplate-buttons-cell');
if (!buttonsCell) { console.warn('Skipping row due to missing buttons cell:', row); row.style.display = 'none'; // Hide rows without a buttons cell return; }
// Check if we've already processed this consolidated item if (!consolidatedItemsMap.has(consolidatedName)) { // This is the first time we see this consolidated item name consolidatedItemsMap.set(consolidatedName, { name: consolidatedName, state: -1, // Default to hide initially, will be overridden by DEFAULT_ITEM_LIST rowElement: row, // This row will be the primary one for this consolidated item buttonsCell: buttonsCell // This cell will host the buttons });
// Update the displayed item name in the table if (itemNameLink) { itemNameLink.textContent = consolidatedName; } else { // Fallback if no link, though usually there should be one itemNameLinkCell.textContent = consolidatedName; }
// Create and append buttons to this consolidated item's primary buttonsCell const buttonsContainer = document.createElement('div'); buttonsContainer.className = 'item-status-buttons'; buttonsContainer.dataset.itemName = consolidatedName; // For event delegation
const states = [ { value: -1, text: 'Hide' }, { value: 0, text: 'Default' }, { value: 1, text: 'Priority' } ];
states.forEach(state => { const button = document.createElement('button'); button.textContent = state.text; button.dataset.value = state.value; buttonsContainer.appendChild(button); });
buttonsCell.appendChild(buttonsContainer);
} else { // This is a duplicate of a consolidated item, so hide its row row.style.display = 'none'; // And remove any buttons that might have been automatically rendered by Cargo for it if (buttonsCell) { buttonsCell.innerHTML = ; // Clear contents of the button cell } } });
// Convert the map values to an array for allItems allItems = Array.from(consolidatedItemsMap.values());
// Apply the default list or any saved state to the consolidated items parseAndApplyList(DEFAULT_ITEM_LIST); // This will update the 'state' in allItems
generateOutputList(); // Initial generation of the output list
if (loadingIndicator) loadingIndicator.style.display = 'none'; if (calculatorControls) calculatorControls.style.display = 'block';
// --- Attach ONE event listener to the tbody for ALL button clicks --- tableTbodyElement.addEventListener('click', (event) => { const clickedButton = event.target.closest('button'); const buttonsContainer = clickedButton ? clickedButton.closest('.item-status-buttons') : null;
if (clickedButton && buttonsContainer) { const itemName = buttonsContainer.dataset.itemName; const newState = parseInt(clickedButton.dataset.value, 10);
const itemObj = allItems.find(i => i.name === itemName); if (itemObj) { itemObj.state = newState; }
// Update active classes for buttons within this specific item's container Array.from(buttonsContainer.children).forEach(btn => { if (parseInt(btn.dataset.value, 10) === newState) { btn.classList.add('active'); } else { btn.classList.remove('active'); } }); generateOutputList(); // Auto-update the list } }); }
/** * Generates the comma-separated output list. */ function generateOutputList() { const output = allItems .map(item => `${item.name}:${item.state}`) .join(','); outputListTextarea.value = output; }
/** * Filters the item list based on search input by hiding/showing table rows. */ function filterItemList() { const searchTerm = itemSearchInput.value.toLowerCase(); allItems.forEach(item => { // We only care about the single primary row for each consolidated item for display const row = item.rowElement; if (row) { if (item.name.toLowerCase().includes(searchTerm)) { row.style.display = ; // Show the primary row } else { row.style.display = 'none'; // Hide the primary row } } }); }
/** * Copies the generated list to the clipboard. */ function copyToClipboard() { outputListTextarea.select(); outputListTextarea.setSelectionRange(0, 99999);
try { document.execCommand('copy'); copyFeedback.textContent = 'Copied!'; setTimeout(() => { copyFeedback.textContent = , 2000; }); } catch (err) { console.error('Failed to copy text: ', err); copyFeedback.textContent = 'Failed to copy.'; setTimeout(() => { copyFeedback.textContent = , 2000; }); } }
/** * Parses a list string and applies the settings to the item buttons. * @param {string} listString The comma-separated list of "ItemName:Value" */ function parseAndApplyList(listString) { const newSettings = new Map(); // Use a Map to store parsed settings and consolidate
listString.split(',').forEach(entry => { const parts = entry.trim().split(':'); if (parts.length === 2) { const originalItemName = parts[0].trim(); const value = parseInt(parts[1].trim(), 10);
if (!isNaN(value) && [ -1, 0, 1 ].includes(value)) { const consolidatedName = getConsolidatedItemName(originalItemName); const existingValue = newSettings.has(consolidatedName) ? newSettings.get(consolidatedName) : -2; // Use -2 as a placeholder for "not set"
// Apply consolidation priority: Priority (1) > Default (0) > Hide (-1) if (value > existingValue) { // Higher value (more priority) wins newSettings.set(consolidatedName, value); } } } });
allItems.forEach(item => { const currentItemName = item.name; // This is already the consolidated name let newState = -1; // Default to Hide if not in the pasted list
if (newSettings.has(currentItemName)) { newState = newSettings.get(currentItemName); }
// Update the internal state item.state = newState;
// Update the active class on the buttons for this item (only the primary one) if (item.buttonsCell) { // Ensure buttonsCell reference exists (this will be the primary one) const buttonsContainer = item.buttonsCell.querySelector('.item-status-buttons'); if (buttonsContainer) { Array.from(buttonsContainer.children).forEach(btn => { if (parseInt(btn.dataset.value, 10) === newState) { btn.classList.add('active'); } else { btn.classList.remove('active'); } }); } } });
// Re-generate the output list based on the new states generateOutputList(); }
/** * Main entry point for the widget. */ function initWidget() { injectCalculatorControls(); // Inject the HTML for controls first
// Now that controls are injected, attach event listeners to them if (itemSearchInput) { itemSearchInput.addEventListener('input', filterItemList); } if (copyButton) { copyButton.addEventListener('click', copyToClipboard); } // Add input listener to the output list textarea for reverse engineering if (outputListTextarea) { outputListTextarea.addEventListener('input', (event) => { parseAndApplyList(event.target.value); }); }
// Use a MutationObserver to wait for the Cargo table's tbody to be generated const observer = new MutationObserver((mutations, obs) => { const table = document.getElementById('item-display-table'); // This is the ID of the table on the main page if (table && table.tBodies[0] && table.tBodies[0].rows.length > 0) { obs.disconnect(); // Stop observing once Cargo has populated the table initializeItemRows(); // Proceed with setting up buttons and interactivity } });
// Start observing the body for the main Cargo table to appear and be populated observer.observe(document.body, { childList: true, subtree: true });
// Fallback for immediate execution if DOM is already loaded and table is present if (document.readyState === 'complete') { const table = document.getElementById('item-display-table'); if (table && table.tBodies[0] && table.tBodies[0].rows.length > 0) { observer.disconnect(); initializeItemRows(); } } }
// Run initialization when the DOM is ready if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', initWidget); } else { initWidget(); }
})(); </script>