// ==UserScript==
// @name Image Names
// @namespace http://tampermonkey.net/
// @version 3.0
// @description Load Image Pokemon Name By HyperBeam and RenjiYuusei
// @run-at document-end
// @author @HyperBeam & @RenjiYuusei
// @match *://sangtacviet.vip/truyen/*
// @license GPL-3.0
// @icon64 https://sangtacviet.vip/favicon.png
// @grant GM_setValue
// @grant GM_getValue
// ==/UserScript==
(function () {
'use strict';
const TYPE_STYLE = {
Normal: '#777c83',
Fire: '#ffa61e',
Water: '#5cb2de',
Electric: '#ffce2f',
Grass: '#49cb77',
Ice: '#73d7ce',
Fighting: '#e15462',
Poison: '#d54ec2',
Ground: '#cd854b',
Flying: '#85a6f4',
Psychic: '#ff8c7a',
Bug: '#98d401',
Rock: '#cdc168',
Ghost: '#746dc4',
Dragon: '#1e70b8',
Dark: '#494355',
Steel: '#2b8d97',
Fairy: '#f8a1dc',
};
const BUTTON_STYLES = {
fontSize: '14px',
outline: 'none',
borderRadius: '100%',
height: '50px',
width: '50px',
marginBottom: '10px',
cursor: 'pointer',
border: '1px solid #ccc',
backgroundColor: '#f0f0f0',
transition: 'background-color 0.3s',
};
const IMAGE_STYLES = {
'.pokemon-image': {
display: 'inline-block',
margin: '-25px -5px -20px 0',
width: '60px',
height: '60px',
},
'.pokemon-type': {
display: 'inline-block',
margin: '-5px -2px 0px 2px',
width: '25px',
height: '25px',
},
'.pokemon-ball': {
display: 'inline-block',
margin: '-5px 0 0 2px',
width: '35px',
height: '35px',
},
'.type': {
fontWeight: 'bold',
},
};
const DEFAULT_CONFIG = {
showCopyButton: true,
showNamesButton: true,
showReloadButton: true,
};
let config = { ...DEFAULT_CONFIG };
function loadConfig() {
const savedConfig = GM_getValue('imageNamesConfig');
if (savedConfig) {
config = { ...DEFAULT_CONFIG, ...JSON.parse(savedConfig) };
}
}
function saveConfig() {
GM_setValue('imageNamesConfig', JSON.stringify(config));
}
function applyStyles() {
document.querySelectorAll('i').forEach((tag) => {
if (/<img|<span/.test(tag.textContent)) {
tag.style.whiteSpace = 'nowrap';
tag.innerHTML = tag.textContent;
}
});
Object.entries(IMAGE_STYLES).forEach(([selector, styles]) => {
document.querySelectorAll(selector).forEach((element) => {
Object.assign(element.style, styles);
});
});
Object.entries(TYPE_STYLE).forEach(([selector, color]) => {
Array.from(document.getElementsByClassName(selector)).forEach((element) => {
element.style.color = color;
});
});
}
function createButton(text, onClickFunction) {
const button = document.createElement('button');
Object.assign(button.style, BUTTON_STYLES);
button.textContent = text;
button.addEventListener('mouseover', () => { button.style.backgroundColor = '#e0e0e0' });
button.addEventListener('mouseout', () => { button.style.backgroundColor = '#f0f0f0' });
button.addEventListener('click', onClickFunction);
return button;
}
function setupButtons() {
const boxMenu = document.createElement('div');
Object.assign(boxMenu.style, {
position: 'fixed',
bottom: '100px',
right: '10px',
display: 'flex',
flexDirection: 'column',
});
const buttons = [
{ condition: 'showCopyButton', text: 'Copy', onClick: copyToClipboard },
{ condition: 'showNamesButton', text: 'Names', onClick: () => document.querySelector("button[onclick='showNS()']")?.click() },
{ condition: 'showReloadButton', text: 'Reload', onClick: () => document.querySelector("button[onclick='excute()']")?.click() },
{ condition: true, text: 'Config', onClick: createConfigMenu },
];
buttons.forEach(({ condition, text, onClick }) => {
if (config[condition] || condition === true) {
boxMenu.appendChild(createButton(text, onClick));
}
});
document.body.appendChild(boxMenu);
}
async function copyToClipboard(e) {
try {
const copyText = document.querySelector('#namewd')?.value || '';
await navigator.clipboard.writeText(copyText);
e.target.textContent = 'Copied!';
} catch (err) {
e.target.textContent = 'Error!';
} finally {
setTimeout(() => { e.target.textContent = 'Copy' }, 2000);
}
}
function createConfigMenu() {
const modal = document.createElement('div');
Object.assign(modal.style, {
position: 'fixed',
top: '0',
left: '0',
width: '100%',
height: '100%',
backgroundColor: 'rgba(0, 0, 0, 0.5)',
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
zIndex: '1000',
});
const menuContent = document.createElement('div');
Object.assign(menuContent.style, {
backgroundColor: 'white',
padding: '20px',
borderRadius: '10px',
maxWidth: '300px',
width: '90%',
});
const title = document.createElement('h2');
title.textContent = 'Configuration';
title.style.marginTop = '0';
menuContent.appendChild(title);
Object.keys(config).forEach((key) => {
const label = document.createElement('label');
label.style.display = 'block';
label.style.marginBottom = '10px';
const checkbox = document.createElement('input');
checkbox.type = 'checkbox';
checkbox.checked = config[key];
checkbox.id = key;
checkbox.style.appearance = 'auto';
checkbox.addEventListener('change', (e) => { config[key] = e.target.checked });
label.appendChild(checkbox);
label.appendChild(document.createTextNode(' ' + key.replace(/([A-Z])/g, ' $1').replace(/^./, (str) => str.toUpperCase())));
menuContent.appendChild(label);
});
const buttonContainer = document.createElement('div');
buttonContainer.style.display = 'flex';
buttonContainer.style.justifyContent = 'space-between';
buttonContainer.style.marginTop = '20px';
const saveButton = createButton('Save', () => {
saveConfig();
modal.remove();
location.reload();
});
saveButton.style.borderRadius = '5px';
saveButton.style.marginRight = '10px';
saveButton.style.flex = '1';
const cancelButton = createButton('Cancel', () => modal.remove());
cancelButton.style.borderRadius = '5px';
cancelButton.style.flex = '1';
buttonContainer.appendChild(saveButton);
buttonContainer.appendChild(cancelButton);
menuContent.appendChild(buttonContainer);
modal.appendChild(menuContent);
document.body.appendChild(modal);
}
function init() {
loadConfig();
applyStyles();
setupButtons();
const button = document.querySelector('[onclick="excute()"]');
if (button) {
button.addEventListener('click', applyStyles);
}
}
requestAnimationFrame(() => {
setTimeout(init, 2000);
});
})();