view.js 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  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. * DS102: Remove unnecessary code created because of implicit returns
  7. * DS207: Consider shorter variations of null checks
  8. * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md
  9. */
  10. app.View = class View extends Events {
  11. constructor(el) {
  12. super();
  13. if (el instanceof HTMLElement) {
  14. this.el = el;
  15. }
  16. this.setupElement();
  17. if (this.el.className) {
  18. this.originalClassName = this.el.className;
  19. }
  20. if (this.constructor.className) {
  21. this.resetClass();
  22. }
  23. this.refreshElements();
  24. if (typeof this.init === "function") {
  25. this.init();
  26. this.refreshElements();
  27. }
  28. }
  29. setupElement() {
  30. if (this.el == null) {
  31. this.el =
  32. typeof this.constructor.el === "string"
  33. ? $(this.constructor.el)
  34. : this.constructor.el
  35. ? this.constructor.el
  36. : document.createElement(this.constructor.tagName || "div");
  37. }
  38. if (this.constructor.attributes) {
  39. for (var key in this.constructor.attributes) {
  40. var value = this.constructor.attributes[key];
  41. this.el.setAttribute(key, value);
  42. }
  43. }
  44. }
  45. refreshElements() {
  46. if (this.constructor.elements) {
  47. for (var name in this.constructor.elements) {
  48. var selector = this.constructor.elements[name];
  49. this[name] = this.find(selector);
  50. }
  51. }
  52. }
  53. addClass(name) {
  54. this.el.classList.add(name);
  55. }
  56. removeClass(name) {
  57. this.el.classList.remove(name);
  58. }
  59. toggleClass(name) {
  60. this.el.classList.toggle(name);
  61. }
  62. hasClass(name) {
  63. return this.el.classList.contains(name);
  64. }
  65. resetClass() {
  66. this.el.className = this.originalClassName || "";
  67. if (this.constructor.className) {
  68. for (var name of Array.from(this.constructor.className.split(" "))) {
  69. this.addClass(name);
  70. }
  71. }
  72. }
  73. find(selector) {
  74. return $(selector, this.el);
  75. }
  76. findAll(selector) {
  77. return $$(selector, this.el);
  78. }
  79. findByClass(name) {
  80. return this.findAllByClass(name)[0];
  81. }
  82. findLastByClass(name) {
  83. const all = this.findAllByClass(name)[0];
  84. return all[all.length - 1];
  85. }
  86. findAllByClass(name) {
  87. return this.el.getElementsByClassName(name);
  88. }
  89. findByTag(tag) {
  90. return this.findAllByTag(tag)[0];
  91. }
  92. findLastByTag(tag) {
  93. const all = this.findAllByTag(tag);
  94. return all[all.length - 1];
  95. }
  96. findAllByTag(tag) {
  97. return this.el.getElementsByTagName(tag);
  98. }
  99. append(value) {
  100. $.append(this.el, value.el || value);
  101. }
  102. appendTo(value) {
  103. $.append(value.el || value, this.el);
  104. }
  105. prepend(value) {
  106. $.prepend(this.el, value.el || value);
  107. }
  108. prependTo(value) {
  109. $.prepend(value.el || value, this.el);
  110. }
  111. before(value) {
  112. $.before(this.el, value.el || value);
  113. }
  114. after(value) {
  115. $.after(this.el, value.el || value);
  116. }
  117. remove(value) {
  118. $.remove(value.el || value);
  119. }
  120. empty() {
  121. $.empty(this.el);
  122. this.refreshElements();
  123. }
  124. html(value) {
  125. this.empty();
  126. this.append(value);
  127. }
  128. tmpl(...args) {
  129. return app.templates.render(...Array.from(args || []));
  130. }
  131. delay(fn, ...args) {
  132. const delay = typeof args[args.length - 1] === "number" ? args.pop() : 0;
  133. return setTimeout(fn.bind(this, ...Array.from(args)), delay);
  134. }
  135. onDOM(event, callback) {
  136. $.on(this.el, event, callback);
  137. }
  138. offDOM(event, callback) {
  139. $.off(this.el, event, callback);
  140. }
  141. bindEvents() {
  142. let method, name;
  143. if (this.constructor.events) {
  144. for (name in this.constructor.events) {
  145. method = this.constructor.events[name];
  146. this[method] = this[method].bind(this);
  147. this.onDOM(name, this[method]);
  148. }
  149. }
  150. if (this.constructor.routes) {
  151. for (name in this.constructor.routes) {
  152. method = this.constructor.routes[name];
  153. this[method] = this[method].bind(this);
  154. app.router.on(name, this[method]);
  155. }
  156. }
  157. if (this.constructor.shortcuts) {
  158. for (name in this.constructor.shortcuts) {
  159. method = this.constructor.shortcuts[name];
  160. this[method] = this[method].bind(this);
  161. app.shortcuts.on(name, this[method]);
  162. }
  163. }
  164. }
  165. unbindEvents() {
  166. let method, name;
  167. if (this.constructor.events) {
  168. for (name in this.constructor.events) {
  169. method = this.constructor.events[name];
  170. this.offDOM(name, this[method]);
  171. }
  172. }
  173. if (this.constructor.routes) {
  174. for (name in this.constructor.routes) {
  175. method = this.constructor.routes[name];
  176. app.router.off(name, this[method]);
  177. }
  178. }
  179. if (this.constructor.shortcuts) {
  180. for (name in this.constructor.shortcuts) {
  181. method = this.constructor.shortcuts[name];
  182. app.shortcuts.off(name, this[method]);
  183. }
  184. }
  185. }
  186. addSubview(view) {
  187. return (this.subviews || (this.subviews = [])).push(view);
  188. }
  189. activate() {
  190. if (this.activated) {
  191. return;
  192. }
  193. this.bindEvents();
  194. if (this.subviews) {
  195. for (var view of Array.from(this.subviews)) {
  196. view.activate();
  197. }
  198. }
  199. this.activated = true;
  200. return true;
  201. }
  202. deactivate() {
  203. if (!this.activated) {
  204. return;
  205. }
  206. this.unbindEvents();
  207. if (this.subviews) {
  208. for (var view of Array.from(this.subviews)) {
  209. view.deactivate();
  210. }
  211. }
  212. this.activated = false;
  213. return true;
  214. }
  215. detach() {
  216. this.deactivate();
  217. $.remove(this.el);
  218. }
  219. };