list_fold.js 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. app.views.ListFold = class ListFold extends app.View {
  2. static targetClass = "_list-dir";
  3. static handleClass = "_list-arrow";
  4. static activeClass = "open";
  5. static events = { click: "onClick" };
  6. static shortcuts = {
  7. left: "onLeft",
  8. right: "onRight",
  9. };
  10. open(el) {
  11. if (el && !el.classList.contains(this.constructor.activeClass)) {
  12. el.classList.add(this.constructor.activeClass);
  13. $.trigger(el, "open");
  14. }
  15. }
  16. close(el) {
  17. if (el && el.classList.contains(this.constructor.activeClass)) {
  18. el.classList.remove(this.constructor.activeClass);
  19. $.trigger(el, "close");
  20. }
  21. }
  22. toggle(el) {
  23. if (el.classList.contains(this.constructor.activeClass)) {
  24. this.close(el);
  25. } else {
  26. this.open(el);
  27. }
  28. }
  29. reset() {
  30. let el;
  31. while ((el = this.findByClass(this.constructor.activeClass))) {
  32. this.close(el);
  33. }
  34. }
  35. getCursor() {
  36. return (
  37. this.findByClass(app.views.ListFocus.activeClass) ||
  38. this.findByClass(app.views.ListSelect.activeClass)
  39. );
  40. }
  41. onLeft() {
  42. const cursor = this.getCursor();
  43. if (cursor?.classList?.contains(this.constructor.activeClass)) {
  44. this.close(cursor);
  45. }
  46. }
  47. onRight() {
  48. const cursor = this.getCursor();
  49. if (
  50. cursor != null
  51. ? cursor.classList.contains(this.constructor.targetClass)
  52. : undefined
  53. ) {
  54. this.open(cursor);
  55. }
  56. }
  57. onClick(event) {
  58. if (event.which !== 1 || event.metaKey || event.ctrlKey) {
  59. return;
  60. }
  61. if (!event.pageY) {
  62. return;
  63. } // ignore fabricated clicks
  64. let el = $.eventTarget(event);
  65. if (el.parentNode.tagName.toUpperCase() === "SVG") {
  66. el = el.parentNode;
  67. }
  68. if (el.classList.contains(this.constructor.handleClass)) {
  69. $.stopEvent(event);
  70. this.toggle(el.parentNode);
  71. } else if (el.classList.contains(this.constructor.targetClass)) {
  72. if (el.hasAttribute("href")) {
  73. if (el.classList.contains(this.constructor.activeClass)) {
  74. if (el.classList.contains(app.views.ListSelect.activeClass)) {
  75. this.close(el);
  76. }
  77. } else {
  78. this.open(el);
  79. }
  80. } else {
  81. this.toggle(el);
  82. }
  83. }
  84. }
  85. };