|
|
@@ -1,5 +1,125 @@
|
|
|
"use strict";
|
|
|
|
|
|
+// https://css-tricks.com/how-to-animate-the-details-element/
|
|
|
+class Accordion {
|
|
|
+ constructor(el) {
|
|
|
+ // Store the <details> element
|
|
|
+ this.el = el;
|
|
|
+ // Store the <summary> element
|
|
|
+ this.summary = el.querySelector('summary');
|
|
|
+ // Store the <div class="content"> 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 <details> 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;
|