User:Monster Domosed/common.js: Difference between revisionsGive feedback
Jump to navigation
Jump to search
No edit summary |
No edit summary |
||
| Line 1: | Line 1: | ||
(function () { | |||
'use strict'; | |||
const LQ_ICON = '/images/6/65/2D_icon.png'; | |||
const HQ_ICON = '/images/7/7e/3D_icon.png'; | |||
function updateViewerSize(viewer, wrapper) { | |||
const match = wrapper.className.match(/model_size_(\d+)/); | |||
if (!match) { | |||
return; | |||
} | |||
const size = parseInt(match[1], 10); | |||
viewer.style.width = size + 'px'; | |||
viewer.style.height = size + 'px'; | |||
} | } | ||
const | |||
function getHQUrl(fileName) { | |||
const apiUrl = | |||
mw.config.get('wgScriptPath') + | |||
'/api.php?action=query' + | |||
'&titles=File:' + encodeURIComponent(fileName) + | |||
'.glb' + | |||
'&prop=imageinfo' + | |||
'&iiprop=url' + | |||
'&format=json'; | |||
return fetch(apiUrl) | |||
.then(function (response) { | |||
return response.json(); | |||
}) | |||
.then(function (data) { | |||
const pages = data.query.pages; | |||
const page = Object.values(pages)[0]; | |||
if (!page.imageinfo) { | |||
return null; | |||
} | |||
return page.imageinfo[0].url; | |||
}); | |||
} | } | ||
function switchQuality(viewer, icon, lqUrl, hqUrl) { | |||
const isLQ = viewer.src === lqUrl; | |||
}); | |||
const oldTime = viewer.currentTime; | |||
const oldAnimation = viewer.animationName; | |||
const oldOrbit = viewer.getAttribute('camera-orbit'); | |||
const oldTarget = viewer.getAttribute('camera-target'); | |||
viewer.addEventListener('load', function restore() { | |||
viewer.removeEventListener('load', restore); | |||
if (oldOrbit) { | |||
viewer.setAttribute('camera-orbit', oldOrbit); | |||
} | |||
if (oldTarget) { | |||
viewer.setAttribute('camera-target', oldTarget); | |||
} | |||
if (oldAnimation) { | |||
viewer.animationName = oldAnimation; | |||
} | |||
if (typeof oldTime === 'number') { | |||
viewer.currentTime = oldTime; | |||
} | |||
if (viewer.hasAttribute('autoplay')) { | |||
viewer.play(); | |||
} | |||
}, { once: true }); | |||
viewer.src = isLQ ? hqUrl : lqUrl; | |||
icon.src = isLQ ? HQ_ICON : LQ_ICON; | |||
} | |||
function initViewer(viewer) { | |||
if (viewer.dataset.qualityButtonAdded) { | |||
return; | |||
} | |||
const wrapper = viewer.closest('[class*="model_size_"]'); | const wrapper = viewer.closest('[class*="model_size_"]'); | ||
| Line 29: | Line 95: | ||
} | } | ||
const | const src = viewer.getAttribute('src'); | ||
if (! | if (!src || !src.endsWith('-compressed.glb')) { | ||
return; | return; | ||
} | } | ||
viewer.dataset.qualityButtonAdded = '1'; | |||
updateViewerSize(viewer, wrapper); | |||
const fileMatch = src.match(/\/([^\/]+)-compressed\.glb$/); | |||
if (!fileMatch) { | |||
if ( | |||
return; | return; | ||
} | } | ||
const baseName = fileMatch[1]; | |||
getHQUrl(baseName) | |||
.then(function (hqUrl) { | |||
if (!hqUrl) { | |||
return; | |||
} | |||
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.src = LQ_ICON; | |||
icon.alt = ''; | |||
button.appendChild(icon); | |||
container.appendChild(button); | |||
button.addEventListener('click', function () { | |||
switchQuality( | |||
viewer, | |||
icon, | |||
src, | |||
hqUrl | |||
); | |||
}); | |||
}); | |||
} | } | ||
function scan() { | function scan() { | ||
document.querySelectorAll('model-viewer').forEach( | document.querySelectorAll('model-viewer').forEach(initViewer); | ||
} | } | ||
scan(); | scan(); | ||
const observer = new MutationObserver(function () { | const observer = new MutationObserver(function () { | ||
scan(); | scan(); | ||
}); | }); | ||
observer.observe(document.body, { | observer.observe(document.body, { | ||
childList: true, | childList: true, | ||
subtree: true | subtree: true | ||
}); | |||
window.addEventListener('resize', function () { | |||
document.querySelectorAll('model-viewer').forEach(function (viewer) { | |||
const wrapper = viewer.closest('[class*="model_size_"]'); | |||
if (wrapper) { | |||
updateViewerSize(viewer, wrapper); | |||
} | |||
}); | |||
}); | }); | ||
})(); | })(); | ||