MediaWiki:Common.js: Difference between revisions

From WikiMSK

No edit summary
No edit summary
Line 13: Line 13:
$('document').ready(function() {
$('document').ready(function() {
   // Get all the <h2> headings
   // Get all the <h2> headings
   const headings = document.querySelectorAll('.mw-parser-output h2');
   const headings = document.querySelectorAll('.mw-parser-output h2')
    
    
   Array.prototype.forEach.call(headings, heading => {
   Array.prototype.forEach.call(headings, heading => {
Line 26: Line 26:
         </svg>
         </svg>
       </button>
       </button>
     `;
     `
      
      
     // Function to create a node list  
     // Function to create a node list  
     // of the content between this <h2> and the next
     // of the content between this <h2> and the next
     const getContent = (elem) => {
     const getContent = (elem) => {
       let elems = [];
       let elems = []
       while (elem.nextElementSibling && elem.nextElementSibling.tagName !== 'H2') {
       while (elem.nextElementSibling && elem.nextElementSibling.tagName !== 'H2') {
         elems.push(elem.nextElementSibling);
         elems.push(elem.nextElementSibling)
         elem = elem.nextElementSibling;
         elem = elem.nextElementSibling
       }
       }
        
        
       // Delete the old versions of the content nodes
       // Delete the old versions of the content nodes
       elems.forEach((node) => {
       elems.forEach((node) => {
         node.parentNode.removeChild(node);
         node.parentNode.removeChild(node)
       });
       })


       return elems;
       return elems
     };
     }
      
      
     // Assign the contents to be expanded/collapsed (array)
     // Assign the contents to be expanded/collapsed (array)
     let contents = getContent(heading);
     let contents = getContent(heading)
      
      
     // Create a wrapper element for `contents` and hide it
     // Create a wrapper element for `contents` and hide it
     let wrapper = document.createElement('div');
     let wrapper = document.createElement('div')
     wrapper.hidden = true;
     wrapper.hidden = true
      
      
     // Add each element of `contents` to `wrapper`
     // Add each element of `contents` to `wrapper`
     contents.forEach(node => {
     contents.forEach(node => {
       wrapper.appendChild(node);
       wrapper.appendChild(node)
     });
     })
      
      
     // Add the wrapped content back into the DOM  
     // Add the wrapped content back into the DOM  
     // after the heading
     // after the heading
     heading.parentNode.insertBefore(wrapper, heading.nextElementSibling);
     heading.parentNode.insertBefore(wrapper, heading.nextElementSibling)
      
      
     // Assign the button
     // Assign the button
     let btn = heading.querySelector('button');
     let btn = heading.querySelector('button')
      
      
     btn.onclick = () => {
     btn.onclick = () => {
       // Cast the state as a boolean
       // Cast the state as a boolean
       let expanded = btn.getAttribute('aria-expanded') === 'true' || false;
       let expanded = btn.getAttribute('aria-expanded') === 'true' || false
        
        
       // Switch the state
       // Switch the state
       btn.setAttribute('aria-expanded', !expanded);
       btn.setAttribute('aria-expanded', !expanded)
       // Switch the content's visibility
       // Switch the content's visibility
       wrapper.hidden = expanded   ;
       wrapper.hidden = expanded  
     };
     }
   });
   })
})();
})()

Revision as of 08:12, 22 August 2020

/* Any JavaScript here will be loaded for all users on every page load. */

function docReady(fn) {
    // see if DOM is already available
    if (document.readyState === "complete" || document.readyState === "interactive") {
        // call on next available tick
        setTimeout(fn, 1);
    } else {
        document.addEventListener("DOMContentLoaded", fn);
    }
}    

$('document').ready(function() {
  // Get all the <h2> headings
  const headings = document.querySelectorAll('.mw-parser-output h2')
  
  Array.prototype.forEach.call(headings, heading => {
    // Give each <h2> a toggle button child
    // with the SVG plus/minus icon
    heading.innerHTML = `
      <button aria-expanded="false">
        ${heading.textContent}
        <svg aria-hidden="true" focusable="false" viewBox="0 0 10 10">
          <rect class="vert" height="8" width="2" y="1" x="4"/>
          <rect height="2" width="8" y="4" x="1"/>
        </svg>
      </button>
    `
    
    // Function to create a node list 
    // of the content between this <h2> and the next
    const getContent = (elem) => {
      let elems = []
      while (elem.nextElementSibling && elem.nextElementSibling.tagName !== 'H2') {
        elems.push(elem.nextElementSibling)
        elem = elem.nextElementSibling
      }
      
      // Delete the old versions of the content nodes
      elems.forEach((node) => {
        node.parentNode.removeChild(node)
      })

      return elems
    }
    
    // Assign the contents to be expanded/collapsed (array)
    let contents = getContent(heading)
    
    // Create a wrapper element for `contents` and hide it
    let wrapper = document.createElement('div')
    wrapper.hidden = true
    
    // Add each element of `contents` to `wrapper`
    contents.forEach(node => {
      wrapper.appendChild(node)
    })
    
    // Add the wrapped content back into the DOM 
    // after the heading
    heading.parentNode.insertBefore(wrapper, heading.nextElementSibling)
    
    // Assign the button
    let btn = heading.querySelector('button')
    
    btn.onclick = () => {
      // Cast the state as a boolean
      let expanded = btn.getAttribute('aria-expanded') === 'true' || false
      
      // Switch the state
      btn.setAttribute('aria-expanded', !expanded)
      // Switch the content's visibility
      wrapper.hidden = expanded    
    }
  })
})()