Imgbox Tweaker

Adds custom formatted links, working Copy to clipboard buttons, menu pre-select for 1-click uploading, links centering.

  1. // ==UserScript==
  2. //
  3. // @name Imgbox Tweaker
  4. // @version 2.1
  5. // @namespace https://github.com/Purfview/Imgbox-Tweaker
  6. // @description Adds custom formatted links, working Copy to clipboard buttons, menu pre-select for 1-click uploading, links centering.
  7. // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABABAMAAABYR2ztAAAAKlBMVEUAAQH9cgMYEAs2Hg1VLRB6PhCdTRG+WQrTZRSyWhrfZwbnbQ/ucxb+eRkNjKAWAAADwElEQVRIx72TSY8SQRTHn90NqLcn0ECrSdm0GOXS0IhLPLTCjFtMugUxGk3AGYjLBVwYozFR1IneHHG9ycHowYtrYryo0cSr28VP46sqG3GcmZPxl3R3Vde/6i31HvxnlLFytzxWZfOtjw9QkKjMvf0gDnkx13oDhyyfefi3ma34m1gEJ2evr8G7mFjfOju9b2qqa/rJ0iw/1EGMjqgLW+lWB1OeZf9pYIWJxOOJ4qNzIhYXnNF17XMvjILrKPFAc0cEuRSoTadQ3r3CvoSEsFYaCRF7yl4xqsIGsT5p07H2bxdXuuuSwYkNHqf4W4eA1XH1KRqtKXFK5ixO870MXg4tXGovRY7RZHxaZqZZ7LqwNUhnCD0/dRSJJAjCPzq4Ig+RwEZYh6QNRX6P0qVPGcQPCqjLgiCj6hH6rCXFGWY51iC25GqVWQAJkPg3yDADZYbHv5tbusVdASgHWfBAOcFz9w51x0JceRO2TwrnXOljkoE6/ibFwCpToJuulyCDCV54kQdCsHQ54ybIyBBT2dinqXZRzLK6tCTeTalgist/HZGCOB+bYyp9VTEuFb3TYs9zGWWMj48bHf2XQEVE+hLy7T+jl70E8Ts5rIs/iD3gLrWEoNMmm/vZ+n02JTUpG2gfExXVDQSqvpqujgSLDVmWZlpkaSoQRFB/At1bDLIkcGytFtLDVROgJitkGW+KpIaDj5AjQaFgWzXjddMDOCcFUcghxhal7rfMDjeRvYstNJ64wWX4MViMqGfr6ngBKavK4CDWZG3kZU/E6RR9vLntfiXM41fOb8aJAV6mpSvDVKsuPH29F3wUmdSO2TtLfNCTXSPrYowBzMR8Vx4rKkT15KjjBne4OhrBm78F4boc7uiLT3qaiuHaR1HxkiztlDYUvqOITK7l4vTmvXk0OGwmL/7gw6oNKtuKwvnFnvoNJGyt6/Besqhx7xx9u6MCRCEDkYvD1rInSLAewClsM7kUKtB04DCDIa+AHNRkh1N4J0vK5YpCloY0bFKvivPcKtsUtwmL+94Sb0SQW2ZR2F+1WEZt++oXgMMbvQMwQhjTdD4LvT3sxPa4Lii3m9oNGMWPpoVLO/N9iwbrltuH4A8i6EyMTC8cWfoV/qSB6ELolJyse6+ttGcJQoht2MKzvQ1Wo9vpwWw2Ypuek6DpsDW5S4e/2fIeVmHcisShkcD6HALFhnVonN0Vh3u1PszNGkSDBKYJ8xBGxEEU5l2HEBcsg/lRyUTjBizAAI37bCGBj0YeFiKHy2FBtOlJ+Nf8BCbnsb61BX21AAAAAElFTkSuQmCC
  8. // @license MIT
  9. //
  10. // @homepage https://github.com/Purfview/Imgbox-Tweaker
  11. // @supportURL https://github.com/Purfview/Imgbox-Tweaker/issues
  12. //
  13. // @compatible firefox
  14. // @compatible opera
  15. // @compatible chrome
  16. // @compatible safari
  17. // @compatible edge
  18. //
  19. // @require https://code.jquery.com/jquery-3.5.1.min.js
  20. // @require https://cdn.jsdelivr.net/gh/sizzlemctwizzle/GM_config@43fd0fe4de1166f343883511e53546e87840aeaf/gm_config.js
  21. // @require https://greasemonkey.github.io/gm4-polyfill/gm4-polyfill.js
  22. //
  23. // @include https://imgbox.com/
  24. // @include https://imgbox.com/upload/edit/*
  25. // @include https://imgbox.com/gallery/edit/*
  26. //
  27. // @grant GM_registerMenuCommand
  28. // @grant GM.registerMenuCommand
  29. //
  30. // @run-at document-start
  31. //
  32. // ==/UserScript==
  33. /*
  34. //==============================================================================
  35. // Version History:
  36. //==============================================================================
  37.  
  38. 2.1 - New feature: Works when logged in.
  39.  
  40. 2.0 - Major script rewrite.
  41. Namespace change.
  42. New feature: Settings menu.
  43. New feature: Pre-select menu for 1-click uploading.
  44. New feature: After upload auto-load into 'edit' page to get Copy buttons.
  45. New feature: All Copy buttons are working.
  46. New feature: Fully working centering option.
  47. New feature: Support for classic Greasemonkey.
  48.  
  49. 1.1 - Fixed: The script was breaking the upload page.
  50.  
  51. 1.0 - New feature: Working Copy buttons.
  52. Added an icon for the script.
  53.  
  54. 0.0.4 - Disabled centering for BBCode boxes (can be enabled with a variable below).
  55.  
  56. 0.0.3 - Fixed: the script wasn't working with the current imgbox.
  57.  
  58. 0.0.2 - Last version from SMz before his disappearance.
  59.  
  60. */
  61. //==============================================================================
  62.  
  63.  
  64. /**
  65. * Sets array elements into placeholders of a pattern.
  66. * @param {string} Base pattern. Placeholders as {%i} for the i-th replacement
  67. * array.
  68. * @param {...string[]} Replacement sources for the pattern. The first array
  69. * will set the returned array length.
  70. * @return {string[]} Replaced pattern elements.
  71. */
  72. function createPatternedArray() {
  73. var pattern = arguments[0];
  74. var modArray = [];
  75. for (var i = 0; i < arguments[1].length; i++) {
  76. modArray[i] = pattern;
  77. }
  78. for (var j = 1; j < arguments.length; j++) {
  79. for (var k = 0; k < modArray.length; k++) {
  80. var replacement = arguments[j][k] || '';
  81. modArray[k] = modArray[k].split('{%' + j + '}').join(replacement);
  82. }
  83. }
  84. return modArray;
  85. }
  86.  
  87.  
  88. function copyInfoToClipboard(collect) {
  89. document.body.insertBefore(collect,document.body.firstChild);
  90. collect.focus();
  91. collect.select();
  92. const x = document.execCommand('copy');
  93. document.body.removeChild(collect);
  94. }
  95.  
  96.  
  97. function startObserver() {
  98. const obscfg = { attributes: true };
  99. const obs = new MutationObserver(preselectMenus);
  100. obs.observe($('#upload-form')[0], obscfg);
  101. }
  102.  
  103.  
  104. function preselectMenus(mutation, observer) {
  105. observer.disconnect();
  106. console.log("Imgbox Tweaker: '#upload-form' mutation detected. Starting preselectMenus().");
  107.  
  108. // Content preselect
  109. let content_index;
  110. const content_val = GM_config.get('menu_content');
  111. if (content_val === 'Family Safe Content' ) { content_index = 1;
  112. } else if (content_val === 'Adult Content') { content_index = 2;
  113. } else { content_index = 0;
  114. }
  115. $('#dropdown-content-type').find('option[selected="selected"]').removeAttr("selected");
  116. $('#dropdown-content-type option:eq('+content_index+')').attr('selected', "selected");
  117. $('button[data-id="dropdown-content-type"]>.filter-option').text(content_val);
  118. $('.dropdown-menu.inner.selectpicker:eq(0)').find('li').removeAttr('class');
  119. $('.dropdown-menu.inner.selectpicker:eq(0)').find('li:eq('+content_index+')').addClass("selected");
  120.  
  121. // Thumbnail preselect
  122. let thumb_index;
  123. const thumb_val = GM_config.get('menu_thumb');
  124. if (thumb_val.match('100x100 pixel \\(square\\)' )) { thumb_index = 0;
  125. } else if (thumb_val.match('150x150 pixel \\(square\\)' )) { thumb_index = 1;
  126. } else if (thumb_val.match('200x200 pixel \\(square\\)' )) { thumb_index = 2;
  127. } else if (thumb_val.match('250x250 pixel \\(square\\)' )) { thumb_index = 3;
  128. } else if (thumb_val.match('300x300 pixel \\(square\\)' )) { thumb_index = 4;
  129. } else if (thumb_val.match('350x350 pixel \\(square\\)' )) { thumb_index = 5;
  130. } else if (thumb_val.match('500x500 pixel \\(square\\)' )) { thumb_index = 6;
  131. } else if (thumb_val.match('800x800 pixel \\(square\\)' )) { thumb_index = 7;
  132. } else if (thumb_val.match('100x100 pixel \\(resized\\)')) { thumb_index = 8;
  133. } else if (thumb_val.match('150x150 pixel \\(resized\\)')) { thumb_index = 9;
  134. } else if (thumb_val.match('200x200 pixel \\(resized\\)')) { thumb_index = 10;
  135. } else if (thumb_val.match('250x250 pixel \\(resized\\)')) { thumb_index = 11;
  136. } else if (thumb_val.match('300x300 pixel \\(resized\\)')) { thumb_index = 12;
  137. } else if (thumb_val.match('350x350 pixel \\(resized\\)')) { thumb_index = 13;
  138. } else if (thumb_val.match('500x500 pixel \\(resized\\)')) { thumb_index = 14;
  139. } else if (thumb_val.match('800x800 pixel \\(resized\\)')) { thumb_index = 15;
  140. }
  141. $('#thumbnail-option').find('option[selected="selected"]').removeAttr("selected");
  142. $('#thumbnail-option option:eq('+thumb_index+')').attr('selected', "selected");
  143. $('button[data-id="thumbnail-option"]>.filter-option').text(thumb_val);
  144. $('.dropdown-menu.inner.selectpicker:eq(1)').find('li').removeAttr('class');
  145. $('.dropdown-menu.inner.selectpicker:eq(1)').find('li:eq('+thumb_index+')').addClass("selected");
  146.  
  147. // Comments preselect
  148. let comment_index;
  149. const comment_val = GM_config.get('menu_comment');
  150. if (comment_val === 'Enable Comments') { comment_index = 0;
  151. } else { comment_index = 1;
  152. }
  153. $('#comments-option').find('option[selected="selected"]').removeAttr("selected");
  154. $('#comments-option option:eq('+comment_index+')').attr('selected', "selected");
  155. $('button[data-id="comments-option"]>.filter-option').text(comment_val);
  156. $('.dropdown-menu.inner.selectpicker:eq(2)').find('li').removeAttr('class');
  157. $('.dropdown-menu.inner.selectpicker:eq(2)').find('li:eq('+comment_index+')').addClass("selected");
  158.  
  159.  
  160. // Check if logged in [Gallery preselect is not supported there]
  161. if ($('.icon-comments').length) {
  162. console.log("Imgbox Tweaker: Login detected. Skiping 'Gallery preselect'.");
  163. return;
  164. }
  165.  
  166. // Gallery preselect
  167. let gallery_index;
  168. const gallery_val = GM_config.get('menu_gallery');
  169. if (gallery_val === 'Create a New Gallery') { gallery_index = 0;
  170. } else { gallery_index = 1;
  171. }
  172. $('#gallery-option').find('option[selected="selected"]').removeAttr("selected");
  173. $('#gallery-option option:eq('+gallery_index+')').attr('selected', "selected");
  174. $('button[data-id="gallery-option"]>.filter-option').text(gallery_val);
  175. $('.dropdown-menu.inner.selectpicker:eq(3)').find('li').removeAttr('class');
  176. $('.dropdown-menu.inner.selectpicker:eq(3)').find('li:eq('+gallery_index+')').addClass("selected");
  177. if (gallery_index === 1) {$('.new-gallery-title-input-container').addClass("hidden");}
  178. }
  179.  
  180.  
  181. function startImboxTweaker() {
  182. // Upload menu-select page
  183. if (GM_config.get('preselect_menu')) {
  184. if ($('#upload-form').length === 1) {
  185. console.log("Imgbox Tweaker: '#upload-form' detected. Starting MutationObserver.");
  186. startObserver();
  187. }
  188. }
  189.  
  190. // Upload result page
  191. if ($('#codes-full').length === 1) {
  192.  
  193. // Check if logged in [there is no Edit page and no Copy butons]
  194. let not_login = true;
  195. if ($('.icon-comments').length) {
  196. not_login = false;
  197. }
  198.  
  199. // Go to "upload edit" page to see Copy buttons
  200. if (!Boolean(location.href.match('\\/edit\\/')) && not_login) {
  201. console.log("Imgbox Tweaker: Restarting into 'upload edit' page.");
  202. const edithref = $('div.text-right a').text();
  203. window.location.replace(edithref +'?#');
  204. return;
  205. }
  206. console.log("Imgbox Tweaker: Upload result page detected. Starting tweaks.");
  207.  
  208. // Display all available outputs
  209. $('#codes-full').show().css('visibility', 'visible')
  210. .insertBefore('#codes-thumb');
  211. $('#codes-thumb').show().css('visibility', 'visible');
  212.  
  213. // Extract direct links to full images and thumbs
  214. var links = [];
  215. $($('#code-html-full').text()).find('img').each(function() {
  216. links.push($(this).attr('src'));
  217. });
  218.  
  219. var thumbs = [];
  220. $($('#code-html-thumb').text()).find('img').each(function() {
  221. thumbs.push($(this).attr('src'));
  222. });
  223.  
  224. // Modify the existing outputs and titles, display all options
  225. $('#code-link-full')
  226. .text(links.join('\n'))
  227. .prev('div').children('span').text('Full size plain');
  228.  
  229. if(GM_config.get('centered_links')){
  230. $('#code-html-full')
  231. .text('<center>' +createPatternedArray('<img src="{%1}">', links).join('\n\n') +'</center>')
  232. .prev('div').children('span').text('Full size HTML');
  233. } else {
  234. $('#code-html-full')
  235. .text(createPatternedArray('<img src="{%1}">', links).join('\n\n'))
  236. .prev('div').children('span').text('Full size HTML');
  237. }
  238.  
  239. if(GM_config.get('centered_links')){
  240. $('#code-bb-full')
  241. .text('[center]' +createPatternedArray('[img]{%1}[/img]', links).join('\n\n') +'[/center]')
  242. .prev('div').children('span').text('Full size BBCode');
  243. } else {
  244. $('#code-bb-full')
  245. .text(createPatternedArray('[img]{%1}[/img]', links).join('\n\n'))
  246. .prev('div').children('span').text('Full size BBCode');
  247. }
  248.  
  249. $('#code-link-thumb')
  250. .text(thumbs.join('\n'))
  251. .prev('div').children('span').text('Thumbs plain');
  252.  
  253. if(GM_config.get('centered_links')){
  254. $('#code-html-thumb')
  255. .text('<center>' +createPatternedArray('<a href="{%1}" target="imgbox-full-size"><img src="{%2}"></a>', links, thumbs).join('\n\n') +'</center>')
  256. .prev('div').children('span').text('Linked thumbs HTML');
  257. } else {
  258. $('#code-html-thumb')
  259. .text(createPatternedArray('<a href="{%1}" target="imgbox-full-size"><img src="{%2}"></a>', links, thumbs).join('\n\n'))
  260. .prev('div').children('span').text('Linked thumbs HTML');
  261. }
  262.  
  263. if(GM_config.get('centered_links')){
  264. $('#code-bb-thumb')
  265. .text('[center]' +createPatternedArray('[url={%1}][img]{%2}[/img][/url]', links, thumbs).join('\n\n') +'[/center]')
  266. .prev('div').children('span').text('Linked thumbs BBCode');
  267. } else {
  268. $('#code-bb-thumb')
  269. .text(createPatternedArray('[url={%1}][img]{%2}[/img][/url]', links, thumbs).join('\n\n'))
  270. .prev('div').children('span').text('Linked thumbs BBCode');
  271. }
  272.  
  273. // Fix Copy to clipboard buttons
  274. let buttons = $('.clipboard-button');
  275. if (buttons.length > 2 && not_login) {
  276. buttons.each(function() {
  277. const elem = $(this);
  278. let collect_id, collect_txt;
  279. if (elem.attr("data-clipboard-text")) {
  280. collect_txt = elem.attr("data-clipboard-text")
  281. } else {
  282. collect_id = elem.attr("data-clipboard-target");
  283. collect_txt = $('#' +collect_id).text();
  284. }
  285. let collect = document.createElement("textarea");
  286. collect.innerHTML+=collect_txt;
  287. elem.click(function() {
  288. copyInfoToClipboard(collect);
  289. });
  290. });
  291. }
  292. }
  293. }
  294.  
  295. //==============================================================================
  296. // Settings Menu (GM_config)
  297. //==============================================================================
  298.  
  299. var config_fields = {
  300. 'aftertitle': {
  301. 'section': ' ',
  302. 'label': ' &nbsp',
  303. 'type': 'hidden'
  304. },
  305. 'centered_links': {
  306. 'type': 'checkbox',
  307. 'label': 'Enable centering on links?',
  308. 'default': false
  309. },
  310. 'preselect_menu': {
  311. 'type': 'checkbox',
  312. 'label': 'Enable the pre-select menu feature?',
  313. 'default': true
  314. },
  315. 'menu_content': {
  316. 'section': 'Pre-select menu:',
  317. 'type': 'select',
  318. 'options': ['SELECT CONTENT TYPE', 'Family Safe Content', 'Adult Content'],
  319. 'default': 'Family Safe Content'
  320. },
  321. 'menu_thumb': {
  322. 'type': 'select',
  323. 'options': ['100x100 pixel (square)', '150x150 pixel (square)', '200x200 pixel (square)', '250x250 pixel (square)', '300x300 pixel (square)', '350x350 pixel (square)', '500x500 pixel (square)', '800x800 pixel (square)', '100x100 pixel (resized)', '150x150 pixel (resized)', '200x200 pixel (resized)', '250x250 pixel (resized)', '300x300 pixel (resized)', '350x350 pixel (resized)', '500x500 pixel (resized)', '800x800 pixel (resized)'],
  324. 'default': '100x100 pixel (resized)'
  325. },
  326. 'menu_comment': {
  327. 'type': 'select',
  328. 'options': ['Enable Comments', 'Disable Comments'],
  329. 'default': 'Disable Comments'
  330. },
  331. 'menu_gallery': {
  332. 'type': 'select',
  333. 'options': ['Create a New Gallery', 'Do Not Create a Gallery'],
  334. 'default': 'Do Not Create a Gallery'
  335. },
  336. };
  337.  
  338. //==============================================================================
  339. // Initialize and register GM_config
  340. //==============================================================================
  341.  
  342. GM_config.init({
  343. 'id': 'imgbox_tweaker',
  344. 'title': 'Imgbox Tweaker Settings',
  345. 'fields': config_fields,
  346. 'css': `#imgbox_tweaker_section_header_1 { \
  347. background: #00ab00 !important; \
  348. color: black !important; \
  349. font-weight: bold !important; \
  350. border: 0px !important; \
  351. padding-left: 0px !important; \
  352. text-align: middle !important;}\
  353. .field_label { \
  354. display: flex !important; \
  355. align-items: center !important; \
  356. font-weight: normal !important;}\
  357. .config_var { \
  358. margin-top: 2px !important; \
  359. margin-bottom: 2px !important; \
  360. display: flex !important; \
  361. align-items: center !important;}\
  362. #imgbox_tweaker_aftertitle_var { \
  363. margin-top: 0px !important; \
  364. margin-bottom: 0px !important;}\
  365. input { \
  366. margin-top: 0px !important; \
  367. margin-bottom: 0px !important;}\
  368. .grey_link { \
  369. margin-left: 4px !important;}\
  370. #imgbox_tweaker_section_header_0 { \
  371. font-weight: bold !important; \
  372. border: 0px !important; \
  373. margin-top: 0px !important; \
  374. background: #bfbfbf !important;}\
  375. #imgbox_tweaker_header { \
  376. background: black !important; \
  377. color: white !important;}\
  378. #imgbox_tweaker_section_0 { \
  379. margin-top: 0px !important;}`,
  380. 'events':
  381. {
  382. 'open': function() {
  383. // Iframe position.
  384. this.frame.style.top = '50px';
  385. this.frame.style.left = 'auto';
  386. this.frame.style.right = '150px';
  387. this.frame.style.height = '50%';
  388. this.frame.style.width = '450px';
  389.  
  390. $('#imgbox_tweaker').contents().find('input#imgbox_tweaker_field_ignore_list').attr('size', '47');
  391.  
  392. const modVersion = 'Imgbox Tweaker v' + GM.info.script.version;
  393. const modUrl = 'https://greasyfork.org/en/scripts/454582-imgbox-tweaker';
  394. $('#imgbox_tweaker').contents().find('#imgbox_tweaker_section_header_0').append($('<a href="'+modUrl+'" target ="_blank">'+modVersion+'</a>'));
  395. $('#imgbox_tweaker').contents().find('#imgbox_tweaker_section_header_0').find('a').css({
  396. 'text-decoration': 'none',
  397. 'color': '#cb0000'
  398. });
  399. },
  400.  
  401. 'close': function() {
  402. location.reload();
  403. }
  404. }
  405. });
  406.  
  407. GM.registerMenuCommand('Imgbox Tweaker Settings', function() {GM_config.open();});
  408.  
  409. window.addEventListener('DOMContentLoaded', startImboxTweaker);