MediaWiki: Common.js: Difference between revisions

From Psalms: Layer by Layer
Jump to: navigation, search
mNo edit summary
mNo edit summary
Line 1: Line 1:
/* Any JavaScript here will be loaded for all users on every page load. */
/* Any JavaScript here will be loaded for all users on every page load. */
// Function to check if all <pre class="mermaid"> elements are processed
function checkMermaidProcessed() {
    var mermaidPreElements = document.querySelectorAll('pre.mermaid');
    var allProcessed = true;
    mermaidPreElements.forEach(function (element) {
        if (!element.hasAttribute('data-processed') || element.getAttribute('data-processed') !== 'true') {
            allProcessed = false;
        }
    });
    return allProcessed;
}
// Function to wait until all Mermaid diagrams are processed
function waitForMermaidProcessing(callback) {
    var interval = setInterval(function () {
        if (checkMermaidProcessed()) {
            clearInterval(interval);
            callback(); // Once all elements are processed, run the callback
        }
    }, 100); // Check every 100ms
}


function toggleVisibility(containerId, className) {
function toggleVisibility(containerId, className) {
     console.log("Toggling visibility for " + className + " in " + containerId);
     //console.log("Toggling visibility for " + className + " in " + containerId);
     var container = document.getElementById(containerId);
     var container = document.getElementById(containerId);
     if (container) {
     if (container) {
Line 21: Line 45:


function attachToggleListeners() {
function attachToggleListeners() {
     // Attach event listeners to all toggle links
     //console.log("Attaching event listeners to toggle links.");
     var toggleLinks = document.querySelectorAll("[data-container-id][data-class]");
     var toggleLinks = document.querySelectorAll("[data-container-id][data-class]");
     // console.log("Found " + toggleLinks.length + " links.");
     //console.log("Found " + toggleLinks.length + " links.");
 
    // If no toggle links are found, print a warning
    if (toggleLinks.length === 0) {
        console.warn("No toggle links found on the page.");
    }
   
     for (var i = 0; i < toggleLinks.length; i++) {
     for (var i = 0; i < toggleLinks.length; i++) {
         (function (toggleLink) {
         (function (toggleLink) {
Line 36: Line 66:
}
}


// ===========================


(function () {
    if (document.readyState === "complete" || document.readyState === "interactive") {
        // console.log("ReadyState is complete.");


        // if the document has already been loaded
$(document).ready(function () {
        attachToggleListeners();
    //console.log("Document ready. Attaching event listeners to toggle links.");
        document.querySelectorAll(".highlight-phrase").forEach(function (element) {
                element.style.display = "none"; // Hide elements initially
    });               
       
    } else {
        console.log("ReadyState is " + document.readyState);


        document.addEventListener("DOMContentLoaded", function () {
    // Now attach event listeners for toggling visibility
    attachToggleListeners();


            // if the document has already been loaded
    // Wait until all Mermaid diagrams are processed
            attachToggleListeners();
    waitForMermaidProcessing(function () {
         });
         //console.log("Mermaid diagrams are fully processed.");
    }


})();
         $('div[id^="verse-"]').each(function () {
// console.log("Common.js is loaded.");
             var parentDiv = $(this);
 
 
// ---------------------------------------------------------------------
 
$(document).ready(function() {
    // Wait for 5 seconds for Mermaid to render all svgs on the page
    setTimeout(function() {
        // Iterate through each <div> containing the button and SVG
         $('div[id^="verse-"]').each(function() {
             var parentDiv = $(this); // The parent div that contains the button and <pre class="mermaid">
             var svg = parentDiv.find('svg');
             var svg = parentDiv.find('svg');
             var panZoomInstance;
             var panZoomInstance;
Line 93: Line 105:
                     });
                     });


                    // Initialize svg-pan-zoom instance
                     panZoomInstance = svgPanZoom(svg[0], {
                     panZoomInstance = svgPanZoom(svg[0], {
                         panEnabled: true,
                         panEnabled: true,
Line 104: Line 115:
                     });
                     });


                     // For resizing the SVG on window resize
                     // Resize handler to keep SVG scaled on window resize
                     var resizeHandler = function() {
                     var resizeHandler = function () {
                         var newWidth = preElement.width();
                         var newWidth = preElement.width();
                         var newHeight = preElement.height();
                         var newHeight = preElement.height();
                         console.log('pre.mermaid container resized to: ', newWidth, newHeight);
                         //console.log('pre.mermaid container resized to: ', newWidth, newHeight);


                         var newScaleX = newWidth / viewBoxWidth;
                         var newScaleX = newWidth / viewBoxWidth;
Line 118: Line 129:
                             'max-width': (newWidth) + 'px'
                             'max-width': (newWidth) + 'px'
                             //'height': (viewBoxHeight * newScale) + 'px'
                             //'height': (viewBoxHeight * newScale) + 'px'
                            // Do not change the height to avoid reflowing the html page
                         });
                         });


Line 124: Line 136:
                         }
                         }
                     };
                     };
 
                   
                     // Listen for resize events
                     // Listen for resize events
                     $(window).on('resize', resizeHandler);
                     $(window).on('resize', resizeHandler);
Line 131: Line 143:
         });
         });


         // Bind the lightbox button to open the corresponding SVG in full-screen
        // Initially hide elements with the "highlight-phrase" class
         $('.lightbox-button').on('click', function() {
        document.querySelectorAll(".highlight-phrase").forEach(function (element) {
            element.style.display = "none"; // Hide elements initially
        });
 
 
 
         // Bind lightbox functionality
         $('.lightbox-button').on('click', function () {
             // Get the target <div> ID from the button's data-target attribute
             // Get the target <div> ID from the button's data-target attribute
             var targetDivId = $(this).data('target'); // e.g., '#verse-1'
             var targetDivId = $(this).data('target'); // e.g., '#verse-1'
Line 139: Line 158:


             if (associatedSvg.length > 0) {
             if (associatedSvg.length > 0) {
                 openLightbox(associatedSvg[0]); // Trigger the lightbox for the corresponding SVG
                 openLightbox(associatedSvg[0]);
             }
             }
         });
         });


         // Function to open the lightbox and display the full-screen SVG
         // Open the lightbox and display the SVG in full-screen
         function openLightbox(svgElement) {
         function openLightbox(svgElement) {
             // Create lightbox container if it doesn't exist
             // Create lightbox container if it doesn't exist          
             var lightbox = $('<div id="lightbox-overlay" class="lightbox-overlay">')
             var lightbox = $('<div id="lightbox-overlay" class="lightbox-overlay">')
                 .appendTo('body')
                 .appendTo('body')
Line 162: Line 181:


             // Create the SVG container in the lightbox
             // Create the SVG container in the lightbox
            var lightboxSvgContainer = $('<div class="lightbox-svg-container">')
                var lightboxSvgContainer = $('<div class="lightbox-svg-container">')
                 .appendTo(lightbox)
                 .appendTo(lightbox)
                 .css({
                 .css({
Line 171: Line 190:
                 });
                 });


             var lightboxSvg = $(svgElement).clone().appendTo(lightboxSvgContainer); // Clone the SVG
             var lightboxSvg = $(svgElement).clone().appendTo(lightboxSvgContainer); // Clone the SVG
// resize the svg to the available space
            // resize the svg to the available space
             lightboxSvg.css({
             lightboxSvg.css({
                 'width': '100%',
                 'width': '100%',
Line 192: Line 211:
             });
             });


            // Create a close button for the lightbox
             var closeButton = $('<button class="lightbox-close-button">Close</button>')
             var closeButton = $('<button class="lightbox-close-button">Close</button>')
                 .appendTo(lightbox)
                 .appendTo(lightbox)
Line 207: Line 225:
                     zIndex: 10000
                     zIndex: 10000
                 })
                 })
                 .on('click', function() {
                 .on('click', function () {
                // Close the lightbox when the close button is clicked
                    // Close the lightbox when the close button is clicked
                     lightbox.remove();  
                     lightbox.remove();
                 });
                 });


            // Close the lightbox when clicking outside the SVG
             lightbox.on('click', function (event) {
             lightbox.on('click', function(event) {
                // Close the lightbox when clicking outside the SVG
                 if ($(event.target).is(lightbox)) {
                 if ($(event.target).is(lightbox)) {
                     lightbox.remove();
                     lightbox.remove();
                 }
                 }
             });
             });
           
 
             // Close the lightbox when the Escape key is pressed
             // Close the lightbox with the Escape key
             $(document).on('keydown', function(event) {
             $(document).on('keydown', function (event) {
                 if (event.key === "Escape" || event.keyCode === 27) { // Check for Escape key
                 if (event.key === "Escape" || event.keyCode === 27) {
                     lightbox.remove();
                     lightbox.remove();
                     $(document).off('keydown');  // Remove the keydown listener to prevent multiple bindings
                     $(document).off('keydown');  // Remove the keydown listener to prevent multiple bindings
Line 227: Line 245:
             });
             });
         }
         }
 
     });
     }, 3000); // 3000 milliseconds = 3 seconds
});
});

