"use strict"; // https://css-tricks.com/how-to-animate-the-details-element/ class Accordion { constructor(el) { // Store the
element this.el = el; // Store the element this.summary = el.querySelector('summary'); // Store the
element this.content = el.querySelector('.opennamu_folding'); // Store the animation object (so we can cancel it if needed) this.animation = null; // Store if the element is closing this.isClosing = false; // Store if the element is expanding this.isExpanding = false; // Detect user clicks on the summary element this.summary.addEventListener('click', (e) => this.onClick(e)); } onClick(e) { // Stop default behaviour from the browser e.preventDefault(); // Add an overflow on the
to avoid content overflowing this.el.style.overflow = 'hidden'; // Check if the element is being closed or is already closed if(this.isClosing || !this.el.open) { this.open(); // Check if the element is being openned or is already open } else if(this.isExpanding || this.el.open) { this.shrink(); } } shrink() { // Set the element as "being closed" this.isClosing = true; // Store the current height of the element const startHeight = `${this.el.offsetHeight}px`; // Calculate the height of the summary const endHeight = `${this.summary.offsetHeight}px`; // If there is already an animation running if(this.animation) { // Cancel the current animation this.animation.cancel(); } // Start a WAAPI animation this.animation = this.el.animate({ // Set the keyframes from the startHeight to endHeight height: [startHeight, endHeight] }, { duration: 200, easing: 'ease-out' }); // When the animation is complete, call onAnimationFinish() this.animation.onfinish = () => this.onAnimationFinish(false); // If the animation is cancelled, isClosing variable is set to false this.animation.oncancel = () => this.isClosing = false; } open() { // Apply a fixed height on the element this.el.style.height = `${this.el.offsetHeight}px`; // Force the [open] attribute on the details element this.el.open = true; // Wait for the next frame to call the expand function window.requestAnimationFrame(() => this.expand()); } expand() { // Set the element as "being expanding" this.isExpanding = true; // Get the current fixed height of the element const startHeight = `${this.el.offsetHeight}px`; // Calculate the open height of the element (summary height + content height) const endHeight = `${this.summary.offsetHeight + this.content.offsetHeight}px`; // If there is already an animation running if(this.animation) { // Cancel the current animation this.animation.cancel(); } // Start a WAAPI animation this.animation = this.el.animate({ // Set the keyframes from the startHeight to endHeight height: [startHeight, endHeight] }, { duration: 200, easing: 'ease-out' }); // When the animation is complete, call onAnimationFinish() this.animation.onfinish = () => this.onAnimationFinish(true); // If the animation is cancelled, isExpanding variable is set to false this.animation.oncancel = () => this.isExpanding = false; } onAnimationFinish(open) { // Set the open attribute based on the parameter this.el.open = open; // Clear the stored animation this.animation = null; // Reset isClosing & isExpanding this.isClosing = false; this.isExpanding = false; // Remove the overflow hidden and the fixed height this.el.style.height = this.el.style.overflow = ''; } } window.addEventListener('DOMContentLoaded', function() { document.querySelectorAll('details').forEach((el) => { new Accordion(el); }); }); function opennamu_do_id_check(data) { if(data.match(/\.|\:/)) { return 0; } else { return 1; } } function opennamu_do_url_encode(data) { return encodeURIComponent(data); } function opennamu_cookie_split_regex(data) { return new RegExp('(?:^|; )' + data + '=([^;]*)'); } function opennamu_get_main_skin_set(set_name) { return fetch("/api/setting/" + opennamu_do_url_encode(set_name)).then(function(res) { return res.json(); }).then(function(text) { if( document.cookie.match(opennamu_cookie_split_regex(set_name)) && document.cookie.match(opennamu_cookie_split_regex(set_name))[1] !== '' && document.cookie.match(opennamu_cookie_split_regex(set_name))[1] !== 'default' ) { return document.cookie.match(opennamu_cookie_split_regex(set_name))[1]; } else { if(text[set_name]) { return text[set_name][0][0]; } else { return ''; } } }); } function opennamu_insert_v(name, data) { document.getElementById(name).value = data; }