Bundle Stars Keys Retrieve

Retrieve keys from Bundle Stars

当前为 2017-04-24 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Bundle Stars Keys Retrieve
  3. // @namespace http://tampermonkey.net/
  4. // @version 1.1.2
  5. // @description Retrieve keys from Bundle Stars
  6. // @icon https://cdn.bundlestars.com/production/brand/apple-touch-icon-180x180.png
  7. // @author Bisumaruko
  8. // @include http*://*bundlestars.com/*
  9. // @grant none
  10. // ==/UserScript==
  11.  
  12. (function() {
  13. 'use strict';
  14.  
  15. var $ = selector => document.querySelector(selector),
  16. $$ = selector => Array.from(document.querySelectorAll(selector));
  17.  
  18. function getAnchor() {
  19. var anchor = $('h2');
  20.  
  21. return anchor && anchor.textContent.trim() === 'Order Keys' ? anchor : null;
  22. }
  23.  
  24. function setup() {
  25. var anchor = getAnchor();
  26.  
  27. if (!anchor) return;
  28. var BSRetrive = document.createElement('div'),
  29. BSTextarea = document.createElement('textarea'),
  30. BSBtnContainer = document.createElement('div'),
  31. BSBtnReveal = document.createElement('button'),
  32. BSBtnRetrieve = document.createElement('button'),
  33. BSBtnCopy = document.createElement('button'),
  34. BSBtnReset = document.createElement('button'),
  35. BSCheckTitle = document.createElement('label'),
  36. BSCheckJoin = document.createElement('label'),
  37. style = document.createElement('style');
  38. BSRetrive.classList.add('BSRetrive');
  39. BSTextarea.classList.add('BSTextarea');
  40. BSBtnContainer.classList.add('BSBtnContainer');
  41. BSBtnReveal.classList.add('BSBtnReveal');
  42. BSBtnReveal.textContent = 'Reveal';
  43. BSBtnRetrieve.classList.add('BSBtnRetrieve');
  44. BSBtnRetrieve.textContent = 'Retrieve';
  45. BSBtnCopy.classList.add('BSBtnCopy');
  46. BSBtnCopy.textContent = 'Copy';
  47. BSBtnReset.classList.add('BSBtnReset');
  48. BSBtnReset.textContent = 'Reset';
  49. BSCheckTitle.innerHTML = '<input type="checkbox" class="BSCheckTitle">Include Game Title';
  50. BSCheckJoin.innerHTML = '<input type="checkbox" class="BSCheckJoin">Join Keys';
  51. style.type = 'text/css';
  52. style.innerHTML = `
  53. .BSRetrive {
  54. width: 100%;
  55. height: 200px;
  56. display: flex;
  57. flex-direction: column;
  58. box-sizing: border-box;
  59. border: 1px solid #424242;
  60. color: #999999;
  61. }
  62. .BSTextarea {
  63. width: 100%;
  64. height: 150px;
  65. border: none;
  66. background-color: #303030;
  67. color: #DDD;
  68. box-sizing: border-box;
  69. resize: none;
  70. }
  71. .BSBtnContainer {
  72. width: 100%;
  73. display: flex;
  74. padding-top: 5px;
  75. flex-grow: 1;
  76. box-sizing: border-box;
  77. }
  78. .BSBtnContainer > button {
  79. height: 34px;
  80. margin-right: 10px;
  81. padding: 6px 12px;
  82. border: 1px solid transparent;
  83. background-color: #262626;
  84. color: #dedede;
  85. box-sizing: border-box;
  86. outline: none;
  87. cursor: pointer;
  88. }
  89. .BSBtnContainer > button:hover {
  90. color: #A8A8A8;
  91. }
  92. .BSBtnContainer > label {
  93. margin-right: 10px;
  94. color: #dedede;
  95. }
  96. `;
  97. BSBtnReveal.addEventListener('click', () => {
  98. var keys = $$('a[ng-click^="redeemSerial"]');
  99. for (let key of keys) {
  100. if (key.parentNode.classList.contains('ng-hide')) continue;
  101. if (!key.closest('td').classList.contains('key-container')) continue;
  102. key.click();
  103. }
  104. });
  105. BSBtnRetrieve.addEventListener('click', () => {
  106. var keys = [],
  107. containers = $$('td.key-container'),
  108. separator = $('.BSCheckJoin').checked ? ',' : "\n";
  109. for (let container of containers) {
  110. let key = container.querySelector('input'),
  111. title = container.previousElementSibling;
  112.  
  113. if (!key) continue;
  114.  
  115. key = key.value.trim();
  116. if (title && $('.BSCheckTitle').checked) key = title.textContent.trim() + ', ' + key;
  117. keys.push(key);
  118. }
  119. BSTextarea.textContent = keys.join(separator);
  120. });
  121. BSBtnCopy.addEventListener('click', () => {
  122. BSTextarea.select();
  123. document.execCommand('copy');
  124. });
  125. BSBtnReset.addEventListener('click', () => {
  126. BSTextarea.textContent = '';
  127. });
  128. document.head.appendChild(style);
  129. BSBtnContainer.appendChild(BSBtnReveal);
  130. BSBtnContainer.appendChild(BSBtnRetrieve);
  131. BSBtnContainer.appendChild(BSBtnCopy);
  132. BSBtnContainer.appendChild(BSBtnReset);
  133. BSBtnContainer.appendChild(BSCheckTitle);
  134. BSBtnContainer.appendChild(BSCheckJoin);
  135. BSRetrive.appendChild(BSTextarea);
  136. BSRetrive.appendChild(BSBtnContainer);
  137. anchor.parentNode.insertBefore(BSRetrive, anchor);
  138. }
  139.  
  140. function observeOrderDetails(target) {
  141. new MutationObserver(mutations => {
  142. for (let mutation of mutations) {
  143. if (!mutation.addedNodes.length) continue;
  144. if (mutation.addedNodes[0].classList.contains('ng-scope')) setup();
  145. }
  146. }).observe(target, {childList: true});
  147. }
  148.  
  149. var anchor = getAnchor();
  150.  
  151. if (anchor) {
  152. setup();
  153. observeOrderDetails(anchor.closest('body > div.ng-scope'));
  154. } else {
  155. var bodyObserver = new MutationObserver(mutations => {
  156. for (let mutation of mutations) {
  157. if (!mutation.addedNodes.length) continue;
  158. if (mutation.addedNodes[0].classList.contains('ng-scope')) {
  159. observeOrderDetails(mutation.addedNodes[0]);
  160. bodyObserver.disconnect();
  161. }
  162. }
  163. });
  164.  
  165. bodyObserver.observe(document.body, {childList: true});
  166. }
  167. })();