Click on a sale price or item name to copy it to the clipboard. Also formats Price as you type with commas like 1,000,000 instead of 1000000
// ==UserScript==
// @name Quick Price Copy!
// @namespace http://tampermonkey.net/
// @version 1.2
// @description Click on a sale price or item name to copy it to the clipboard. Also formats Price as you type with commas like 1,000,000 instead of 1000000
// @author Lucky11
// @match https://fairview.deadfrontier.com/onlinezombiemmo/index.php?page=35
// @match https://fairview.deadfrontier.com/onlinezombiemmo/index.php?page=27*
// @grant none
// @license MIT
// ==/UserScript==
(function() {
'use strict';
// // // // // // // // // // // // //
// //
// Quick Price Copy! Settings //
// // // // // // // // // // // // //
// Toggle variables
const Price_Undercut_Value = 1;
let Show_Feedback = true;
let enablePriceCopying = true;// Set to false to disable price copying
let enableNameCopying = true;// Set to false to disable name copying
// // // // // // // // // // // // //
// 1,000,000 //
// Price Input Modifier Settings //
// // // // // // // // // // // // //
let enable_price_modifying = true;
function showCopyFeedback(price) {
const feedback = document.createElement('div');
feedback.textContent = `Copied: ${price}`;
feedback.style.position = 'absolute';
feedback.style.bottom = '250px';
feedback.style.left = '50%';
feedback.style.width = '90%';
feedback.style.maxWidth = '300px';
feedback.style.height = '19px';
feedback.style.backgroundColor = 'rgba(0, 0, 0, 0.9)';
feedback.style.textAlign = 'center';
feedback.style.fontSize = '15px';
feedback.style.border = '2px solid rgb(153, 0, 0)';
feedback.style.padding = '2px 3px';
feedback.style.color = 'white';
feedback.style.zIndex = '1000';
feedback.style.transform = 'translateX(-50%)';
const invController = document.getElementById('invController');
invController.appendChild(feedback);
setTimeout(() => {
invController.removeChild(feedback);
}, 1000);
}
function copyToClipboard(text) {
const textarea = document.createElement('textarea');
textarea.value = text;
document.body.appendChild(textarea);
textarea.select();
const successful = document.execCommand('copy');
document.body.removeChild(textarea);
}
function addClickListenerToPricesAndNames() {
const salePrices = document.querySelectorAll('.salePrice');
const itemNames = document.querySelectorAll('.itemName');
salePrices.forEach(priceElement => {
if (enablePriceCopying && !priceElement.dataset.listenerAdded) {
priceElement.style.cursor = 'pointer';
priceElement.addEventListener('click', (event) => {
event.stopPropagation();
const priceText = priceElement.textContent.replace(/[^0-9]/g, '');
const priceValue = parseInt(priceText, 10) - Price_Undercut_Value;
copyToClipboard(priceValue.toString());
if (Show_Feedback) {
showCopyFeedback(priceValue.toString());
}
changeColor(priceElement);
});
priceElement.dataset.listenerAdded = 'true';
}
});
itemNames.forEach(nameElement => {
if (enableNameCopying && !nameElement.dataset.listenerAdded) {
nameElement.style.cursor = 'pointer';
nameElement.addEventListener('click', (event) => {
event.stopPropagation();
const itemName = nameElement.textContent;
copyToClipboard(itemName);
if (Show_Feedback) {
showCopyFeedback(itemName);
}
changeColor(nameElement);
});
nameElement.dataset.listenerAdded = 'true';
}
});
}
function changeColor(element) {
const originalColor = element.style.color;
element.style.color = '#28a745';
setTimeout(() => {
element.style.color = originalColor;
}, 700);
}
const observer = new MutationObserver((mutations) => {
let pricesFound = false;
mutations.forEach(() => {
const salePrices = document.querySelectorAll('.salePrice');
const itemNames = document.querySelectorAll('.itemName');
if (salePrices.length > 0 || itemNames.length > 0) {
pricesFound = true;
addClickListenerToPricesAndNames();
}
});
});
//observer.observe(document.body, { childList: true, subtree: true });
// Observe specific elements only not whole body as above
const targetNode = document.querySelector('#marketplace');
if (targetNode) {
observer.observe(targetNode, { childList: true, subtree: true });
}
// Create a new style element
const style = document.createElement('style');
// Add CSS rules for the classes and pseudo-elements
style.textContent = `
.itemName::before,
.itemName::after {
z-index: -1; /* Put pseudo-elements below item names */
}
.itemName {
z-index: 10; /* Bring itemName in front */
}
.salePrice, .itemName {
cursor: pointer !important; /* Ensure both classes have pointer cursor */
}
`;
// Append the style element to the head of the document
document.head.appendChild(style);
// // // // // // // // // //
// 1,000,000 //
// Price Input Modifier //
// // // // // // // // // //
//
// This script creates a fake text box positioned beneath the real price input.
// The fake box displays the formatted price with commas (e.g. 1,000,000).
// The real input is made transparent, so users see the formatted value instead
// while their input is captured and formatted seamlessly.
//
const observer1 = new MutationObserver(() => {
setup();
});
const setup = () => {
if (!enable_price_modifying) return; // Early exit if disabled
const df_prompt = document.getElementById('prompt');
if (df_prompt) {
const gameContent = document.getElementById('gamecontent');
let priceHolder = gameContent.querySelector('#priceHolder');
let priceInput = gameContent.querySelector("input[data-type='price']");
let priceInputFake = gameContent.querySelector('#priceInputFake');
if (!priceHolder) {
priceHolder = document.createElement("div");
priceHolder.id = "priceHolder";
priceHolder.style.position = "absolute";
priceHolder.style.width = "100%";
priceHolder.style.textAlign = "center";
priceHolder.style.bottom = "30px";
priceHolder.style.display = "flex";
priceHolder.style.flexDirection = "column";
priceHolder.style.alignItems = "center";
gameContent.appendChild(priceHolder);
}
if (priceInput && !priceInputFake) {
const dollarLabel = document.createElement('label');
dollarLabel.textContent = '$';
dollarLabel.style.color = 'rgb(255, 255, 0)';
dollarLabel.style.alignSelf= 'start';
dollarLabel.style.paddingLeft= '35px';
priceHolder.appendChild(dollarLabel);
priceInputFake = document.createElement('input');
priceInputFake.setAttribute('type', 'text');
priceInputFake.setAttribute('id', 'priceInputFake');
priceInputFake.setAttribute('readonly', true);
priceInputFake.setAttribute('placeholder', 'Enter your price');
// Apply styles to priceInput
priceInput.style.cssText = `
width: 180px;
padding: 2px;
height: 13px;
font-family: MS Shell Dlg 2;
font-size: 11px;
position: absolute;
left: 50%;
transform: translateX(-50%);
background: transparent !important; /* Make background transparent of real text input without commas 1000000 */
border: none !important; /* Remove border */
color: transparent !important; /* clear real input box text by making it transparent */
`;
// Appending fake input styles
priceInputFake.style.cssText = `
width: 180px;
color: #ffff00;
padding: 2px;
border: none;
height: 13px;
font-family: MS Shell Dlg 2;
font-size: 11px;
position: absolute;
left: 50%;
transform: translateX(-50%);
background: rgba(89, 0, 0, 0.9);/* Remove image and repeat below to change color of the input box for price! */
background-image: url(https://fairview.deadfrontier.com/onlinezombiemmo/Themes/deadfrontier/images/HD/input.gif);
background-repeat: repeat-x;
`;
priceHolder.appendChild(priceInputFake); // Append fake input
priceHolder.appendChild(priceInput); // Append real input
// Sync initial value of priceInput to priceInputFake
priceInputFake.value = formatWithCommas(priceInput.value); // Add this line
// Focus the priceInput when it is added to the DOM
priceInput.focus();
}
if (priceInputFake) {
priceInput.addEventListener('input', () => {
const numericValue = priceInput.value;
priceInputFake.value = formatWithCommas(numericValue);
});
}
}
};
const formatWithCommas = (value) => {
const num = Number(value);
return isNaN(num) ? '' : num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
};
const prompt = document.getElementById('prompt');
if (prompt) {
observer1.observe(prompt, { childList: true, subtree: true });
setup(); // Initial setup
//console.log('Price Input Modifier Started');
}
})();