Revision as of 17:37, 17 January 2025

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

// Function to check if all <pre class="mermaid"> elements are processed
function checkMermaidProcessed() {
    var mermaidPreElements = document.querySelectorAll('pre.mermaid');
    var allProcessed = true;

    mermaidPreElements.forEach(function (element) {
        if (!element.hasAttribute('data-processed') || element.getAttribute('data-processed') !== 'true') {
            allProcessed = false;
        }
    });

    return allProcessed;
}

// Function to wait until all Mermaid diagrams are processed
function waitForMermaidProcessing(callback) {
    var interval = setInterval(function () {
        if (checkMermaidProcessed()) {
            clearInterval(interval);
            callback(); // Once all elements are processed, run the callback
        }
    }, 100); // Check every 100ms
}

function toggleVisibility(containerId, className) {
    //console.log("Toggling visibility for " + className + " in " + containerId);
    var container = document.getElementById(containerId);
    if (container) {
        var elements = container.querySelectorAll("g." + className);
        for (var i = 0; i < elements.length; i++) {
            var element = elements[i];
            
            if (element.style.display === "none") {
                element.style.display = ""; // Show element
            } else {
                element.style.display = "none"; // Hide element
            }
        }
    } else {
        console.warn("Container with ID \"" + containerId + "\" not found.");
    }
}

