index.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325
  1. var baseSelect = document.getElementsByTagName('select');
  2. for ( var b = 0; b < baseSelect.length; b++ ) {
  3. if ( baseSelect[b].id === 'wb-settings-lang' ) {
  4. const langWidget = document.getElementById('wb-settings-lang-widget');
  5. if ( langWidget ) {
  6. var widgetPath = 'widgets';
  7. if ( document.location.pathname.split('/')[3] === 'rcscript' ) {
  8. widgetPath = 'widgets/RcGcDb';
  9. }
  10. langWidget.setAttribute('src', `/src/${widgetPath}/${baseSelect[b].value}.png`);
  11. baseSelect[b].addEventListener( 'input', function() {
  12. langWidget.setAttribute('src', `/src/${widgetPath}/${this.value}.png`);
  13. } );
  14. }
  15. }
  16. if ( baseSelect[b].parentNode.querySelector('button.addmore') ) {
  17. baseSelect[b].addEventListener( 'input', toggleOption );
  18. toggleOption.call(baseSelect[b]);
  19. }
  20. }
  21. var addmore = document.getElementsByClassName('addmore');
  22. for ( var j = 0; j < addmore.length; j++ ) {
  23. addmore[j].onclick = function() {
  24. var clone = this.previousElementSibling.cloneNode(true);
  25. clone.classList.add('wb-settings-additional-select');
  26. clone.removeAttribute('id');
  27. clone.removeAttribute('required');
  28. clone.childNodes.forEach( function(child) {
  29. child.removeAttribute('hidden');
  30. child.removeAttribute('selected');
  31. } );
  32. clone.querySelector('option.defaultSelect').setAttribute('selected', '');
  33. clone.addEventListener( 'input', toggleOption );
  34. this.before(clone);
  35. toggleOption.call(clone);
  36. }
  37. }
  38. /**
  39. * @this HTMLSelectElement
  40. */
  41. function toggleOption() {
  42. var options = [];
  43. var selected = [];
  44. var allSelect = this.parentNode.querySelectorAll('select');
  45. allSelect.forEach( function(select) {
  46. options.push(...select.options);
  47. selected.push(...select.selectedOptions);
  48. } );
  49. var button = this.parentNode.querySelector('button.addmore');
  50. if ( selected.some( function(option) {
  51. if ( option && option.value ) return false;
  52. else return true;
  53. } ) || allSelect.length >= 10 || allSelect.length >= this.options.length-1 ) {
  54. button.setAttribute('hidden', '');
  55. }
  56. else button.removeAttribute('hidden');
  57. selected = selected.filter( function(option) {
  58. if ( option && option.value ) return true;
  59. else return false;
  60. } ).map( function(option) {
  61. return option.value;
  62. } );
  63. options.forEach( function(option) {
  64. if ( selected.includes( option.value ) && !option.selected ) {
  65. option.setAttribute('disabled', '');
  66. }
  67. else if ( option.disabled ) option.removeAttribute('disabled');
  68. } );
  69. }
  70. const wiki = document.getElementById('wb-settings-wiki');
  71. if ( wiki ) {
  72. wiki.addEventListener( 'input', function() {
  73. if ( !/^(?:https?:)?\/\//.test(this.value) ) {
  74. if ( this.validity.valid ) {
  75. var divTemp = document.createElement('div');
  76. divTemp.innerHTML = '<input type="url" value="invalid">';
  77. this.setCustomValidity(divTemp.firstChild.validationMessage);
  78. }
  79. }
  80. else this.setCustomValidity('');
  81. } );
  82. const wikicheck = document.getElementById('wb-settings-wiki-check');
  83. const wikichecknotice = document.getElementById('wb-settings-wiki-check-notice');
  84. if ( wikicheck && wikichecknotice ) {
  85. wikicheck.onclick = function() {
  86. var wikinew = wiki.value.replace( /^(?:https?:)?\/\//, '' );
  87. var regex = wikinew.match( /^([a-z\d-]{1,50}\.(?:gamepedia\.com|(?:fandom\.com|wikia\.org)(?:(?!\/(?:wiki|api)\/)\/[a-z-]{2,12})?))(?:\/|$)/ );
  88. if ( regex ) wikinew = regex[1];
  89. else if ( !wiki.validity.valid ) return wiki.reportValidity();
  90. else {
  91. wikinew = wikinew.replace( /\/(?:api|load|index)\.php(?:|\?.*)$/, '' ).replace( /\/$/, '' );
  92. }
  93. wiki.setAttribute('readonly', '');
  94. wikicheck.setAttribute('disabled', '');
  95. fetch( '/api?wiki=' + encodeURIComponent( wikinew ), {
  96. method: 'GET',
  97. cache: 'no-cache',
  98. mode: 'same-origin',
  99. headers: {
  100. Accept: 'application/json'
  101. }
  102. } ).then( function(response) {
  103. if ( response.ok && response.status === 200 ) return response.json();
  104. else return Promise.reject('Error: The server did not respond correctly.');
  105. } ).then( function(response) {
  106. if ( !response.api ) {
  107. console.log('Error: The server did not respond correctly.');
  108. return;
  109. }
  110. wikichecknotice.className = 'notice';
  111. wikichecknotice.innerHTML = '';
  112. if ( response.error ) {
  113. wiki.setCustomValidity(i18n.invalid.title);
  114. wikichecknotice.classList.add('notice-error');
  115. var noticeTitle = document.createElement('b');
  116. noticeTitle.textContent = i18n.invalid.title;
  117. var noticeText = document.createElement('div');
  118. noticeText.textContent = i18n.invalid.text;
  119. wikichecknotice.append(noticeTitle, noticeText);
  120. return;
  121. }
  122. wiki.value = response.wiki;
  123. if ( document.location.pathname.split('/')[3] === 'rcscript' ) {
  124. if ( !response.MediaWiki ) {
  125. wiki.setCustomValidity(i18n.outdated.title);
  126. wikichecknotice.classList.add('notice-error');
  127. var noticeTitle = document.createElement('b');
  128. noticeTitle.textContent = i18n.outdated.title;
  129. var noticeText = document.createElement('div');
  130. noticeText.textContent = i18n.outdated.text;
  131. var noticeLink = document.createElement('a');
  132. noticeLink.setAttribute('target', '_blank');
  133. noticeLink.setAttribute('href', 'https://www.mediawiki.org/wiki/MediaWiki_1.30');
  134. noticeLink.textContent = 'https://www.mediawiki.org/wiki/MediaWiki_1.30';
  135. wikichecknotice.append(noticeTitle, noticeText, noticeLink);
  136. return;
  137. }
  138. if ( response.RcGcDw !== document.location.pathname.split('/')[2] ) {
  139. wikichecknotice.classList.add('notice-info');
  140. var noticeTitle = document.createElement('b');
  141. noticeTitle.textContent = i18n.sysmessage.title;
  142. var sysmessageLink = document.createElement('a');
  143. sysmessageLink.setAttribute('target', '_blank');
  144. sysmessageLink.setAttribute('href', response.customRcGcDw);
  145. var sysmessageCode = document.createElement('code');
  146. sysmessageCode.textContent = 'MediaWiki:Custom-RcGcDw';
  147. sysmessageLink.append(sysmessageCode);
  148. var guildCode = document.createElement('code');
  149. guildCode.className = 'user-select';
  150. guildCode.textContent = document.location.pathname.split('/')[2];
  151. var noticeText = document.createElement('div');
  152. var textSnippets = i18n.sysmessage.text.split(/\$\d/);
  153. noticeText.append(
  154. document.createTextNode(textSnippets[0]),
  155. sysmessageLink,
  156. document.createTextNode(textSnippets[1]),
  157. guildCode,
  158. document.createTextNode(textSnippets[2])
  159. );
  160. var noticeLink = sysmessageLink.cloneNode();
  161. noticeLink.textContent = response.customRcGcDw;
  162. wikichecknotice.append(noticeTitle, noticeText, noticeLink);
  163. return;
  164. }
  165. wikichecknotice.classList.add('notice-success');
  166. var noticeTitle = document.createElement('b');
  167. noticeTitle.textContent = i18n.valid.title;
  168. wikichecknotice.append(noticeTitle);
  169. return;
  170. }
  171. wikichecknotice.classList.add('notice-success');
  172. var noticeTitle = document.createElement('b');
  173. noticeTitle.textContent = i18n.valid.title;
  174. wikichecknotice.append(noticeTitle);
  175. if ( !/\.(?:gamepedia\.com|fandom\.com|wikia\.org)$/.test(wiki.value.split('/')[2]) ) {
  176. if ( !response.MediaWiki ) {
  177. var noticeLink = document.createElement('a');
  178. noticeLink.setAttribute('target', '_blank');
  179. noticeLink.setAttribute('href', 'https://www.mediawiki.org/wiki/MediaWiki_1.30');
  180. noticeLink.textContent = 'MediaWiki 1.30';
  181. var noticeText = document.createElement('div');
  182. var textSnippets = i18n.valid.MediaWiki.split(/\$\d/);
  183. noticeText.append(
  184. document.createTextNode(textSnippets[0]),
  185. noticeLink,
  186. document.createTextNode(textSnippets[1])
  187. );
  188. wikichecknotice.append(noticeText);
  189. }
  190. if ( !response.TextExtracts ) {
  191. var noticeLink = document.createElement('a');
  192. noticeLink.setAttribute('target', '_blank');
  193. noticeLink.setAttribute('href', 'https://www.mediawiki.org/wiki/Extension:TextExtracts');
  194. noticeLink.textContent = 'TextExtracts';
  195. var noticeText = document.createElement('div');
  196. var textSnippets = i18n.valid.TextExtracts.split(/\$\d/);
  197. noticeText.append(
  198. document.createTextNode(textSnippets[0]),
  199. noticeLink,
  200. document.createTextNode(textSnippets[1])
  201. );
  202. wikichecknotice.append(noticeText);
  203. }
  204. if ( !response.PageImages ) {
  205. var noticeLink = document.createElement('a');
  206. noticeLink.setAttribute('target', '_blank');
  207. noticeLink.setAttribute('href', 'https://www.mediawiki.org/wiki/Extension:PageImages');
  208. noticeLink.textContent = 'PageImages';
  209. var noticeText = document.createElement('div');
  210. var textSnippets = i18n.valid.PageImages.split(/\$\d/);
  211. noticeText.append(
  212. document.createTextNode(textSnippets[0]),
  213. noticeLink,
  214. document.createTextNode(textSnippets[1])
  215. );
  216. wikichecknotice.append(noticeText);
  217. }
  218. }
  219. }, function(error) {
  220. console.log(error)
  221. } ).finally( function() {
  222. wiki.removeAttribute('readonly');
  223. wikicheck.removeAttribute('disabled');
  224. } );
  225. }
  226. }
  227. const feeds = document.getElementById('wb-settings-feeds');
  228. if ( feeds ) {
  229. const hidefeeds = document.getElementById('wb-settings-feeds-hide');
  230. const feedsonly = document.getElementById('wb-settings-feeds-only');
  231. const hidefeedsonly = document.getElementById('wb-settings-feeds-only-hide');
  232. feeds.addEventListener( 'change', function() {
  233. if ( this.checked ) {
  234. hidefeedsonly.removeAttribute('style');
  235. if ( !hidefeeds.hasAttribute('style') ) feedsonly.removeAttribute('disabled');
  236. }
  237. else {
  238. hidefeedsonly.setAttribute('style', 'visibility: hidden;');
  239. feedsonly.setAttribute('disabled', '');
  240. }
  241. } );
  242. wiki.addEventListener( 'input', function() {
  243. if ( this.validity.valid && /\.(?:fandom\.com|wikia\.org)$/.test(this.value.split('/')[2]) ) {
  244. hidefeeds.removeAttribute('style');
  245. feeds.removeAttribute('disabled');
  246. if ( !hidefeedsonly.hasAttribute('style') ) feedsonly.removeAttribute('disabled');
  247. }
  248. else {
  249. hidefeeds.setAttribute('style', 'visibility: hidden;');
  250. feeds.setAttribute('disabled', '');
  251. feedsonly.setAttribute('disabled', '');
  252. }
  253. } );
  254. }
  255. }
  256. const usergroup = document.getElementById('wb-settings-usergroup');
  257. if ( usergroup ) {
  258. const multigroup = document.getElementById('wb-settings-usergroup-multiple');
  259. const usergrouplist = document.getElementById('wb-settings-usergroup-list');
  260. usergroup.addEventListener( 'input', function() {
  261. if ( /\s*[,|]\s*$/.test(usergroup.value) ) {
  262. var usedGroups = usergroup.value.trim().split(/\s*[,|]\s*/);
  263. var lastChar = usergroup.value.substring(usergroup.value.length - 1);
  264. usergrouplist.childNodes.forEach( function(listedGroup) {
  265. if ( !listedGroup.value ) return;
  266. var lastIndex = listedGroup.value.lastIndexOf(lastChar);
  267. var originalGroup = listedGroup.value.substring(lastIndex + 1).trim();
  268. if ( usedGroups.includes( originalGroup ) ) return;
  269. listedGroup.value = `${usergroup.value.trim()} ${originalGroup}`;
  270. } );
  271. }
  272. var newWidth = usergroup.value.trim().length * 7;
  273. if ( newWidth < usergroup.parentElement.clientWidth * 0.75 ) {
  274. usergroup.setAttribute('style', `min-width: ${newWidth}px;`);
  275. }
  276. if ( usergroup.value.includes( ',' ) || usergroup.value.includes( '|' ) ) {
  277. multigroup.removeAttribute('style');
  278. multigroup.removeAttribute('disabled');
  279. }
  280. else if ( !multigroup.hasAttribute('style') ) {
  281. multigroup.setAttribute('style', 'visibility: hidden;');
  282. multigroup.setAttribute('disabled', '');
  283. }
  284. } );
  285. }
  286. const prefix = document.getElementById('wb-settings-prefix');
  287. if ( prefix ) prefix.addEventListener( 'input', function() {
  288. if ( prefix.validity.patternMismatch ) {
  289. if ( prefix.value.trim().includes( ' ' ) ) {
  290. prefix.setCustomValidity(i18n.prefix.space);
  291. }
  292. else if ( prefix.value.includes( '`' ) ) {
  293. prefix.setCustomValidity(i18n.prefix.code);
  294. }
  295. else if ( prefix.value.includes( '\\' ) ) {
  296. prefix.setCustomValidity(i18n.prefix.backslash);
  297. }
  298. else prefix.setCustomValidity('');
  299. }
  300. else prefix.setCustomValidity('');
  301. } );
  302. /*
  303. var collapsible = document.getElementsByClassName('collapsible');
  304. for ( var i = 0; i < collapsible.length; i++ ) {
  305. collapsible[i].onclick = function() {
  306. this.classList.toggle('active');
  307. if ( this.id === 'wb-settings-wiki-search' ) {
  308. wiki.toggleAttribute('readonly');
  309. }
  310. var content = this.nextElementSibling;
  311. if ( content.style.display === 'block' ) {
  312. content.style.display = 'none';
  313. }
  314. else {
  315. content.style.display = 'block';
  316. }
  317. }
  318. }
  319. */