Skip to content

Commit 44edd61

Browse files
authored
Use builtin image as fallback when authored image fails to load. (swiftlang#42)
1 parent b091c45 commit 44edd61

File tree

3 files changed

+59
-2
lines changed

3 files changed

+59
-2
lines changed

src/assets/img/[email protected]

6.01 KB
Loading

src/components/ImageAsset.vue

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,13 @@
99
-->
1010

1111
<template>
12-
<picture>
12+
<img
13+
v-if="fallbackImageSrcSet"
14+
class="fallback"
15+
:alt="`${alt} Image failed to load.`"
16+
:srcset="fallbackImageSrcSet"
17+
/>
18+
<picture v-else>
1319
<!--
1420
if "Auto" is selected, provide an alternate dark variant if available
1521
using the appropriate media query
@@ -24,6 +30,7 @@
2430
v-if="prefersDark && darkVariantAttributes"
2531
v-bind="darkVariantAttributes"
2632
:alt="alt"
33+
@error="handleImageLoadError"
2734
>
2835
<!--
2936
otherwise use the default variant (light preferred over dark if both available)
@@ -32,6 +39,7 @@
3239
v-else
3340
v-bind="defaultAttributes"
3441
:alt="alt"
42+
@error="handleImageLoadError"
3543
>
3644
</picture>
3745
</template>
@@ -41,6 +49,7 @@
4149
import imageAsset from 'docc-render/mixins/imageAsset';
4250
import AppStore from 'docc-render/stores/AppStore';
4351
import ColorScheme from 'docc-render/constants/ColorScheme';
52+
import noImage from 'theme/assets/img/[email protected]';
4453
import { normalizeAssetUrl } from 'docc-render/utils/assets';
4554

4655
function constructAttributes(sources) {
@@ -70,7 +79,10 @@ function constructAttributes(sources) {
7079
export default {
7180
name: 'ImageAsset',
7281
mixins: [imageAsset],
73-
data: () => ({ appState: AppStore.state }),
82+
data: () => ({
83+
appState: AppStore.state,
84+
fallbackImageSrcSet: null,
85+
}),
7486
computed: {
7587
defaultAttributes: ({
7688
lightVariantAttributes,
@@ -92,5 +104,12 @@ export default {
92104
required: true,
93105
},
94106
},
107+
methods: {
108+
handleImageLoadError() {
109+
// fall back to a default DocC-Render provided image if the specificed
110+
// image fails to load for any reason
111+
this.fallbackImageSrcSet = `${noImage} 2x`;
112+
},
113+
},
95114
};
96115
</script>

tests/unit/components/ImageAsset.spec.js

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,4 +231,42 @@ describe('ImageAsset', () => {
231231
expect(image.attributes('width')).toBe('1202');
232232
expect(image.attributes('height')).toBe('auto');
233233
});
234+
235+
it('renders a fallback image if the specified one does not load', () => {
236+
const url = 'https://www.example.com/image.png';
237+
const alt = 'This is alt text.';
238+
const wrapper = shallowMount(ImageAsset, {
239+
propsData: {
240+
variants: [
241+
{
242+
traits: [
243+
'2x',
244+
'light',
245+
],
246+
url,
247+
size: {
248+
width: 1202,
249+
height: 630,
250+
},
251+
},
252+
],
253+
alt,
254+
},
255+
});
256+
257+
const picture = wrapper.find('picture');
258+
expect(picture.exists()).toBe(true);
259+
const img = picture.find('img');
260+
expect(img.exists()).toBe(true);
261+
expect(img.classes('fallback')).toBe(false);
262+
263+
// simulate an error loading the real image
264+
img.trigger('error');
265+
266+
expect(wrapper.find('picture').exists()).toBe(false);
267+
const fallbackImg = wrapper.find('img');
268+
expect(fallbackImg.exists()).toBe(true);
269+
expect(fallbackImg.classes('fallback')).toBe(true);
270+
expect(fallbackImg.attributes('alt')).toBe(`${alt} Image failed to load.`);
271+
});
234272
});

0 commit comments

Comments
 (0)