func.js 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. "use strict";
  2. // https://css-tricks.com/how-to-animate-the-details-element/
  3. class Accordion {
  4. constructor(el) {
  5. this.el = el;
  6. this.summary = el.querySelector('summary');
  7. this.content = el.querySelector('.opennamu_folding');
  8. this.animation = null;
  9. this.isClosing = false;
  10. this.isExpanding = false;
  11. this.summary.addEventListener('click', (e) => this.onClick(e));
  12. }
  13. onClick(e) {
  14. e.preventDefault();
  15. this.el.style.overflow = 'hidden';
  16. if(this.isClosing || !this.el.open) {
  17. this.open();
  18. } else if(this.isExpanding || this.el.open) {
  19. this.shrink();
  20. }
  21. }
  22. shrink() {
  23. this.isClosing = true;
  24. const startHeight = `${this.el.offsetHeight}px`;
  25. const endHeight = `${this.summary.offsetHeight}px`;
  26. if(this.animation) {
  27. this.animation.cancel();
  28. }
  29. this.animation = this.el.animate({
  30. height: [startHeight, endHeight]
  31. }, {
  32. duration: 200,
  33. easing: 'ease-out'
  34. });
  35. this.animation.onfinish = () => this.onAnimationFinish(false);
  36. this.animation.oncancel = () => this.isClosing = false;
  37. }
  38. open() {
  39. this.el.style.height = `${this.el.offsetHeight}px`;
  40. this.el.open = true;
  41. window.requestAnimationFrame(() => this.expand());
  42. }
  43. expand() {
  44. this.isExpanding = true;
  45. const startHeight = `${this.el.offsetHeight}px`;
  46. const endHeight = `${this.summary.offsetHeight + this.content.offsetHeight}px`;
  47. if(this.animation) {
  48. this.animation.cancel();
  49. }
  50. this.animation = this.el.animate({
  51. height: [startHeight, endHeight]
  52. }, {
  53. duration: 200,
  54. easing: 'ease-out'
  55. });
  56. this.animation.onfinish = () => this.onAnimationFinish(true);
  57. this.animation.oncancel = () => this.isExpanding = false;
  58. }
  59. onAnimationFinish(open) {
  60. this.el.open = open;
  61. this.animation = null;
  62. this.isClosing = false;
  63. this.isExpanding = false;
  64. this.el.style.height = this.el.style.overflow = '';
  65. }
  66. }
  67. function opennamu_do_id_check(data) {
  68. if(data.match(/\.|\:/)) {
  69. return 0;
  70. } else {
  71. return 1;
  72. }
  73. }
  74. function opennamu_do_url_encode(data) {
  75. return encodeURIComponent(data);
  76. }
  77. function opennamu_cookie_split_regex(data) {
  78. return new RegExp('(?:^|; )' + data + '=([^;]*)');
  79. }
  80. function opennamu_get_main_skin_set(set_name) {
  81. return fetch("/api/setting/" + opennamu_do_url_encode(set_name)).then(function(res) {
  82. return res.json();
  83. }).then(function(text) {
  84. if(
  85. document.cookie.match(opennamu_cookie_split_regex(set_name)) &&
  86. document.cookie.match(opennamu_cookie_split_regex(set_name))[1] !== '' &&
  87. document.cookie.match(opennamu_cookie_split_regex(set_name))[1] !== 'default'
  88. ) {
  89. return document.cookie.match(opennamu_cookie_split_regex(set_name))[1];
  90. } else {
  91. if(text[set_name]) {
  92. return text[set_name][0][0];
  93. } else {
  94. return '';
  95. }
  96. }
  97. });
  98. }
  99. function opennamu_insert_v(name, data) {
  100. document.getElementById(name).value = data;
  101. }
  102. function opennamu_do_trace_spread() {
  103. if(document.getElementsByClassName('opennamu_trace')) {
  104. document.getElementsByClassName('opennamu_trace')[0].innerHTML = '' +
  105. '<style>.opennamu_trace_button { display: none; } .opennamu_trace { white-space: pre-wrap; overflow-x: unset; text-overflow: unset; }</style>' +
  106. '' + document.getElementsByClassName('opennamu_trace')[0].innerHTML
  107. }
  108. }
  109. function opennamu_do_render(to_obj, data, name = '', do_type = '', option = '') {
  110. let url;
  111. if(do_type === '') {
  112. url = "/api/render";
  113. } else {
  114. url = "/api/render/" + do_type;
  115. }
  116. fetch(url, {
  117. method : 'POST',
  118. headers : { 'Content-Type': 'application/x-www-form-urlencoded' },
  119. body : new URLSearchParams({
  120. 'name' : name,
  121. 'data': data,
  122. 'option' : option
  123. })
  124. }).then(function(res) {
  125. return res.json();
  126. }).then(function(text) {
  127. if(document.getElementById(to_obj)) {
  128. if(text["data"]) {
  129. document.getElementById(to_obj).innerHTML = text.data;
  130. eval(text.js_data);
  131. } else {
  132. document.getElementById(to_obj).innerHTML = '';
  133. }
  134. }
  135. });
  136. }
  137. function opennamu_xss_filter(str) {
  138. return str.replace(/[&<>"'\/]/g, function(match) {
  139. switch(match) {
  140. case '&':
  141. return '&amp;';
  142. case '<':
  143. return '&lt;';
  144. case '>':
  145. return '&gt;';
  146. case "'":
  147. return '&#x27;';
  148. case '"':
  149. return '&quot;';
  150. case '/':
  151. return '&#x2F;';
  152. }
  153. });
  154. }