view.js 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  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. * 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.View = class View {
  12. static initClass() {
  13. $.extend(this.prototype, Events);
  14. }
  15. constructor() {
  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. }
  27. this.refreshElements();
  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.onDOM(name, this[method]);
  147. }
  148. }
  149. if (this.constructor.routes) {
  150. for (name in this.constructor.routes) {
  151. method = this.constructor.routes[name];
  152. app.router.on(name, this[method]);
  153. }
  154. }
  155. if (this.constructor.shortcuts) {
  156. for (name in this.constructor.shortcuts) {
  157. method = this.constructor.shortcuts[name];
  158. app.shortcuts.on(name, this[method]);
  159. }
  160. }
  161. }
  162. unbindEvents() {
  163. let method, name;
  164. if (this.constructor.events) {
  165. for (name in this.constructor.events) {
  166. method = this.constructor.events[name];
  167. this.offDOM(name, this[method]);
  168. }
  169. }
  170. if (this.constructor.routes) {
  171. for (name in this.constructor.routes) {
  172. method = this.constructor.routes[name];
  173. app.router.off(name, this[method]);
  174. }
  175. }
  176. if (this.constructor.shortcuts) {
  177. for (name in this.constructor.shortcuts) {
  178. method = this.constructor.shortcuts[name];
  179. app.shortcuts.off(name, this[method]);
  180. }
  181. }
  182. }
  183. addSubview(view) {
  184. return (this.subviews || (this.subviews = [])).push(view);
  185. }
  186. activate() {
  187. if (this.activated) {
  188. return;
  189. }
  190. this.bindEvents();
  191. if (this.subviews) {
  192. for (var view of Array.from(this.subviews)) {
  193. view.activate();
  194. }
  195. }
  196. this.activated = true;
  197. return true;
  198. }
  199. deactivate() {
  200. if (!this.activated) {
  201. return;
  202. }
  203. this.unbindEvents();
  204. if (this.subviews) {
  205. for (var view of Array.from(this.subviews)) {
  206. view.deactivate();
  207. }
  208. }
  209. this.activated = false;
  210. return true;
  211. }
  212. detach() {
  213. this.deactivate();
  214. $.remove(this.el);
  215. }
  216. };
  217. app.View.initClass();