doc_list.js 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  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. 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 = { role: "navigation" };
  24. this.events = {
  25. open: "onOpen",
  26. close: "onClose",
  27. click: "onClick",
  28. };
  29. this.routes = { after: "afterRoute" };
  30. this.elements = {
  31. disabledTitle: "._list-title",
  32. disabledList: "._disabled-list",
  33. };
  34. }
  35. init() {
  36. this.lists = {};
  37. this.addSubview((this.listFocus = new app.views.ListFocus(this.el)));
  38. this.addSubview((this.listFold = new app.views.ListFold(this.el)));
  39. this.addSubview((this.listSelect = new app.views.ListSelect(this.el)));
  40. app.on("ready", this.render);
  41. }
  42. activate() {
  43. if (super.activate(...arguments)) {
  44. for (var slug in this.lists) {
  45. var list = this.lists[slug];
  46. list.activate();
  47. }
  48. this.listSelect.selectCurrent();
  49. }
  50. }
  51. deactivate() {
  52. if (super.deactivate(...arguments)) {
  53. for (var slug in this.lists) {
  54. var list = this.lists[slug];
  55. list.deactivate();
  56. }
  57. }
  58. }
  59. render() {
  60. let html = "";
  61. for (var doc of Array.from(app.docs.all())) {
  62. html += this.tmpl("sidebarDoc", doc, {
  63. fullName: app.docs.countAllBy("name", doc.name) > 1,
  64. });
  65. }
  66. this.html(html);
  67. if (!app.isSingleDoc() && app.disabledDocs.size() !== 0) {
  68. this.renderDisabled();
  69. }
  70. }
  71. renderDisabled() {
  72. this.append(
  73. this.tmpl("sidebarDisabled", { count: app.disabledDocs.size() }),
  74. );
  75. this.refreshElements();
  76. this.renderDisabledList();
  77. }
  78. renderDisabledList() {
  79. if (app.settings.get("hideDisabled")) {
  80. this.removeDisabledList();
  81. } else {
  82. this.appendDisabledList();
  83. }
  84. }
  85. appendDisabledList() {
  86. let doc;
  87. let html = "";
  88. const docs = [].concat(...Array.from(app.disabledDocs.all() || []));
  89. while ((doc = docs.shift())) {
  90. if (doc.version != null) {
  91. var versions = "";
  92. while (true) {
  93. versions += this.tmpl("sidebarDoc", doc, { disabled: true });
  94. if ((docs[0] != null ? docs[0].name : undefined) !== doc.name) {
  95. break;
  96. }
  97. doc = docs.shift();
  98. }
  99. html += this.tmpl("sidebarDisabledVersionedDoc", doc, versions);
  100. } else {
  101. html += this.tmpl("sidebarDoc", doc, { disabled: true });
  102. }
  103. }
  104. this.append(this.tmpl("sidebarDisabledList", html));
  105. this.disabledTitle.classList.add("open-title");
  106. this.refreshElements();
  107. }
  108. removeDisabledList() {
  109. if (this.disabledList) {
  110. $.remove(this.disabledList);
  111. }
  112. this.disabledTitle.classList.remove("open-title");
  113. this.refreshElements();
  114. }
  115. reset(options) {
  116. if (options == null) {
  117. options = {};
  118. }
  119. this.listSelect.deselect();
  120. if (this.listFocus != null) {
  121. this.listFocus.blur();
  122. }
  123. this.listFold.reset();
  124. if (options.revealCurrent || app.isSingleDoc()) {
  125. this.revealCurrent();
  126. }
  127. }
  128. onOpen(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] = doc.types.isEmpty()
  133. ? new app.views.EntryList(doc.entries.all())
  134. : new app.views.TypeList(doc);
  135. $.after(event.target, this.lists[doc.slug].el);
  136. }
  137. }
  138. onClose(event) {
  139. $.stopEvent(event);
  140. const doc = app.docs.findBy("slug", event.target.getAttribute("data-slug"));
  141. if (doc && this.lists[doc.slug]) {
  142. this.lists[doc.slug].detach();
  143. delete this.lists[doc.slug];
  144. }
  145. }
  146. select(model) {
  147. this.listSelect.selectByHref(model != null ? model.fullPath() : undefined);
  148. }
  149. reveal(model) {
  150. this.openDoc(model.doc);
  151. if (model.type) {
  152. this.openType(model.getType());
  153. }
  154. this.focus(model);
  155. this.paginateTo(model);
  156. this.scrollTo(model);
  157. }
  158. focus(model) {
  159. if (this.listFocus != null) {
  160. this.listFocus.focus(this.find(`a[href='${model.fullPath()}']`));
  161. }
  162. }
  163. revealCurrent() {
  164. let model;
  165. if ((model = app.router.context.type || app.router.context.entry)) {
  166. this.reveal(model);
  167. this.select(model);
  168. }
  169. }
  170. openDoc(doc) {
  171. if (app.disabledDocs.contains(doc) && doc.version) {
  172. this.listFold.open(
  173. this.find(`[data-slug='${doc.slug_without_version}']`),
  174. );
  175. }
  176. this.listFold.open(this.find(`[data-slug='${doc.slug}']`));
  177. }
  178. closeDoc(doc) {
  179. this.listFold.close(this.find(`[data-slug='${doc.slug}']`));
  180. }
  181. openType(type) {
  182. this.listFold.open(
  183. this.lists[type.doc.slug].find(`[data-slug='${type.slug}']`),
  184. );
  185. }
  186. paginateTo(model) {
  187. if (this.lists[model.doc.slug] != null) {
  188. this.lists[model.doc.slug].paginateTo(model);
  189. }
  190. }
  191. scrollTo(model) {
  192. $.scrollTo(this.find(`a[href='${model.fullPath()}']`), null, "top", {
  193. margin: app.isMobile() ? 48 : 0,
  194. });
  195. }
  196. toggleDisabled() {
  197. if (this.disabledTitle.classList.contains("open-title")) {
  198. this.removeDisabledList();
  199. app.settings.set("hideDisabled", true);
  200. } else {
  201. this.appendDisabledList();
  202. app.settings.set("hideDisabled", false);
  203. }
  204. }
  205. onClick(event) {
  206. let slug;
  207. const target = $.eventTarget(event);
  208. if (
  209. this.disabledTitle &&
  210. $.hasChild(this.disabledTitle, target) &&
  211. target.tagName !== "A"
  212. ) {
  213. $.stopEvent(event);
  214. this.toggleDisabled();
  215. } else if ((slug = target.getAttribute("data-enable"))) {
  216. $.stopEvent(event);
  217. const doc = app.disabledDocs.findBy("slug", slug);
  218. if (doc) {
  219. app.enableDoc(doc, this.onEnabled, this.onEnabled);
  220. }
  221. }
  222. }
  223. onEnabled() {
  224. this.reset();
  225. this.render();
  226. }
  227. afterRoute(route, context) {
  228. if (context.init) {
  229. if (this.activated) {
  230. this.reset({ revealCurrent: true });
  231. }
  232. } else {
  233. this.select(context.type || context.entry);
  234. }
  235. }
  236. };
  237. app.views.DocList.initClass();