InstaSynchP Autocomplete

Autocomplete emotes, commands and others for the chat

目前为 2015-05-10 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name InstaSynchP Autocomplete
  3. // @namespace InstaSynchP
  4. // @description Autocomplete emotes, commands and others for the chat
  5.  
  6. // @version 1.1.1
  7. // @author Zod-
  8. // @source https://github.com/Zod-/InstaSynchP-Autocomplete
  9. // @license MIT
  10.  
  11. // @include *://instasync.com/r/*
  12. // @include *://*.instasync.com/r/*
  13. // @grant none
  14. // @run-at document-start
  15.  
  16. // @require https://greasyfork.org/scripts/5647-instasynchp-library/code/InstaSynchP%20Library.js?version=37716
  17. // ==/UserScript==
  18.  
  19. function Autocomplete(version) {
  20. "use strict";
  21. this.version = version;
  22. this.name = 'InstaSynchP Autocomplete';
  23. this.menuActive = false;
  24. this.autocompleteEnabled = true;
  25. this.sources = [];
  26. this.selects = [];
  27. this.settings = [{
  28. label: 'Autocomplete chat commands starting with \'',
  29. id: 'autocomplete-commands',
  30. type: 'checkbox',
  31. 'default': true,
  32. section: ['Chat', 'Autocomplete']
  33. }, {
  34. label: 'Autocomplete emotes starting with /',
  35. id: 'autocomplete-emotes',
  36. type: 'checkbox',
  37. 'default': true,
  38. section: ['Chat', 'Autocomplete']
  39. }, {
  40. label: 'Sort the results of the autocomplete',
  41. id: 'autocomplete-sort',
  42. type: 'checkbox',
  43. 'default': true,
  44. section: ['Chat', 'Autocomplete']
  45. }, {
  46. label: '# of results shown in the autocomplete',
  47. id: 'autocomplete-results',
  48. type: 'int',
  49. min: 0,
  50. 'default': 7,
  51. size: 1,
  52. section: ['Chat', 'Autocomplete']
  53. }];
  54. this.styles = [{
  55. name: 'autocomplete',
  56. url: 'https://cdn.rawgit.com/Zod-/InstaSynchP-Autocomplete/b3812c5c3f27a72ff36d5f130b8e20ee96cad2ee/jquery-ui.css',
  57. autoload: true
  58. }];
  59. }
  60.  
  61. Autocomplete.prototype.resetVariables = function () {
  62. "use strict";
  63. this.menuActive = false;
  64. this.autocompleteEnabled = true;
  65. };
  66.  
  67. Autocomplete.prototype.addSource = function (source, select) {
  68. "use strict";
  69. this.sources.push(source);
  70. this.selects.push(select);
  71. };
  72.  
  73. Autocomplete.prototype.executeOnce = function () {
  74. "use strict";
  75. var th = this;
  76. events.on(th, 'InputKeydown[9]', function (event) {
  77. if (!th.menuActive) {
  78. return;
  79. }
  80. event.keyCode = $.ui.keyCode.ENTER;
  81. $(this).trigger(event);
  82. });
  83. //emotes
  84. th.addSource(function (term) {
  85. if (!gmc.get('autocomplete-emotes')) {
  86. return [];
  87. }
  88. var lastIndex = term.lastIndexOf('/'),
  89. partToComplete = term.substring(lastIndex, term.length).toLowerCase();
  90. return $.map(Object.keys(window.$codes), function (item) {
  91. item = '/' + item;
  92. if (item.toLowerCase().startsWith(partToComplete)) {
  93. return item;
  94. }
  95. });
  96. },
  97. function (val, item) {
  98. //check if emote is at the beginning of the input
  99. if (window.$codes[item.substring(1, item.length)]) {
  100. return val.lastIndexOf(item) === 0;
  101. }
  102. return false;
  103. }
  104. );
  105.  
  106. //commands
  107. th.addSource(function (term) {
  108. term = term.toLowerCase();
  109. if (!gmc.get('autocomplete-commands')) {
  110. return [];
  111. }
  112. return $.map(Object.keys(commands.getAll()), function (item) {
  113. var command = commands.get(item);
  114. if (item.startsWith(term)) {
  115. if (command.type === 'mod' && !isMod()) {
  116. return undefined;
  117. }
  118. return command.name;
  119. }
  120. });
  121. },
  122. function (val, item) {
  123. var command = commands.get(item);
  124. if (command) {
  125. return val.lastIndexOf(item) === 0 && !command.hasArguments;
  126. }
  127. return false;
  128. }
  129. );
  130.  
  131. events.on(th, 'InputKeydown', function (event) {
  132. if (event.keyCode !== 40 && event.keyCode !== 38) {
  133. th.autocompleteEnabled = true;
  134. }
  135. });
  136. };
  137.  
  138. Autocomplete.prototype.preConnect = function () {
  139. "use strict";
  140. var th = this;
  141. //add the jquery autcomplete widget to InstaSynch's input field
  142. $("#cin").autocomplete({
  143. delay: 0,
  144. minLength: 0,
  145. source: function (request, response) {
  146. var result = [],
  147. i,
  148. words = request.term.split(' '),
  149. last = words[words.length - 1];
  150. //return if autocomplete has been turned off by other plugins
  151. if (!th.autocompleteEnabled || last.length === 0 || request.term.length !==
  152. $('#cin')[0].selectionStart) {
  153. response(result);
  154. return;
  155. }
  156. for (i = 0; i < th.sources.length; i += 1) {
  157. try {
  158. result = result.concat(th.sources[i].apply(this, [last]));
  159. } catch (err) {
  160. logger().error(th.name, "Source Error", err);
  161. }
  162. }
  163. if (gmc.get('autocomplete-sort')) {
  164. result.sort();
  165. }
  166.  
  167. response(result.slice(0, gmc.get('autocomplete-results')));
  168. },
  169. select: function (event, ui) {
  170. var val = this.value,
  171. uiVal = ui.item.value,
  172. i,
  173. instant = false;
  174. this.value = val.substring(0, val.lastIndexOf(uiVal[0])) + uiVal;
  175.  
  176. for (i = 0; i < th.selects.length; i += 1) {
  177. try {
  178. //check if the item can be sent instantly
  179. if (th.selects[i].apply(this, [this.value, uiVal])) {
  180. instant = true;
  181. break;
  182. }
  183. } catch (err) {
  184. logger().error(th.name, "Select Error", err);
  185. }
  186. }
  187. if (instant) {
  188. $(this).trigger(
  189. $.Event('keypress', {
  190. which: 13,
  191. keyCode: 13
  192. })
  193. );
  194. } else {
  195. this.value = this.value + ' ';
  196. }
  197. return false;
  198. },
  199. autoFocus: true,
  200. focus: function () {
  201. return false;
  202. },
  203. close: function () {
  204. th.menuActive = false;
  205. },
  206. open: function () {
  207. th.menuActive = true;
  208. }
  209. }).on('paste', function () {
  210. th.autocompleteEnabled = false;
  211. });
  212. };
  213.  
  214. window.plugins = window.plugins || {};
  215. window.plugins.autocomplete = new Autocomplete('1.1.1');