function attachToggleListeners() {
    //console.log("Attaching event listeners to toggle links.");
    var toggleLinks = document.querySelectorAll("[data-container-id][data-class]");
    //console.log("Found " + toggleLinks.length + " links.");

    // If no toggle links are found, print a warning
    if (toggleLinks.length === 0) {
        console.warn("No toggle links found on the page.");
    }
    
    for (var i = 0; i < toggleLinks.length; i++) {
        (function (toggleLink) {
            toggleLink.addEventListener("click", function (event) {
                event.preventDefault(); // Prevent default link behavior
                var containerId = toggleLink.getAttribute("data-container-id");
                var className = toggleLink.getAttribute("data-class");
                toggleVisibility(containerId, className);
            });
        })(toggleLinks[i]);
    }
}

// ===========================


$(document).ready(function () {
    //console.log("Document ready. Attaching event listeners to toggle links.");

    // Now attach event listeners for toggling visibility
    attachToggleListeners();

    // Wait until all Mermaid diagrams are processed
    waitForMermaidProcessing(function () {
        //console.log("Mermaid diagrams are fully processed.");

        $('div[id^="verse-"]').each(function () {
            var parentDiv = $(this);
            var svg = parentDiv.find('svg');
            var panZoomInstance;

            if (svg.length > 0) {
                var preElement = parentDiv.find('pre.mermaid');  // The <pre> element containing the SVG
                var preWidth = preElement.width();
                var preHeight = preElement.height();
                var viewBox = svg[0].getAttribute('viewBox');

                if (viewBox) {
                    var viewBoxValues = viewBox.split(' ');
                    var viewBoxWidth = parseFloat(viewBoxValues[2]);
                    var viewBoxHeight = parseFloat(viewBoxValues[3]);
                    var scaleX = preWidth / viewBoxWidth;
                    var scaleY = preHeight / viewBoxHeight;
                    var scale = Math.min(scaleX, scaleY);

                    svg.css({
                        'width': (preWidth) + 'px',
                        'max-width': (preWidth) + 'px',
                        'height': (viewBoxHeight * scale) + 'px',
                        'position': 'relative'  // Ensure the SVG has a positioning context
                    });

                    panZoomInstance = svgPanZoom(svg[0], {
                        panEnabled: true,
                        controlIconsEnabled: false,
                        zoomEnabled: true,
                        dblClickZoomEnabled: true,
                        contain: true,
                        fit: true,
                        center: false
                    });

                    // Resize handler to keep SVG scaled on window resize
                    var resizeHandler = function () {
                        var newWidth = preElement.width();
                        var newHeight = preElement.height();
                        //console.log('pre.mermaid container resized to: ', newWidth, newHeight);

                        var newScaleX = newWidth / viewBoxWidth;
                        var newScaleY = newHeight / viewBoxHeight;
                        var newScale = Math.min(newScaleX, newScaleY);

                        svg.css({
                            'width': (newWidth) + 'px',
                            'max-width': (newWidth) + 'px'
                            //'height': (viewBoxHeight * newScale) + 'px'
                            // Do not change the height to avoid reflowing the html page
                        });

                        if (panZoomInstance) {
                            panZoomInstance.resize();
                        }
                    };
                    
                    // Listen for resize events
                    $(window).on('resize', resizeHandler);
                }
            }
        });

        // Initially hide elements with the "highlight-phrase" class
        document.querySelectorAll(".highlight-phrase").forEach(function (element) {
            element.style.display = "none"; // Hide elements initially
        });



        // Bind lightbox functionality
        $('.lightbox-button').on('click', function () {
            // Get the target <div> ID from the button's data-target attribute
            var targetDivId = $(this).data('target'); // e.g., '#verse-1'
            var parentDiv = $(targetDivId); // Find the corresponding <div> by ID
            var associatedSvg = parentDiv.find('svg'); // Find the SVG inside the <pre>

            if (associatedSvg.length > 0) {
                openLightbox(associatedSvg[0]);
            }
        });

        // Open the lightbox and display the SVG in full-screen
        function openLightbox(svgElement) {
            // Create lightbox container if it doesn't exist            
            var lightbox = $('<div id="lightbox-overlay" class="lightbox-overlay">')
                .appendTo('body')
                .css({
                    position: 'fixed',
                    top: 0,
                    left: 0,
                    width: '100%',
                    height: '100%',
                    backgroundColor: 'rgba(128, 128, 128, 0.8)',
                    display: 'flex',
                    justifyContent: 'center',
                    alignItems: 'center',
                    zIndex: 9999,
                });

            // Create the SVG container in the lightbox
                var lightboxSvgContainer = $('<div class="lightbox-svg-container">')
                .appendTo(lightbox)
                .css({
                    width: '95%',
                    height: '95%',
                    overflow: 'hidden',
                    backgroundColor: 'rgba(255, 255, 255, 1.0)',
                });

            var lightboxSvg = $(svgElement).clone().appendTo(lightboxSvgContainer);  // Clone the SVG
            // resize the svg to the available space
            lightboxSvg.css({
                'width': '100%',
                'max-width': '100%',
                'height': '100%'
            });



            // Apply svg-pan-zoom to the cloned SVG in the lightbox
            var panZoomInstanceLightbox = svgPanZoom(lightboxSvg[0], {
                panEnabled: true,
                controlIconsEnabled: false,
                zoomEnabled: true,
                dblClickZoomEnabled: true,
                contain: true,
                fit: true,
                center: true
            });

            var closeButton = $('<button class="lightbox-close-button">Close</button>')
                .appendTo(lightbox)
                .css({
                    position: 'absolute',
                    top: '10px',
                    right: '10px',
                    backgroundColor: '#fff',
                    color: '#000',
                    border: '1px solid #bbb',
                    borderRadius: '1rem',
                    padding: '10px 20px',
                    cursor: 'pointer',
                    zIndex: 10000
                })
                .on('click', function () {
                    // Close the lightbox when the close button is clicked
                    lightbox.remove();
                });

            lightbox.on('click', function (event) {
                // Close the lightbox when clicking outside the SVG
                if ($(event.target).is(lightbox)) {
                    lightbox.remove();
                }
            });

            // Close the lightbox with the Escape key
            $(document).on('keydown', function (event) {
                if (event.key === "Escape" || event.keyCode === 27) {
                    lightbox.remove();
                    $(document).off('keydown');  // Remove the keydown listener to prevent multiple bindings
                }
            });
        }
    });
});