doc_list.js 6.3 KB

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