Wanikani Open Framework - Menu module

Menu module for Wanikani Open Framework

目前為 2018-02-17 提交的版本,檢視 最新版本

此腳本不應該直接安裝,它是一個供其他腳本使用的函式庫。欲使用本函式庫,請在腳本 metadata 寫上: // @require https://update.cn-greasyfork.org/scripts/38578/252062/Wanikani%20Open%20Framework%20-%20Menu%20module.js

  1. // ==UserScript==
  2. // @name Wanikani Open Framework - Menu module
  3. // @namespace rfindley
  4. // @description Menu module for Wanikani Open Framework
  5. // @version 1.0.0
  6. // @copyright 2018+, 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.Menu = {
  17. insert_script_link: insert_script_link
  18. };
  19. //########################################################################
  20.  
  21. //------------------------------
  22. // Install 'Scripts' header in menu, if not present.
  23. //------------------------------
  24. function install_scripts_header() {
  25. // Abort if already installed.
  26. if ($('.scripts-header').length !== 0) return false;
  27.  
  28. // Install html.
  29. $('.nav-header:contains("Account")').before(
  30. '<li class="scripts-header nav-header">Scripts</li>'
  31. );
  32.  
  33. // Click to open Settings menu.
  34. $('.dropdown.account').on('click','.scripts-submenu>a',function(e){
  35. var link = $(e.target).parent();
  36. link.siblings('.scripts-submenu.open').removeClass('open');
  37. link.toggleClass('open');
  38. // If we opened the menu, listen for off-menu clicks.
  39. if (link.hasClass('open')) {
  40. $('body').on('click.scripts-submenu',function(e){
  41. $('body').off('click.scripts-submenu');
  42. $('.scripts-submenu').removeClass('open');
  43. return true;
  44. })
  45. } else {
  46. $('body').off('click.scripts-submenu');
  47. }
  48. return false;
  49. });
  50. return true;
  51. }
  52.  
  53. //------------------------------
  54. // Sort menu items
  55. //------------------------------
  56. function sort_name(a,b) {
  57. return a.querySelector('a').innerText.localeCompare(b.querySelector('a').innerText);
  58. }
  59.  
  60. //------------------------------
  61. // Install Submenu, if not present.
  62. //------------------------------
  63. function install_scripts_submenu(name) {
  64. // Abort if already installed.
  65. if ($('.scripts-submenu[name="'+name+'"]').length !== 0) return false;
  66.  
  67. // Install css and html.
  68. if ($('style[name="scripts_submenu"]').length === 0) {
  69. $('head').append(
  70. '<style name="scripts_submenu">'+
  71. 'html#main .navbar .scripts-submenu {position:relative;}'+
  72. 'html#main .navbar .scripts-submenu.open>.dropdown-menu {display:block;position:absolute;top:0px;}'+
  73. '.scripts-submenu>a:before {content:"\uf0d9 "; font-family:"FontAwesome";}'+
  74. '@media (max-width: 979px) {'+
  75. ' .scripts-submenu>a:before {content:"";}'+
  76. ' html#main .navbar .scripts-submenu {margin-left:1.5em;}'+
  77. ' html#main .navbar .scripts-submenu>a {text-align:left;}'+
  78. ' html#main .navbar .scripts-submenu>ul.dropdown-menu {margin-left:.5em;}'+
  79. ' html#main .navbar .dropdown.account>.dropdown-menu>.script-link {margin-left:1.5em;}'+
  80. ' html#main .navbar .dropdown.account>.dropdown-menu>.script-link>a {text-align:left;}'+
  81. ' html#main .navbar .dropdown-menu>li:not(.nav-header).scripts-submenu {display:block;width:100%;}'+
  82. ' html#main .navbar .scripts-submenu>.dropdown-menu {display:block;padding:0;margin:0;box-shadow:none;}'+
  83. ' html#main .navbar .scripts-submenu.open>.dropdown-menu {position:relative;top:0px;left:initial;right:initial;}'+
  84. ' html#main .navbar .dropdown-menu>li:not(.nav-header).scripts-submenu>.dropdown-menu>li {width:auto;padding:0 1em;}'+
  85. '}'+
  86. '</style>'
  87. );
  88. }
  89. $('.scripts-header').after(
  90. '<li class="scripts-submenu" name="'+name+'">'+
  91. ' <a href="#">'+name+'</a>'+
  92. ' <ul class="dropdown-menu">'+
  93. ' </ul>'+
  94. '</li>'
  95. );
  96. var items = $('.scripts-header').siblings('.scripts-submenu,.script-link').sort(sort_name);
  97. $('.scripts-header').after(items);
  98. return true;
  99. }
  100.  
  101. //------------------------------
  102. // Inserts script link into script settings menu.
  103. //------------------------------
  104. function insert_script_link(config) {
  105. // Abort if the script already exists
  106. var link_id = config.name+'_settings_link';
  107. if ($('#'+link_id).length !== 0) return;
  108. install_scripts_header();
  109. if (config.submenu) {
  110. install_scripts_submenu(config.submenu);
  111.  
  112. // Append the script, and sort the menu.
  113. var menu = $('.scripts-submenu[name="'+config.submenu+'"] .dropdown-menu');
  114. var class_html = (config.class ? ' class="'+config.class+'"': '');
  115. menu.append('<li id="'+link_id+'" name="'+config.name+'"'+class_html+'><a href="#">'+config.title+'</a></li>');
  116. menu.append(menu.children().sort(sort_name));
  117. } else {
  118. var class_html = (config.class ? ' '+classes:'');
  119. $('.scripts-header').after('<li id="'+link_id+'" name="'+config.name+'" class="script-link '+class_html+'"><a href="#">'+config.title+'</a></li>');
  120. var items = $('.scripts-header').siblings('.scripts-submenu,.script-link').sort(sort_name);
  121. $('.scripts-header').after(items);
  122. }
  123.  
  124. // Add a callback for when the link is clicked.
  125. $('#'+link_id).on('click', function(e){
  126. $('body').off('click.scripts-settings');
  127. $('.dropdown.account').removeClass('open');
  128. $('.scripts-submenu').removeClass('open');
  129. config.on_click(e);
  130. return false;
  131. });
  132. }
  133.  
  134. wkof.ready('document').then(set_ready_state);
  135.  
  136. function set_ready_state(){
  137. // Delay guarantees include() callbacks are called before ready() callbacks.
  138. setTimeout(function(){wkof.set_state('wkof.Menu', 'ready');},0);
  139. }
  140.  
  141. })(window);
  142.