Wanikani Open Framework - Progress module

Progress module for Wanikani Open Framework

此脚本不应直接安装,它是一个供其他脚本使用的外部库。如果您需要使用该库,请在脚本元属性加入:// @require https://update.gf.qytechs.cn/scripts/38577/1091792/Wanikani%20Open%20Framework%20-%20Progress%20module.js

  1. // ==UserScript==
  2. // @name Wanikani Open Framework - Progress module
  3. // @namespace rfindley
  4. // @description Progress module for Wanikani Open Framework
  5. // @version 1.0.11
  6. // @copyright 2022+, Robin Findley
  7. // @license MIT; http://opensource.org/licenses/MIT
  8. // ==/UserScript==
  9.  
  10. (function(global) {
  11.  
  12. //########################################################################
  13. //------------------------------
  14. // Published interface
  15. //------------------------------
  16. global.wkof.Progress = {
  17. update: update_progress,
  18. popup_delay: get_or_set_popup_delay,
  19. }
  20. //########################################################################
  21.  
  22. const default_popup_delay = 2500; // Delay before popup will open (in milliseconds).
  23. var popup_delay = default_popup_delay;
  24. var show_popup = true;
  25. var popup_delay_started = false, popup_delay_expired = false, popup_timer;
  26. var externals_requested = false, externals_loaded = false;
  27. var progress_bars = {};
  28. var user_closed = false;
  29. var dialog_visible = false, dialog;
  30.  
  31. //------------------------------
  32. // Set the delay before the progress dialog pops up.
  33. //------------------------------
  34. function get_or_set_popup_delay(delay, silent) {
  35. if (typeof delay !== 'undefined' && delay !== null) {
  36. if (delay === 'default') delay = default_popup_delay;
  37. delay = Number(delay);
  38. if (Number.isNaN(delay)) throw 'Invalid value for popup_delay';
  39. show_popup = (delay >= 0);
  40. localStorage.setItem('wkof.Progress.popup_delay', delay);
  41. popup_delay = delay;
  42. }
  43. if (silent !== true) console.log('popup_delay ' + (show_popup ? ('= ' + popup_delay) : 'is disabled'));
  44. }
  45.  
  46. //------------------------------
  47. // Update the progress bar.
  48. //------------------------------
  49. function update_progress(data) {
  50. if (data) update_data(data);
  51.  
  52. if (!dialog_visible && !have_pending()) return shutdown();
  53.  
  54. // We have something pending, but don't show dialog until popup_delay has passed.
  55. if (!popup_delay_started) return start_popup_delay();
  56.  
  57. // Popup delay has passed. Show progress.
  58. if (!popup_delay_expired) return;
  59. update_dialog();
  60. }
  61.  
  62. //------------------------------
  63. // Update our stored progress bar status
  64. //------------------------------
  65. function update_data(data) {
  66. var bar = progress_bars[data.name];
  67. if (!bar) progress_bars[data.name] = bar = {label: data.label};
  68. bar.is_updated = true;
  69. bar.value = data.value;
  70. bar.max = data.max;
  71. if (bar.max === 0) {
  72. bar.value = 1;
  73. bar.max = 1;
  74. }
  75. // Don't retain items that complete before the dialog pops up.
  76. if (!popup_delay_expired && (bar.value >= bar.max)) delete progress_bars[data.name];
  77. }
  78.  
  79. //------------------------------
  80. // Check if some progress is still pending.
  81. //------------------------------
  82. function have_pending() {
  83. var all_done = true;
  84. for (name in progress_bars) {
  85. var progress_bar = progress_bars[name];
  86. if (progress_bar.value < progress_bar.max) all_done = false;
  87. }
  88. return !all_done;
  89. }
  90.  
  91. //------------------------------
  92. // Delay the dialog from popping up until progress takes at least N milliseconds.
  93. //------------------------------
  94. function start_popup_delay() {
  95. get_or_set_popup_delay(localStorage.getItem('wkof.Progress.popup_delay'), true /* silent */);
  96. if (!show_popup) return;
  97. popup_delay_started = true;
  98. popup_timer = setTimeout(function() {
  99. popup_delay_expired = true;
  100. update_progress();
  101. }, popup_delay);
  102. }
  103.  
  104. //------------------------------
  105. // Update the contents of the progress dialog (if it's currently visible)
  106. //------------------------------
  107. function update_dialog() {
  108. if (!externals_requested) {
  109. externals_requested = true;
  110. load_externals()
  111. .then(function() {
  112. externals_loaded = true;
  113. update_progress();
  114. });
  115. return;
  116. }
  117. if (!externals_loaded) return;
  118. if (user_closed) return;
  119.  
  120. if (!dialog_visible) {
  121. dialog_visible = true;
  122. if (!document.querySelector('#wkof_ds')) {
  123. let ds = document.createElement('div');
  124. ds.setAttribute('id', 'wkof_ds');
  125. document.body.prepend(ds);
  126. }
  127.  
  128. dialog = $('<div id="wkof_progbar_dlg" class="wkofs_progress_dlg" style="display:none;"></div>');
  129.  
  130. dialog.dialog({
  131. title: 'Loading Data...',
  132. minHeight: 20,
  133. maxHeight: window.innerHeight,
  134. height: 'auto',
  135. dialogClass: 'wkof_progbar_dlg',
  136. modal: false,
  137. resizable: false,
  138. autoOpen: false,
  139. appendTo: '#wkof_ds',
  140. close: dialog_close
  141. });
  142. dialog.dialog('open');
  143. }
  144.  
  145. var all_done = true;
  146. for (name in progress_bars) {
  147. var progress_bar = progress_bars[name];
  148. if (progress_bar.value < progress_bar.max) all_done = false;
  149. var bar = $('#wkof_progbar_dlg .wkof_progbar_wrap[name="'+name+'"]');
  150. if (bar.length === 0) {
  151. bar = $('<div class="wkof_progbar_wrap" name="'+name+'"><label>'+progress_bar.label+'</label><div class="wkof_progbar"></div></div>');
  152. var bars = $('#wkof_progbar_dlg .wkof_progbar_wrap');
  153. bars.push(bar[0]);
  154. $('#wkof_progbar_dlg').append(bars.sort(bar_label_compare));
  155. }
  156. if (progress_bar.is_updated) {
  157. progress_bar.is_updated = false;
  158. bar.find('.wkof_progbar').progressbar({value: progress_bar.value, max: progress_bar.max});
  159. }
  160. }
  161.  
  162. if (all_done) shutdown();
  163. }
  164.  
  165. function dialog_close() {
  166. dialog.dialog('destroy');
  167. dialog_visible = false;
  168. user_closed = true;
  169. }
  170.  
  171. //------------------------------
  172. // Load external support files (jquery UI and stylesheet)
  173. //------------------------------
  174. function load_externals() {
  175. var css_url = wkof.support_files['jqui_wkmain.css'];
  176.  
  177. wkof.include('Jquery');
  178. return wkof.ready('document, Jquery')
  179. .then(function(){
  180. return Promise.all([
  181. wkof.load_script(wkof.support_files['jquery_ui.js'], true /* cache */),
  182. wkof.load_css(css_url, true /* cache */)
  183. ]);
  184. })
  185. .then(function(){
  186. // Workaround... https://community.wanikani.com/t/19984/55
  187. delete $.fn.autocomplete;
  188. });
  189. }
  190.  
  191. //------------------------------
  192. // Comparison function for sorting progress bars.
  193. //------------------------------
  194. function bar_label_compare(a, b) {
  195. var a = $(a).find('label').text();
  196. var b = $(b).find('label').text();
  197. return a.localeCompare(b);
  198. }
  199.  
  200. //------------------------------
  201. // Shut down the dialog box and cancel the popup delay timer.
  202. //------------------------------
  203. function shutdown() {
  204. // If popup timer was pending, cancel it.
  205. if (popup_delay_started && !popup_delay_expired) clearTimeout(popup_timer);
  206. popup_delay_started = false;
  207. popup_delay_expired = false;
  208.  
  209. // If progress dialog is open, close it.
  210. if (dialog_visible) dialog.dialog('close');
  211. user_closed = false;
  212. progress_bars = {};
  213. }
  214.  
  215. function set_ready_state() {
  216. // Delay guarantees include() callbacks are called before ready() callbacks.
  217. setTimeout(function(){wkof.set_state('wkof.Progress', 'ready');}, 0);
  218. }
  219. set_ready_state();
  220.  
  221. })(window);

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址