IMVU HTML Description Injector V5.1

Adds button to inject HTML code into the description box on IMVU product edit page

  1. // ==UserScript==
  2. // @name IMVU HTML Description Injector V5.1
  3. // @namespace http://tampermonkey.net/
  4. // @version 5.1
  5. // @description Adds button to inject HTML code into the description box on IMVU product edit page
  6. // @author Shop Spikes / add spcckz @ discord for any issues/feature requests you have
  7. // @match https://www.imvu.com/creator/edit_product_html/*
  8. // @grant none
  9. // @license GNU GPLv3
  10. // ==/UserScript==
  11.  
  12. (function() {
  13. 'use strict';
  14.  
  15. let textColor = localStorage.getItem('chosenColor') || '#ffffff';
  16. let textShadow = localStorage.getItem('rememberShadow') === 'true' ? '2px 2px 4px rgba(0,0,0,0.8)' : 'none';
  17.  
  18. function toggleDropShadow() {
  19. textShadow = document.getElementById('dropShadowCheckbox').checked ? '2px 2px 4px rgba(0,0,0,0.8)' : 'none';
  20. injectHTMLCode();
  21. localStorage.setItem('rememberShadow', document.getElementById('dropShadowCheckbox').checked);
  22. }
  23.  
  24. function changeFontColor() {
  25. textColor = document.getElementById('fontColorPicker').value;
  26. injectHTMLCode();
  27. localStorage.setItem('chosenColor', textColor);
  28. }
  29.  
  30. function getUserIdFromLink() {
  31. const userIdMatch = document.querySelector('a.notranslate').getAttribute('href').match(/user=(\d+)/);
  32. return userIdMatch ? userIdMatch[1] : null;
  33. }
  34.  
  35. function injectHTMLCode() {
  36. const userId = getUserIdFromLink();
  37. const derivedFromNumber = window.location.href.match(/edit_product_html\/(\d+)/) ? window.location.href.match(/edit_product_html\/(\d+)/)[1] : '';
  38.  
  39. if (userId) {
  40. const userImages = document.getElementById('userImages').value.split('\n');
  41. const backgroundImage = localStorage.getItem('chosenImage') || '';
  42. const bannerCode = document.getElementById('bannerBox').value.trim();
  43. const footerTextColor = document.getElementById('fontColorPicker').value;
  44. const additionalHtml = document.getElementById('additionalHtml').value;
  45. const username = document.getElementById('usernameInput').value.trim(); // Added username input
  46.  
  47. // Added category buttons with dynamic username
  48. const categoryButtonsHTML = `
  49. <head>
  50. <meta charset="UTF-8">
  51. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  52. <title>Button Links</title>
  53. <style>
  54. body, html {
  55. margin: 0;
  56. padding: 0;
  57. height: 100%;
  58. }
  59.  
  60. .button-container {
  61. display: flex;
  62. justify-content: center;
  63. align-items: flex-start;
  64. min-height: 10px; /* Adjust minimum height to ensure full viewport coverage */
  65. gap: 25px; /* Add some space between columns */
  66. padding: 20px; /* Add padding as necessary */
  67. }
  68.  
  69. .column {
  70. display: flex;
  71. flex-direction: column;
  72. align-items: center;
  73. flex: 1; /* Ensure columns grow to fill container */
  74. }
  75.  
  76. .column h2 {
  77. margin-bottom: 20px;
  78. }
  79.  
  80. .styled-button {
  81. display: flex;
  82. align-items: center;
  83. justify-content: center;
  84. width: 150px; /* Fixed width for all buttons */
  85. padding: 10px 20px;
  86. font-size: 16px;
  87. color: #fff;
  88. background-color: #333;
  89. border: none;
  90. border-radius: 5px;
  91. text-decoration: none;
  92. margin: 10px 0;
  93. transition: background-color 0.3s;
  94. box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3); /* Add drop shadow */
  95. }
  96.  
  97. .styled-button:hover {
  98. background-color: #555;
  99. box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3); /* Add drop shadow */
  100. }
  101. </style>
  102. </head>
  103. <body>
  104. <div class="button-container">
  105. <div class="column">
  106. <h2>MALE</h2>
  107. <a href="https://www.imvu.com/shop/web_search.php?keywords=${username}&within=creator_name&page=1&cat=106-41-71&bucket=&tag=&sortorder=desc&quickfind=new&product_rating=-1&offset=27&narrow=&manufacturers_id=&derived_from=0&derivable=0&sort=id" class="styled-button" target="_blank">
  108. Accessories
  109. </a>
  110. <a href="https://www.imvu.com/shop/web_search.php?keywords=${username}&within=creator_name&page=1&cat=106-41-68&bucket=&tag=&sortorder=desc&quickfind=new&product_rating=-1&offset=27&narrow=&manufacturers_id=&derived_from=0&derivable=0&sort=id" class="styled-button" target="_blank">
  111. Skins
  112. </a>
  113. <a href="https://www.imvu.com/shop/web_search.php?keywords=${username}&within=creator_name&page=1&cat=106-41-91&bucket=&tag=&sortorder=desc&quickfind=new&product_rating=-1&offset=27&narrow=&manufacturers_id=&derived_from=0&derivable=0&sort=id" class="styled-button" target="_blank">
  114. Eyes
  115. </a>
  116. <a href="https://www.imvu.com/shop/web_search.php?keywords=${username}&within=creator_name&page=1&cat=106-41-67&bucket=&tag=&sortorder=desc&quickfind=new&product_rating=-1&offset=27&narrow=&manufacturers_id=&derived_from=0&derivable=0&sort=id" class="styled-button" target="_blank">
  117. Hair
  118. </a>
  119. <a href="https://www.imvu.com/shop/web_search.php?keywords=${username}&within=creator_name&page=1&cat=106-41-69&bucket=&tag=&sortorder=desc&quickfind=new&product_rating=-1&offset=27&narrow=&manufacturers_id=&derived_from=0&derivable=0&sort=id" class="styled-button" target="_blank">
  120. Tops
  121. </a>
  122. <a href="https://www.imvu.com/shop/web_search.php?keywords=${username}&within=creator_name&page=1&cat=106-41-70&bucket=&tag=&sortorder=desc&quickfind=new&product_rating=-1&offset=27&narrow=&manufacturers_id=&derived_from=0&derivable=0&sort=id" class="styled-button" target="_blank">
  123. Pants
  124. </a>
  125. <a href="https://www.imvu.com/shop/web_search.php?keywords=${username}&within=creator_name&page=1&cat=106-41-102&bucket=&tag=&sortorder=desc&quickfind=new&product_rating=-1&offset=27&narrow=&manufacturers_id=&derived_from=0&derivable=0&sort=id" class="styled-button" target="_blank">
  126. Shoes
  127. </a>
  128. </div>
  129. <div class="column">
  130. <h2>FEMALE</h2>
  131. <a href="https://www.imvu.com/shop/web_search.php?keywords=${username}&within=creator_name&page=1&cat=106-40-153&bucket=&tag=&sortorder=desc&quickfind=new&product_rating=-1&offset=27&narrow=&manufacturers_id=&derived_from=0&derivable=0&sort=id" class="styled-button" target="_blank">
  132. Accessories
  133. </a>
  134. <a href="https://www.imvu.com/shop/web_search.php?keywords=${username}&within=creator_name&page=1&cat=106-40-76&bucket=&tag=&sortorder=desc&quickfind=new&product_rating=-1&offset=27&narrow=&manufacturers_id=&derived_from=0&derivable=0&sort=id" class="styled-button" target="_blank">
  135. Skins
  136. </a>
  137. <a href="https://www.imvu.com/shop/web_search.php?keywords=${username}&within=creator_name&page=1&cat=106-40-89&bucket=&tag=&sortorder=desc&quickfind=new&product_rating=-1&offset=27&narrow=&manufacturers_id=&derived_from=0&derivable=0&sort=id" class="styled-button" target="_blank">
  138. Eyes
  139. </a>
  140. <a href="https://www.imvu.com/shop/web_search.php?keywords=${username}&within=creator_name&page=1&cat=106-40-75&bucket=&tag=&sortorder=desc&quickfind=new&product_rating=-1&offset=27&narrow=&manufacturers_id=&derived_from=0&derivable=0&sort=id" class="styled-button" target="_blank">
  141. Hair
  142. </a>
  143. <a href="https://www.imvu.com/shop/web_search.php?keywords=${username}&within=creator_name&page=1&cat=106-40-128&bucket=&tag=&sortorder=desc&quickfind=new&product_rating=-1&offset=27&narrow=&manufacturers_id=&derived_from=0&derivable=0&sort=id" class="styled-button" target="_blank">
  144. Tops
  145. </a>
  146. <a href="https://www.imvu.com/shop/web_search.php?keywords=${username}&within=creator_name&page=1&cat=106-40-78&bucket=&tag=&sortorder=desc&quickfind=new&product_rating=-1&offset=27&narrow=&manufacturers_id=&derived_from=0&derivable=0&sort=id" class="styled-button" target="_blank">
  147. Pants
  148. </a>
  149. <a href="https://www.imvu.com/shop/web_search.php?keywords=${username}&within=creator_name&page=1&cat=106-40-101&bucket=&tag=&sortorder=desc&quickfind=new&product_rating=-1&offset=27&narrow=&manufacturers_id=&derived_from=0&derivable=0&sort=id" class="styled-button" target="_blank">
  150. Shoes
  151. </a>
  152. </div>
  153. </div>
  154. `;
  155.  
  156. const dropShadowImageUrl = 'https://userimages-akm.imvu.com/userdata/38/39/59/89/userpics/Snap_j4ogbJlGKQ1012285644.png';
  157.  
  158. const imageHTML = userImages.map(image => `<center><div style="position: relative; display: inline-block;"><img src="${image.trim()}" style="position: relative; z-index: 1;"><img src="${dropShadowImageUrl}" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; z-index: 0;"></div></center>`).join('');
  159.  
  160. const gaf210Code = `<center><!-- Product Marquee made @ gaf210.gafcodes.com --><style>.imvustylez_products_marquee{margin:0 auto}.imvustylez_products_marquee [id$="_panel_header"]{display:none!important;font-size:1px}.imvustylez_products_marquee [id$="_panel_body"]{line-height:1px}.imvustylez_products_marquee .productbox,.imvustylez_products_marquee .productbox img{width:100px!important;height:80px!important}</style><marquee class='imvustylez_products_marquee' width='500' height='100' scrollamount='12' direction='left' behavior='scroll' onmouseover="this.stop()" onmouseout="this.start()"><div style='width:2675px'><script src="https://gaf210.gafcodes.com/newprodsbanner/filtered_dev_panel.js.php?dev_id=${userId}&pn=new&q=25"></script></div></marquee></center>`;
  161.  
  162. const iframeCode = `<center><a href="https://www.imvu.com/shop/web_search.php?derived_from=${derivedFromNumber}" target="_blank">CLICK HERE to open derivations of this item in a new tab</a><iframe name="Derived Products" src='https://www.imvu.com/shop/web_search.php?derived_from=${derivedFromNumber}?keywords=Punishment&within=creator_name&sortorder=desc&quickfind=new&sort=id#products' width='775' height='105' scrolling="no" style="margin: 0; padding: 0;"></iframe></center>`;
  163.  
  164. const injectedHtmlCode = `
  165. <center>${gaf210Code}${iframeCode}${categoryButtonsHTML}
  166. <style>
  167. html, body {
  168. }
  169. body {
  170. background-image: url('${backgroundImage}');
  171. background-repeat: no-repeat;
  172. background-attachment: fixed;
  173. background-size: cover;
  174. color: ${textColor};
  175. text-shadow: ${textShadow};
  176. padding: 0;
  177. margin: 0;
  178. overflow: visible;
  179. display: flex;
  180. flex-direction: column;
  181. justify-content: space-between;
  182.  
  183. .body-content {
  184. overflow-y: visible; /* Enable scrolling for content that exceeds viewport height */
  185. }
  186.  
  187. .autoHtmlFooter {
  188. font-size: 16px;
  189. color: ${footerTextColor};
  190. margin: 0;
  191. padding: 0px;
  192. overflow-y: visible;
  193. text-align: right;
  194. }
  195. .preview-container {
  196. flex: 1; /* This makes the preview container grow to fill available space */
  197. display: flex;
  198. flex-direction: column;
  199. align-items: center;
  200. justify-content: center;
  201. padding: 20px;
  202. overflow-y: visible;
  203. }
  204. </style>
  205. <div class="preview-container">${imageHTML}</div>
  206. ${bannerCode ? bannerCode : ''}
  207. <div class="autoHtmlFooter">EZ-AutoHTML by Spikes, spcckz@discord</div>
  208. ${additionalHtml}
  209. </center>`;
  210.  
  211.  
  212. const descriptionTextarea = document.querySelector('#description');
  213. if (descriptionTextarea) {
  214. descriptionTextarea.value = injectedHtmlCode;
  215. }
  216. }
  217. }
  218.  
  219. function loadSavedValues() {
  220. document.getElementById('userImages').value = localStorage.getItem('userImages') || '';
  221. document.getElementById('bannerBox').value = localStorage.getItem('bannerCode') || '';
  222. document.getElementById('backgroundImageInput').value = localStorage.getItem('chosenImage') || '';
  223. document.getElementById('additionalHtml').value = localStorage.getItem('additionalHtml') || '';
  224. document.getElementById('usernameInput').value = localStorage.getItem('username') || '';
  225. }
  226.  
  227. function saveInputValues() {
  228. localStorage.setItem('userImages', document.getElementById('userImages').value);
  229. localStorage.setItem('bannerCode', document.getElementById('bannerBox').value);
  230. localStorage.setItem('chosenImage', document.getElementById('backgroundImageInput').value);
  231. localStorage.setItem('additionalHtml', document.getElementById('additionalHtml').value);
  232. localStorage.setItem('username', document.getElementById('usernameInput').value.trim());
  233. }
  234.  
  235. function addButtonAndInput() {
  236. const container = document.createElement('div');
  237. container.style.cssText = 'position:absolute;top:235px;right:200px;z-index:9999;font-size:16px;display:flex;flex-direction:column;align-items:center';
  238.  
  239. const input = document.createElement('textarea');
  240. input.id = 'userImages';
  241. input.rows = 6;
  242. input.placeholder = 'Enter preview image URLs here. To add more, press Shift+Enter after the first URL.';
  243.  
  244. const bannerLabel = document.createElement('label');
  245. bannerLabel.htmlFor = 'bannerBox';
  246. bannerLabel.textContent = 'Banner HTML Code';
  247.  
  248. const bannerBox = document.createElement('textarea');
  249. bannerBox.id = 'bannerBox';
  250. bannerBox.rows = 6;
  251. bannerBox.placeholder = 'Enter banner HTML code here.';
  252. bannerBox.value = localStorage.getItem('bannerCode') || '';
  253.  
  254. const backgroundImageInput = document.createElement('input');
  255. backgroundImageInput.type = 'text';
  256. backgroundImageInput.id = 'backgroundImageInput';
  257. backgroundImageInput.placeholder = 'Enter background image URL';
  258. backgroundImageInput.value = localStorage.getItem('chosenImage') || '';
  259.  
  260. const bgImgLabel = document.createElement('label');
  261. bgImgLabel.htmlFor = 'backgroundImageInput';
  262. bgImgLabel.textContent = 'Background Image URL';
  263.  
  264. const button = document.createElement('button');
  265. button.textContent = 'Inject HTML Code';
  266. button.addEventListener('click', injectHTMLCode);
  267.  
  268. const shadowCheckbox = document.createElement('input');
  269. shadowCheckbox.type = 'checkbox';
  270. shadowCheckbox.id = 'dropShadowCheckbox';
  271. shadowCheckbox.checked = textShadow !== 'none';
  272. shadowCheckbox.addEventListener('change', toggleDropShadow);
  273.  
  274. const colorPicker = document.createElement('input');
  275. colorPicker.type = 'color';
  276. colorPicker.id = 'fontColorPicker';
  277. colorPicker.value = localStorage.getItem('chosenColor') || textColor;
  278. colorPicker.addEventListener('input', changeFontColor);
  279.  
  280. const colorLabel = document.createElement('label');
  281. colorLabel.htmlFor = 'fontColorPicker';
  282. colorLabel.textContent = 'Font Color';
  283.  
  284. const shadowLabel = document.createElement('label');
  285. shadowLabel.htmlFor = 'dropShadowCheckbox';
  286. shadowLabel.textContent = 'Font Drop Shadow';
  287.  
  288. const additionalHtmlLabel = document.createElement('label');
  289. additionalHtmlLabel.htmlFor = 'additionalHtml';
  290. additionalHtmlLabel.textContent = 'Additional HTML';
  291.  
  292. const additionalHtml = document.createElement('textarea');
  293. additionalHtml.id = 'additionalHtml';
  294. additionalHtml.rows = 6;
  295. additionalHtml.placeholder = 'Enter additional HTML code here.';
  296. additionalHtml.value = localStorage.getItem('additionalHtml') || '';
  297.  
  298. const usernameInput = document.createElement('input'); // Added username input
  299. usernameInput.type = 'text';
  300. usernameInput.id = 'usernameInput';
  301. usernameInput.placeholder = 'Enter your username';
  302. usernameInput.value = localStorage.getItem('username') || '';
  303. usernameInput.addEventListener('input', () => {
  304. localStorage.setItem('username', usernameInput.value.trim());
  305. });
  306.  
  307. container.appendChild(usernameInput); // Moved username input above the inject button
  308. container.appendChild(button);
  309. container.appendChild(input);
  310. container.appendChild(bgImgLabel);
  311. container.appendChild(backgroundImageInput);
  312. container.appendChild(colorLabel);
  313. container.appendChild(colorPicker);
  314. container.appendChild(document.createElement('br'));
  315. container.appendChild(shadowLabel);
  316. container.appendChild(shadowCheckbox);
  317. container.appendChild(document.createElement('br'));
  318. container.appendChild(bannerLabel);
  319. container.appendChild(bannerBox);
  320. container.appendChild(document.createElement('br'));
  321. container.appendChild(additionalHtmlLabel);
  322. container.appendChild(additionalHtml);
  323.  
  324. document.body.appendChild(container);
  325.  
  326. loadSavedValues(); // Load saved input values on page load
  327.  
  328. window.addEventListener('beforeunload', saveInputValues); // Save input values before leaving the page
  329. }
  330.  
  331. window.addEventListener('load', addButtonAndInput);
  332.  
  333. })();