GGn Upload Blocker Manager

The "library" version of upload blocker. Import this with @require and use the APIs to standardize blocking uploads in GGn.

此脚本不应直接安装,它是一个供其他脚本使用的外部库。如果您需要使用该库,请在脚本元属性加入:// @require https://update.cn-greasyfork.org/scripts/533781/1578387/GGn%20Upload%20Blocker%20Manager.js

  1. // ==UserScript==
  2. // @name GGn Upload Blocker Manager
  3. // @namespace https://greasyfork.org/users/1395131
  4. // @version 1.1
  5. // @author SleepingGiant
  6. // @description The "library" version of upload blocker. Import this with @require and use the APIs to standardize blocking uploads in GGn.
  7. // @match https://gazellegames.net/*
  8. // @grant none
  9. // ==/UserScript==
  10. // @export UploadBlockerManager
  11.  
  12. (function (global) {
  13. 'use strict';
  14. const reasonListId = 'ggn-block-reasons';
  15.  
  16. class UploadBlockerManager {
  17. constructor(submitButton) {
  18. this.submitButton = submitButton;
  19. this.originalText = submitButton.value;
  20. this.reasonContainer = this._ensureReasonList();
  21. }
  22.  
  23. _ensureReasonList() {
  24. let ul = document.getElementById(reasonListId);
  25. if (!ul) {
  26. ul = document.createElement('ul');
  27. ul.id = reasonListId;
  28. ul.style.marginTop = '0.5em';
  29. ul.style.color = 'red';
  30. ul.style.listStyleType = 'none';
  31. this.submitButton.parentNode.insertBefore(ul, this.submitButton.nextSibling);
  32. }
  33. return ul;
  34. }
  35.  
  36. addReason(text) {
  37. if (!this._hasReason(text)) {
  38. const li = document.createElement('li');
  39. li.textContent = text;
  40. this.reasonContainer.appendChild(li);
  41. }
  42. this._updateButtonState();
  43. }
  44.  
  45. removeReason(text) {
  46. for (const li of Array.from(this.reasonContainer.children)) {
  47. if (li.textContent === text) {
  48. li.remove();
  49. break;
  50. }
  51. }
  52. this._updateButtonState();
  53. }
  54.  
  55. _hasReason(text) {
  56. return Array.from(this.reasonContainer.children)
  57. .some(li => li.textContent === text);
  58. }
  59.  
  60. _updateButtonState() {
  61. const hasBlockers = this.reasonContainer.children.length > 0;
  62. const override = document.querySelector('#upload-blocker-override')?.checked;
  63.  
  64. if (hasBlockers && !override) {
  65. this.submitButton.disabled = true;
  66. this.submitButton.style.opacity = '0.5';
  67. this.submitButton.style.pointerEvents = 'none';
  68. this.submitButton.value = 'Uploading Blocked';
  69. } else {
  70. this.submitButton.disabled = false;
  71. this.submitButton.style.opacity = '1';
  72. this.submitButton.style.pointerEvents = 'auto';
  73. this.submitButton.value = this.originalText;
  74. }
  75. }
  76.  
  77. attachOverrideCheckbox() {
  78. if (!document.getElementById('upload-blocker-override')) {
  79. const cb = document.createElement('input');
  80. cb.type = 'checkbox';
  81. cb.id = 'upload-blocker-override';
  82. cb.style.marginLeft = '0.5em';
  83. cb.addEventListener('change', () => this._updateButtonState());
  84.  
  85. const label = document.createElement('label');
  86. label.htmlFor = cb.id;
  87. label.textContent = ' Override blockers';
  88. label.style.marginLeft = '0.25em';
  89.  
  90. this.submitButton.parentNode.insertBefore(cb, this.submitButton.nextSibling);
  91. this.submitButton.parentNode.insertBefore(label, cb.nextSibling);
  92. }
  93. }
  94.  
  95. }
  96.  
  97. // Export into global so other scripts can import it
  98. global.UploadBlockerManager = UploadBlockerManager;
  99.  
  100. })(window);