doc_list.js 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  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. * DS101: Remove unnecessary use of Array.from
  7. * DS206: Consider reworking classes to avoid initClass
  8. * DS207: Consider shorter variations of null checks
  9. * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md
  10. */
  11. const Cls = (app.views.DocList = class DocList extends app.View {
  12. constructor(...args) {
  13. this.render = this.render.bind(this);
  14. this.onOpen = this.onOpen.bind(this);
  15. this.onClose = this.onClose.bind(this);
  16. this.onClick = this.onClick.bind(this);
  17. this.onEnabled = this.onEnabled.bind(this);
  18. this.afterRoute = this.afterRoute.bind(this);
  19. super(...args);
  20. }
  21. static initClass() {
  22. this.className = '_list';
  23. this.attributes =
  24. {role: 'navigation'};
  25. this.events = {
  26. open: 'onOpen',
  27. close: 'onClose',
  28. click: 'onClick'
  29. };
  30. this.routes =
  31. {after: 'afterRoute'};
  32. this.elements = {
  33. disabledTitle: '._list-title',
  34. disabledList: '._disabled-list'
  35. };
  36. }
  37. init() {
  38. this.lists = {};
  39. this.addSubview(this.listFocus = new app.views.ListFocus(this.el));
  40. this.addSubview(this.listFold = new app.views.ListFold(this.el));
  41. this.addSubview(this.listSelect = new app.views.ListSelect(this.el));
  42. app.on('ready', this.render);
  43. }
  44. activate() {
  45. if (super.activate(...arguments)) {
  46. for (var slug in this.lists) { var list = this.lists[slug]; list.activate(); }
  47. this.listSelect.selectCurrent();
  48. }
  49. }
  50. deactivate() {
  51. if (super.deactivate(...arguments)) {
  52. for (var slug in this.lists) { var list = this.lists[slug]; list.deactivate(); }
  53. }
  54. }
  55. render() {
  56. let html = '';
  57. for (var doc of Array.from(app.docs.all())) {
  58. html += this.tmpl('sidebarDoc', doc, {fullName: app.docs.countAllBy('name', doc.name) > 1});
  59. }
  60. this.html(html);
  61. if (!app.isSingleDoc() && (app.disabledDocs.size() !== 0)) { this.renderDisabled(); }
  62. }
  63. renderDisabled() {
  64. this.append(this.tmpl('sidebarDisabled', {count: app.disabledDocs.size()}));
  65. this.refreshElements();
  66. this.renderDisabledList();
  67. }
  68. renderDisabledList() {
  69. if (app.settings.get('hideDisabled')) {
  70. this.removeDisabledList();
  71. } else {
  72. this.appendDisabledList();
  73. }
  74. }
  75. appendDisabledList() {
  76. let doc;
  77. let html = '';
  78. const docs = [].concat(...Array.from(app.disabledDocs.all() || []));
  79. while ((doc = docs.shift())) {
  80. if (doc.version != null) {
  81. var versions = '';
  82. while (true) {
  83. versions += this.tmpl('sidebarDoc', doc, {disabled: true});
  84. if ((docs[0] != null ? docs[0].name : undefined) !== doc.name) { break; }
  85. doc = docs.shift();
  86. }
  87. html += this.tmpl('sidebarDisabledVersionedDoc', doc, versions);
  88. } else {
  89. html += this.tmpl('sidebarDoc', doc, {disabled: true});
  90. }
  91. }
  92. this.append(this.tmpl('sidebarDisabledList', html));
  93. this.disabledTitle.classList.add('open-title');
  94. this.refreshElements();
  95. }
  96. removeDisabledList() {
  97. if (this.disabledList) { $.remove(this.disabledList); }
  98. this.disabledTitle.classList.remove('open-title');
  99. this.refreshElements();
  100. }
  101. reset(options) {
  102. if (options == null) { options = {}; }
  103. this.listSelect.deselect();
  104. if (this.listFocus != null) {
  105. this.listFocus.blur();
  106. }
  107. this.listFold.reset();
  108. if (options.revealCurrent || app.isSingleDoc()) { this.revealCurrent(); }
  109. }
  110. onOpen(event) {
  111. $.stopEvent(event);
  112. const doc = app.docs.findBy('slug', event.target.getAttribute('data-slug'));
  113. if (doc && !this.lists[doc.slug]) {
  114. this.lists[doc.slug] = doc.types.isEmpty() ?
  115. new app.views.EntryList(doc.entries.all())
  116. :
  117. new app.views.TypeList(doc);
  118. $.after(event.target, this.lists[doc.slug].el);
  119. }
  120. }
  121. onClose(event) {
  122. $.stopEvent(event);
  123. const doc = app.docs.findBy('slug', event.target.getAttribute('data-slug'));
  124. if (doc && this.lists[doc.slug]) {
  125. this.lists[doc.slug].detach();
  126. delete this.lists[doc.slug];
  127. }
  128. }
  129. select(model) {
  130. this.listSelect.selectByHref(model != null ? model.fullPath() : undefined);
  131. }
  132. reveal(model) {
  133. this.openDoc(model.doc);
  134. if (model.type) { this.openType(model.getType()); }
  135. this.focus(model);
  136. this.paginateTo(model);
  137. this.scrollTo(model);
  138. }
  139. focus(model) {
  140. if (this.listFocus != null) {
  141. this.listFocus.focus(this.find(`a[href='${model.fullPath()}']`));
  142. }
  143. }
  144. revealCurrent() {
  145. let model;
  146. if (model = app.router.context.type || app.router.context.entry) {
  147. this.reveal(model);
  148. this.select(model);
  149. }
  150. }
  151. openDoc(doc) {
  152. if (app.disabledDocs.contains(doc) && doc.version) { this.listFold.open(this.find(`[data-slug='${doc.slug_without_version}']`)); }
  153. this.listFold.open(this.find(`[data-slug='${doc.slug}']`));
  154. }
  155. closeDoc(doc) {
  156. this.listFold.close(this.find(`[data-slug='${doc.slug}']`));
  157. }
  158. openType(type) {
  159. this.listFold.open(this.lists[type.doc.slug].find(`[data-slug='${type.slug}']`));
  160. }
  161. paginateTo(model) {
  162. if (this.lists[model.doc.slug] != null) {
  163. this.lists[model.doc.slug].paginateTo(model);
  164. }
  165. }
  166. scrollTo(model) {
  167. $.scrollTo(this.find(`a[href='${model.fullPath()}']`), null, 'top', {margin: app.isMobile() ? 48 : 0});
  168. }
  169. toggleDisabled() {
  170. if (this.disabledTitle.classList.contains('open-title')) {
  171. this.removeDisabledList();
  172. app.settings.set('hideDisabled', true);
  173. } else {
  174. this.appendDisabledList();
  175. app.settings.set('hideDisabled', false);
  176. }
  177. }
  178. onClick(event) {
  179. let slug;
  180. const target = $.eventTarget(event);
  181. if (this.disabledTitle && $.hasChild(this.disabledTitle, target) && (target.tagName !== 'A')) {
  182. $.stopEvent(event);
  183. this.toggleDisabled();
  184. } else if (slug = target.getAttribute('data-enable')) {
  185. $.stopEvent(event);
  186. const doc = app.disabledDocs.findBy('slug', slug);
  187. if (doc) { app.enableDoc(doc, this.onEnabled, this.onEnabled); }
  188. }
  189. }
  190. onEnabled() {
  191. this.reset();
  192. this.render();
  193. }
  194. afterRoute(route, context) {
  195. if (context.init) {
  196. if (this.activated) { this.reset({revealCurrent: true}); }
  197. } else {
  198. this.select(context.type || context.entry);
  199. }
  200. }
  201. });
  202. Cls.initClass();