sidebar.js 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. // TODO: This file was created by bulk-decaffeinate.
  2. // Sanity-check the conversion and remove this comment.
  3. /*
  4. * decaffeinate suggestions:
  5. * DS002: Fix invalid constructor
  6. * DS102: Remove unnecessary code created because of implicit returns
  7. * DS103: Rewrite code to no longer use __guard__, or convert again using --optional-chaining
  8. * DS206: Consider reworking classes to avoid initClass
  9. * DS207: Consider shorter variations of null checks
  10. * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md
  11. */
  12. const Cls = (app.views.Sidebar = class Sidebar extends app.View {
  13. constructor(...args) {
  14. this.resetHoverOnMouseMove = this.resetHoverOnMouseMove.bind(this);
  15. this.resetHover = this.resetHover.bind(this);
  16. this.showResults = this.showResults.bind(this);
  17. this.onReady = this.onReady.bind(this);
  18. this.onScopeChange = this.onScopeChange.bind(this);
  19. this.onSearching = this.onSearching.bind(this);
  20. this.onSearchClear = this.onSearchClear.bind(this);
  21. this.onFocus = this.onFocus.bind(this);
  22. this.onSelect = this.onSelect.bind(this);
  23. this.onClick = this.onClick.bind(this);
  24. this.onAltR = this.onAltR.bind(this);
  25. this.onEscape = this.onEscape.bind(this);
  26. this.afterRoute = this.afterRoute.bind(this);
  27. super(...args);
  28. }
  29. static initClass() {
  30. this.el = '._sidebar';
  31. this.events = {
  32. focus: 'onFocus',
  33. select: 'onSelect',
  34. click: 'onClick'
  35. };
  36. this.routes =
  37. {after: 'afterRoute'};
  38. this.shortcuts = {
  39. altR: 'onAltR',
  40. escape: 'onEscape'
  41. };
  42. }
  43. init() {
  44. if (!app.isMobile()) { this.addSubview(this.hover = new app.views.SidebarHover(this.el)); }
  45. this.addSubview(this.search = new app.views.Search);
  46. this.search
  47. .on('searching', this.onSearching)
  48. .on('clear', this.onSearchClear)
  49. .scope
  50. .on('change', this.onScopeChange);
  51. this.results = new app.views.Results(this, this.search);
  52. this.docList = new app.views.DocList;
  53. app.on('ready', this.onReady);
  54. $.on(document.documentElement, 'mouseleave', () => this.hide());
  55. $.on(document.documentElement, 'mouseenter', () => this.resetDisplay({forceNoHover: false}));
  56. }
  57. hide() {
  58. this.removeClass('show');
  59. }
  60. display() {
  61. this.addClass('show');
  62. }
  63. resetDisplay(options) {
  64. if (options == null) { options = {}; }
  65. if (!this.hasClass('show')) { return; }
  66. this.removeClass('show');
  67. if ((options.forceNoHover !== false) && !this.hasClass('no-hover')) {
  68. this.addClass('no-hover');
  69. $.on(window, 'mousemove', this.resetHoverOnMouseMove);
  70. }
  71. }
  72. resetHoverOnMouseMove() {
  73. $.off(window, 'mousemove', this.resetHoverOnMouseMove);
  74. return $.requestAnimationFrame(this.resetHover);
  75. }
  76. resetHover() {
  77. return this.removeClass('no-hover');
  78. }
  79. showView(view) {
  80. if (this.view !== view) {
  81. if (this.hover != null) {
  82. this.hover.hide();
  83. }
  84. this.saveScrollPosition();
  85. if (this.view != null) {
  86. this.view.deactivate();
  87. }
  88. this.view = view;
  89. this.render();
  90. this.view.activate();
  91. this.restoreScrollPosition();
  92. }
  93. }
  94. render() {
  95. this.html(this.view);
  96. }
  97. showDocList() {
  98. this.showView(this.docList);
  99. }
  100. showResults() {
  101. this.display();
  102. this.showView(this.results);
  103. }
  104. reset() {
  105. this.display();
  106. this.showDocList();
  107. this.docList.reset();
  108. this.search.reset();
  109. }
  110. onReady() {
  111. this.view = this.docList;
  112. this.render();
  113. this.view.activate();
  114. }
  115. onScopeChange(newDoc, previousDoc) {
  116. if (previousDoc) { this.docList.closeDoc(previousDoc); }
  117. if (newDoc) { this.docList.reveal(newDoc.toEntry()); } else { this.scrollToTop(); }
  118. }
  119. saveScrollPosition() {
  120. if (this.view === this.docList) {
  121. this.scrollTop = this.el.scrollTop;
  122. }
  123. }
  124. restoreScrollPosition() {
  125. if ((this.view === this.docList) && this.scrollTop) {
  126. this.el.scrollTop = this.scrollTop;
  127. this.scrollTop = null;
  128. } else {
  129. this.scrollToTop();
  130. }
  131. }
  132. scrollToTop() {
  133. this.el.scrollTop = 0;
  134. }
  135. onSearching() {
  136. this.showResults();
  137. }
  138. onSearchClear() {
  139. this.resetDisplay();
  140. this.showDocList();
  141. }
  142. onFocus(event) {
  143. this.display();
  144. if (event.target !== this.el) { $.scrollTo(event.target, this.el, 'continuous', {bottomGap: 2}); }
  145. }
  146. onSelect() {
  147. this.resetDisplay();
  148. }
  149. onClick(event) {
  150. if (event.which !== 1) { return; }
  151. if (__guardMethod__($.eventTarget(event), 'hasAttribute', o => o.hasAttribute('data-reset-list'))) {
  152. $.stopEvent(event);
  153. this.onAltR();
  154. }
  155. }
  156. onAltR() {
  157. this.reset();
  158. this.docList.reset({revealCurrent: true});
  159. this.display();
  160. }
  161. onEscape() {
  162. let doc;
  163. this.reset();
  164. this.resetDisplay();
  165. if ((doc = this.search.getScopeDoc())) { this.docList.reveal(doc.toEntry()); } else { this.scrollToTop(); }
  166. }
  167. onDocEnabled() {
  168. this.docList.onEnabled();
  169. this.reset();
  170. }
  171. afterRoute(name, context) {
  172. if ((app.shortcuts.eventInProgress != null ? app.shortcuts.eventInProgress.name : undefined) === 'escape') { return; }
  173. if (!context.init && app.router.isIndex()) { this.reset(); }
  174. this.resetDisplay();
  175. }
  176. });
  177. Cls.initClass();
  178. function __guardMethod__(obj, methodName, transform) {
  179. if (typeof obj !== 'undefined' && obj !== null && typeof obj[methodName] === 'function') {
  180. return transform(obj, methodName);
  181. } else {
  182. return undefined;
  183. }
  184. }