func.js 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  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. window.addEventListener('DOMContentLoaded', function() {
  68. document.querySelectorAll('details').forEach((el) => {
  69. new Accordion(el);
  70. });
  71. });
  72. function opennamu_do_id_check(data) {
  73. if(data.match(/\.|\:/)) {
  74. return 0;
  75. } else {
  76. return 1;
  77. }
  78. }
  79. function opennamu_do_url_encode(data) {
  80. return encodeURIComponent(data);
  81. }
  82. function opennamu_cookie_split_regex(data) {
  83. return new RegExp('(?:^|; )' + data + '=([^;]*)');
  84. }
  85. function opennamu_get_main_skin_set(set_name) {
  86. return fetch("/api/setting/" + opennamu_do_url_encode(set_name)).then(function(res) {
  87. return res.json();
  88. }).then(function(text) {
  89. if(
  90. document.cookie.match(opennamu_cookie_split_regex(set_name)) &&
  91. document.cookie.match(opennamu_cookie_split_regex(set_name))[1] !== '' &&
  92. document.cookie.match(opennamu_cookie_split_regex(set_name))[1] !== 'default'
  93. ) {
  94. return document.cookie.match(opennamu_cookie_split_regex(set_name))[1];
  95. } else {
  96. if(text[set_name]) {
  97. return text[set_name][0][0];
  98. } else {
  99. return '';
  100. }
  101. }
  102. });
  103. }
  104. function opennamu_insert_v(name, data) {
  105. document.getElementById(name).value = data;
  106. }
  107. function opennamu_do_trace_spread() {
  108. if(document.getElementsByClassName('opennamu_trace')) {
  109. document.getElementsByClassName('opennamu_trace')[0].innerHTML = '' +
  110. '<style>.opennamu_trace_button { display: none; } .opennamu_trace { white-space: pre-wrap; overflow-x: unset; text-overflow: unset; }</style>' +
  111. '' + document.getElementsByClassName('opennamu_trace')[0].innerHTML
  112. }
  113. }
  114. function opennamu_do_render(to_obj, name, data, do_type = '') {
  115. let url;
  116. if(do_type === '') {
  117. url = "/api/render/" + opennamu_do_url_encode(name);
  118. } else {
  119. url = "/api/render_tool/thread/" + opennamu_do_url_encode(name);
  120. }
  121. fetch(url, {
  122. method : 'POST',
  123. headers : { 'Content-Type': 'application/x-www-form-urlencoded' },
  124. body : new URLSearchParams({
  125. 'data': data,
  126. })
  127. }).then(function(res) {
  128. return res.json();
  129. }).then(function(text) {
  130. if(document.getElementById(to_obj)) {
  131. if(text["data"]) {
  132. document.getElementById(to_obj).innerHTML = text.data;
  133. eval(text.js_data);
  134. } else {
  135. document.getElementById(to_obj).innerHTML = '';
  136. }
  137. }
  138. });
  139. }