User:Monster Domosed/common.js: Difference between revisions

Jump to navigation Jump to search
No edit summary
No edit summary
Line 24: Line 24:
     function updateViewerSize(viewer) {
     function updateViewerSize(viewer) {
         const wrapper = viewer.closest('[class*="model_size_"]');
         const wrapper = viewer.closest('[class*="model_size_"]');
         if (!wrapper) {
         if (!wrapper) {
             return;
             return;
Line 29: Line 30:


         const match = wrapper.className.match(/\bmodel_size_(\d+)\b/);
         const match = wrapper.className.match(/\bmodel_size_(\d+)\b/);
         if (!match) {
         if (!match) {
             return;
             return;
Line 39: Line 41:
     }
     }


     function switchModel(viewer, icon) {
 
const isHQ = !viewer.src.endsWith('-compressed.glb');
     function switchQuality(viewer, buttonIcon, lqUrl, hqUrl) {
        const currentSrc = viewer.src;
viewer.src = isHQ
 
    ? viewer.src.replace(/\.glb$/i, '-compressed.glb')
        const targetSrc = currentSrc === lqUrl ? hqUrl : lqUrl;
    : viewer.src.replace(/-compressed\.glb$/i, '.glb');
 
        const currentTime = viewer.currentTime;
icon.src = isHQ ? LQ_ICON : HQ_ICON;
        const animationName = viewer.animationName;
 
        const cameraOrbit = viewer.getAttribute('camera-orbit');
        const cameraTarget = viewer.getAttribute('camera-target');
 
        viewer.addEventListener('load', function restore() {
            viewer.removeEventListener('load', restore);
 
            if (cameraOrbit) {
                viewer.setAttribute('camera-orbit', cameraOrbit);
            }
 
            if (cameraTarget) {
                viewer.setAttribute('camera-target', cameraTarget);
            }
 
            if (animationName) {
                viewer.animationName = animationName;
            }
 
            if (typeof currentTime === 'number') {
                viewer.currentTime = currentTime;
            }
 
            if (viewer.hasAttribute('autoplay')) {
                viewer.play();
            }
        }, { once: true });
 
 
        viewer.src = targetSrc;
 
        buttonIcon.src = targetSrc === hqUrl ? HQ_ICON : LQ_ICON;
    }
 


     function initViewer(viewer) {
     function initViewer(viewer) {
         if (viewer.dataset.modelViewerEnhanced) {
         if (viewer.dataset.qualityButton) {
             return;
             return;
         }
         }


         viewer.dataset.modelViewerEnhanced = '1';
         viewer.dataset.qualityButton = '1';


         updateViewerSize(viewer);
         updateViewerSize(viewer);


        const wrapper = document.createElement('div');
        wrapper.className = 'mv-quality-container';


         viewer.parentNode.insertBefore(wrapper, viewer);
         const wrapper = viewer.closest('[class*="model_size_"]');
         wrapper.appendChild(viewer);
 
        if (!wrapper) {
            return;
         }
 
 
        const hqName = wrapper.dataset.hqFile;
 
        if (!hqName) {
            return;
        }


        const button = document.createElement('button');
        button.className = 'mv-quality-toggle';
        button.type = 'button';
        button.title = 'Switch quality';


         const icon = document.createElement('img');
         const lqUrl = viewer.src;
        icon.alt = '';


         const isHQ = !viewer.src.endsWith('-compressed.glb');
         const fileUrl = new URL(lqUrl);
        icon.src = isHQ ? HQ_ICON : LQ_ICON;


         button.appendChild(icon);
         const basePath = fileUrl.pathname.substring(
         wrapper.appendChild(button);
            0,
            fileUrl.pathname.lastIndexOf('/')
         );


         button.addEventListener('click', function () {
 
            switchModel(viewer, icon);
        const apiUrl = mw.config.get('wgScriptPath') +
        });
            '/api.php?action=query&titles=File:' +
            encodeURIComponent(hqName + '.glb') +
            '&prop=imageinfo&iiprop=url&format=json';
 
 
         fetch(apiUrl)
            .then(response => response.json())
            .then(data => {
 
                const pages = data.query.pages;
 
                const page = Object.values(pages)[0];
 
                if (!page.imageinfo) {
                    return;
                }
 
                const hqUrl = page.imageinfo[0].url;
 
 
                const container = document.createElement('div');
 
                container.className = 'mv-quality-container';
 
 
                viewer.parentNode.insertBefore(container, viewer);
 
                container.appendChild(viewer);
 
 
                const button = document.createElement('button');
 
                button.className = 'mv-quality-toggle';
 
                button.type = 'button';
 
 
                const icon = document.createElement('img');
 
                icon.alt = '';
 
                icon.src = LQ_ICON;
 
 
                button.appendChild(icon);
 
                container.appendChild(button);
 
 
                button.addEventListener('click', function () {
                    switchQuality(
                        viewer,
                        icon,
                        lqUrl,
                        hqUrl
                    );
                });
 
            });
     }
     }


     function init() {
     function init() {
         document.querySelectorAll('model-viewer').forEach(initViewer);
         document.querySelectorAll('model-viewer').forEach(initViewer);
     }
     }


     if (document.readyState === 'loading') {
     if (document.readyState === 'loading') {
Line 91: Line 191:
         init();
         init();
     }
     }


     window.addEventListener('resize', function () {
     window.addEventListener('resize', function () {
         document.querySelectorAll('model-viewer').forEach(updateViewerSize);
         document.querySelectorAll('model-viewer').forEach(updateViewerSize);
     });
     });
})();
})();