StillImage: Improved animated image detection
ci/woodpecker/pr/woodpecker Pipeline was successful Details

This patch makes StillImage's animation detection return early in cases
where we can't detect the mimetype of the image. It also sets the image
as animated in those cases if the user agent wants reduced motion.

As reduced motion is an accessibility setting, I think it's best to use
a "better safe than sorry" approach, it's better to accidentally mark
something as animated that isn't than to have unblocked animations.
This commit is contained in:
Yuki Joou 2023-08-03 16:03:12 +02:00
parent af97dd7484
commit 43d0a24547
1 changed files with 14 additions and 1 deletions

View File

@ -39,12 +39,25 @@ const StillImage = {
this.imageLoadError && this.imageLoadError() this.imageLoadError && this.imageLoadError()
}, },
detectAnimation (image) { detectAnimation (image) {
// If there are no file extensions, the mimetype isn't set, and no mediaproxy is available, we can't figure out
// the mimetype of the image.
const hasFileExtension = this.src.split('/').pop().includes('.') // TODO: Better check?
const mediaProxyAvailable = this.$store.state.instance.mediaProxyAvailable
if (!hasFileExtension && this.mimetype === undefined && !mediaProxyAvailable) {
// It's a bit aggressive to assume all images we can't find the mimetype of is animated, but necessary for
// people in need of reduced motion accessibility. As such, we'll consider those images animated if the user
// agent is set to prefer reduced motion. Otherwise, it'll just be used as an early exit.
if (window.matchMedia('(prefers-reduced-motion: reduce)').matches)
this.isAnimated = true
return
}
if (this.mimetype === 'image/gif' || this.src.endsWith('.gif')) { if (this.mimetype === 'image/gif' || this.src.endsWith('.gif')) {
this.isAnimated = true this.isAnimated = true
return return
} }
// harmless CORS errors without-- clean console with // harmless CORS errors without-- clean console with
if (!this.$store.state.instance.mediaProxyAvailable) return if (!mediaProxyAvailable) return
// Animated JPEGs? // Animated JPEGs?
if (!(this.src.endsWith('.webp') || this.src.endsWith('.png'))) return if (!(this.src.endsWith('.webp') || this.src.endsWith('.png'))) return
// Browser Cache should ensure image doesn't get loaded twice if cache exists // Browser Cache should ensure image doesn't get loaded twice if cache exists