@veracity/vui 2.15.1 → 2.15.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/avatar/avatar.d.ts.map +1 -1
- package/dist/cjs/avatar/avatar.js +40 -9
- package/dist/cjs/input/input.d.ts.map +1 -1
- package/dist/cjs/input/input.js +1 -0
- package/dist/cjs/utils/images.d.ts +3 -0
- package/dist/cjs/utils/images.d.ts.map +1 -0
- package/dist/cjs/utils/images.js +24 -0
- package/dist/esm/avatar/avatar.d.ts.map +1 -1
- package/dist/esm/avatar/avatar.js +17 -9
- package/dist/esm/input/input.d.ts.map +1 -1
- package/dist/esm/input/input.js +1 -0
- package/dist/esm/utils/images.d.ts +3 -0
- package/dist/esm/utils/images.d.ts.map +1 -0
- package/dist/esm/utils/images.js +20 -0
- package/package.json +1 -1
- package/src/avatar/avatar.tsx +45 -18
- package/src/input/input.tsx +1 -0
- package/src/utils/images.ts +20 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"avatar.d.ts","sourceRoot":"","sources":["../../../src/avatar/avatar.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"avatar.d.ts","sourceRoot":"","sources":["../../../src/avatar/avatar.tsx"],"names":[],"mappings":"AAOA,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAG5C,eAAO,MAAM,UAAU,gIAoBtB,CAAA;AAED,kEAAkE;AAClE,eAAO,MAAM,MAAM,qDA8DjB,CAAA;AAsCF,eAAe,MAAM,CAAA"}
|
|
@@ -1,4 +1,27 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
2
25
|
var __rest = (this && this.__rest) || function (s, e) {
|
|
3
26
|
var t = {};
|
|
4
27
|
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
@@ -15,18 +38,13 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
15
38
|
};
|
|
16
39
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
40
|
exports.Avatar = exports.AvatarBase = void 0;
|
|
18
|
-
const react_1 =
|
|
41
|
+
const react_1 = __importStar(require("react"));
|
|
19
42
|
const core_1 = require("../core");
|
|
20
43
|
const icon_1 = __importDefault(require("../icon"));
|
|
21
44
|
const image_1 = __importDefault(require("../image"));
|
|
22
45
|
const utils_1 = require("../utils");
|
|
46
|
+
const images_1 = require("../utils/images");
|
|
23
47
|
const helpers_1 = require("./helpers");
|
|
24
|
-
function imageExists(image_url) {
|
|
25
|
-
const http = new XMLHttpRequest();
|
|
26
|
-
http.open('HEAD', image_url, false);
|
|
27
|
-
http.send();
|
|
28
|
-
return http.status !== 404;
|
|
29
|
-
}
|
|
30
48
|
exports.AvatarBase = core_1.styled.spanBox `
|
|
31
49
|
align-items: center;
|
|
32
50
|
display: inline-flex;
|
|
@@ -54,7 +72,6 @@ exports.Avatar = (0, core_1.vui)((props, ref) => {
|
|
|
54
72
|
const _b = (0, core_1.useStyleConfig)('Avatar', props), { activeBg, h, hoverBg, iconSize } = _b, styles = __rest(_b, ["activeBg", "h", "hoverBg", "iconSize"]);
|
|
55
73
|
const borderRadius = isSquare ? (props.size === 'sm' ? '3px' : '6px') : '50%';
|
|
56
74
|
const initials = getInitials(name);
|
|
57
|
-
const internalIcon = src && !imageExists(src) ? 'falUser' : icon;
|
|
58
75
|
const interactiveProps = !disabled && isInteractive
|
|
59
76
|
? {
|
|
60
77
|
cursor: 'pointer',
|
|
@@ -71,7 +88,21 @@ exports.Avatar = (0, core_1.vui)((props, ref) => {
|
|
|
71
88
|
borderRadius: borderRadius,
|
|
72
89
|
'aria-disabled': disabled
|
|
73
90
|
});
|
|
74
|
-
return (react_1.default.createElement(exports.AvatarBase, Object.assign({ borderRadius: borderRadius, className: (0, utils_1.cs)('vui-avatar', className), h: h, ref: ref, w: h }, styles, interactiveProps, aliasedProps, rest), children ? (children) : src
|
|
91
|
+
return (react_1.default.createElement(exports.AvatarBase, Object.assign({ borderRadius: borderRadius, className: (0, utils_1.cs)('vui-avatar', className), h: h, ref: ref, w: h }, styles, interactiveProps, aliasedProps, rest), children ? (children) : src ? (react_1.default.createElement(LazyImageOrDefault, { borderRadius: borderRadius, icon: icon, iconSize: iconSize, initials: initials, src: src })) : icon ? (react_1.default.createElement(icon_1.default, { name: icon, size: iconSize })) : initials ? (initials) : (react_1.default.createElement(icon_1.default, { name: "falUser", size: iconSize }))));
|
|
75
92
|
});
|
|
93
|
+
function LazyImageOrDefault({ src, borderRadius, icon, iconSize, initials }) {
|
|
94
|
+
const [imgLoaded, setImgLoaded] = (0, react_1.useState)(false);
|
|
95
|
+
(0, react_1.useEffect)(() => {
|
|
96
|
+
let cancelled = false;
|
|
97
|
+
(0, images_1.loadImageUrl)(src).then(res => {
|
|
98
|
+
if (!cancelled)
|
|
99
|
+
setImgLoaded(res);
|
|
100
|
+
});
|
|
101
|
+
return () => {
|
|
102
|
+
cancelled = true;
|
|
103
|
+
};
|
|
104
|
+
}, [src]);
|
|
105
|
+
return imgLoaded ? (react_1.default.createElement(image_1.default, { borderRadius: borderRadius, src: src })) : icon ? (react_1.default.createElement(icon_1.default, { name: icon, size: iconSize })) : initials ? (react_1.default.createElement(react_1.default.Fragment, null, "initials")) : (react_1.default.createElement(icon_1.default, { name: "falUser", size: iconSize }));
|
|
106
|
+
}
|
|
76
107
|
exports.Avatar.displayName = 'Avatar';
|
|
77
108
|
exports.default = exports.Avatar;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"input.d.ts","sourceRoot":"","sources":["../../../src/input/input.tsx"],"names":[],"mappings":"AAGA,OAAO,EAA+B,YAAY,EAAE,MAAM,SAAS,CAAA;AAOnE,OAAO,QAAQ,MAAM,YAAY,CAAA;AACjC,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAC1C,OAAO,SAAS,MAAM,aAAa,CAAA;AACnC,OAAO,UAAU,MAAM,cAAc,CAAA;AAErC,eAAO,MAAM,SAAS,+
|
|
1
|
+
{"version":3,"file":"input.d.ts","sourceRoot":"","sources":["../../../src/input/input.tsx"],"names":[],"mappings":"AAGA,OAAO,EAA+B,YAAY,EAAE,MAAM,SAAS,CAAA;AAOnE,OAAO,QAAQ,MAAM,YAAY,CAAA;AACjC,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAC1C,OAAO,SAAS,MAAM,aAAa,CAAA;AACnC,OAAO,UAAU,MAAM,cAAc,CAAA;AAErC,eAAO,MAAM,SAAS,+HAoBrB,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,KAAK;UAuKV,gBAAgB;WACf,iBAAiB;cACd,eAAe;CAC1B,CAAA;AAOD,eAAe,KAAK,CAAA"}
|
package/dist/cjs/input/input.js
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"images.d.ts","sourceRoot":"","sources":["../../../src/utils/images.ts"],"names":[],"mappings":"AAEA,kFAAkF;AAClF,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,oBAgBvC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.loadImageUrl = void 0;
|
|
4
|
+
const loadImagePromises = new Map();
|
|
5
|
+
/** Attempts to load the image and returns a boolean indicating success or not. */
|
|
6
|
+
function loadImageUrl(url) {
|
|
7
|
+
let promise = loadImagePromises.get(url);
|
|
8
|
+
if (promise)
|
|
9
|
+
return promise;
|
|
10
|
+
promise = new Promise(resolve => {
|
|
11
|
+
const img = new Image();
|
|
12
|
+
img.onload = () => {
|
|
13
|
+
// After this event occurs, you can use the url in the DOM. The browser will not make another request for the image; there will be no delay.
|
|
14
|
+
resolve(true);
|
|
15
|
+
};
|
|
16
|
+
img.onerror = () => {
|
|
17
|
+
resolve(false);
|
|
18
|
+
};
|
|
19
|
+
img.src = url;
|
|
20
|
+
});
|
|
21
|
+
loadImagePromises.set(url, promise);
|
|
22
|
+
return promise;
|
|
23
|
+
}
|
|
24
|
+
exports.loadImageUrl = loadImageUrl;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"avatar.d.ts","sourceRoot":"","sources":["../../../src/avatar/avatar.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"avatar.d.ts","sourceRoot":"","sources":["../../../src/avatar/avatar.tsx"],"names":[],"mappings":"AAOA,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAG5C,eAAO,MAAM,UAAU,gIAoBtB,CAAA;AAED,kEAAkE;AAClE,eAAO,MAAM,MAAM,qDA8DjB,CAAA;AAsCF,eAAe,MAAM,CAAA"}
|
|
@@ -1,15 +1,10 @@
|
|
|
1
|
-
import React from 'react';
|
|
1
|
+
import React, { useEffect, useState } from 'react';
|
|
2
2
|
import { omitThemingProps, styled, useStyleConfig, vui } from '../core';
|
|
3
3
|
import Icon from '../icon';
|
|
4
4
|
import Image from '../image';
|
|
5
5
|
import { cs, filterUndefined } from '../utils';
|
|
6
|
+
import { loadImageUrl } from '../utils/images';
|
|
6
7
|
import { defaultGetInitials } from './helpers';
|
|
7
|
-
function imageExists(image_url) {
|
|
8
|
-
const http = new XMLHttpRequest();
|
|
9
|
-
http.open('HEAD', image_url, false);
|
|
10
|
-
http.send();
|
|
11
|
-
return http.status !== 404;
|
|
12
|
-
}
|
|
13
8
|
export const AvatarBase = styled.spanBox `
|
|
14
9
|
align-items: center;
|
|
15
10
|
display: inline-flex;
|
|
@@ -37,7 +32,6 @@ export const Avatar = vui((props, ref) => {
|
|
|
37
32
|
const { activeBg, h, hoverBg, iconSize, ...styles } = useStyleConfig('Avatar', props);
|
|
38
33
|
const borderRadius = isSquare ? (props.size === 'sm' ? '3px' : '6px') : '50%';
|
|
39
34
|
const initials = getInitials(name);
|
|
40
|
-
const internalIcon = src && !imageExists(src) ? 'falUser' : icon;
|
|
41
35
|
const interactiveProps = !disabled && isInteractive
|
|
42
36
|
? {
|
|
43
37
|
cursor: 'pointer',
|
|
@@ -54,7 +48,21 @@ export const Avatar = vui((props, ref) => {
|
|
|
54
48
|
borderRadius: borderRadius,
|
|
55
49
|
'aria-disabled': disabled
|
|
56
50
|
});
|
|
57
|
-
return (React.createElement(AvatarBase, { borderRadius: borderRadius, className: cs('vui-avatar', className), h: h, ref: ref, w: h, ...styles, ...interactiveProps, ...aliasedProps, ...rest }, children ? (children) : src
|
|
51
|
+
return (React.createElement(AvatarBase, { borderRadius: borderRadius, className: cs('vui-avatar', className), h: h, ref: ref, w: h, ...styles, ...interactiveProps, ...aliasedProps, ...rest }, children ? (children) : src ? (React.createElement(LazyImageOrDefault, { borderRadius: borderRadius, icon: icon, iconSize: iconSize, initials: initials, src: src })) : icon ? (React.createElement(Icon, { name: icon, size: iconSize })) : initials ? (initials) : (React.createElement(Icon, { name: "falUser", size: iconSize }))));
|
|
58
52
|
});
|
|
53
|
+
function LazyImageOrDefault({ src, borderRadius, icon, iconSize, initials }) {
|
|
54
|
+
const [imgLoaded, setImgLoaded] = useState(false);
|
|
55
|
+
useEffect(() => {
|
|
56
|
+
let cancelled = false;
|
|
57
|
+
loadImageUrl(src).then(res => {
|
|
58
|
+
if (!cancelled)
|
|
59
|
+
setImgLoaded(res);
|
|
60
|
+
});
|
|
61
|
+
return () => {
|
|
62
|
+
cancelled = true;
|
|
63
|
+
};
|
|
64
|
+
}, [src]);
|
|
65
|
+
return imgLoaded ? (React.createElement(Image, { borderRadius: borderRadius, src: src })) : icon ? (React.createElement(Icon, { name: icon, size: iconSize })) : initials ? (React.createElement(React.Fragment, null, "initials")) : (React.createElement(Icon, { name: "falUser", size: iconSize }));
|
|
66
|
+
}
|
|
59
67
|
Avatar.displayName = 'Avatar';
|
|
60
68
|
export default Avatar;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"input.d.ts","sourceRoot":"","sources":["../../../src/input/input.tsx"],"names":[],"mappings":"AAGA,OAAO,EAA+B,YAAY,EAAE,MAAM,SAAS,CAAA;AAOnE,OAAO,QAAQ,MAAM,YAAY,CAAA;AACjC,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAC1C,OAAO,SAAS,MAAM,aAAa,CAAA;AACnC,OAAO,UAAU,MAAM,cAAc,CAAA;AAErC,eAAO,MAAM,SAAS,+
|
|
1
|
+
{"version":3,"file":"input.d.ts","sourceRoot":"","sources":["../../../src/input/input.tsx"],"names":[],"mappings":"AAGA,OAAO,EAA+B,YAAY,EAAE,MAAM,SAAS,CAAA;AAOnE,OAAO,QAAQ,MAAM,YAAY,CAAA;AACjC,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAC1C,OAAO,SAAS,MAAM,aAAa,CAAA;AACnC,OAAO,UAAU,MAAM,cAAc,CAAA;AAErC,eAAO,MAAM,SAAS,+HAoBrB,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,KAAK;UAuKV,gBAAgB;WACf,iBAAiB;cACd,eAAe;CAC1B,CAAA;AAOD,eAAe,KAAK,CAAA"}
|
package/dist/esm/input/input.js
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"images.d.ts","sourceRoot":"","sources":["../../../src/utils/images.ts"],"names":[],"mappings":"AAEA,kFAAkF;AAClF,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,oBAgBvC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
const loadImagePromises = new Map();
|
|
2
|
+
/** Attempts to load the image and returns a boolean indicating success or not. */
|
|
3
|
+
export function loadImageUrl(url) {
|
|
4
|
+
let promise = loadImagePromises.get(url);
|
|
5
|
+
if (promise)
|
|
6
|
+
return promise;
|
|
7
|
+
promise = new Promise(resolve => {
|
|
8
|
+
const img = new Image();
|
|
9
|
+
img.onload = () => {
|
|
10
|
+
// After this event occurs, you can use the url in the DOM. The browser will not make another request for the image; there will be no delay.
|
|
11
|
+
resolve(true);
|
|
12
|
+
};
|
|
13
|
+
img.onerror = () => {
|
|
14
|
+
resolve(false);
|
|
15
|
+
};
|
|
16
|
+
img.src = url;
|
|
17
|
+
});
|
|
18
|
+
loadImagePromises.set(url, promise);
|
|
19
|
+
return promise;
|
|
20
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@veracity/vui",
|
|
3
|
-
"version": "2.15.
|
|
3
|
+
"version": "2.15.3",
|
|
4
4
|
"description": "Veracity UI is a React component library crafted for use within Veracity applications and pages. Based on Styled Components and @xstyled.",
|
|
5
5
|
"module": "./dist/esm/index.js",
|
|
6
6
|
"main": "./dist/cjs/index.js",
|
package/src/avatar/avatar.tsx
CHANGED
|
@@ -1,21 +1,13 @@
|
|
|
1
|
-
import React from 'react'
|
|
1
|
+
import React, { useEffect, useState } from 'react'
|
|
2
2
|
|
|
3
3
|
import { omitThemingProps, styled, useStyleConfig, vui } from '../core'
|
|
4
|
-
import Icon from '../icon'
|
|
4
|
+
import Icon, { IconProp, IconProps } from '../icon'
|
|
5
5
|
import Image from '../image'
|
|
6
6
|
import { cs, filterUndefined } from '../utils'
|
|
7
|
+
import { loadImageUrl } from '../utils/images'
|
|
7
8
|
import { AvatarProps } from './avatar.types'
|
|
8
9
|
import { defaultGetInitials } from './helpers'
|
|
9
10
|
|
|
10
|
-
function imageExists(image_url: string) {
|
|
11
|
-
const http = new XMLHttpRequest()
|
|
12
|
-
|
|
13
|
-
http.open('HEAD', image_url, false)
|
|
14
|
-
http.send()
|
|
15
|
-
|
|
16
|
-
return http.status !== 404
|
|
17
|
-
}
|
|
18
|
-
|
|
19
11
|
export const AvatarBase = styled.spanBox`
|
|
20
12
|
align-items: center;
|
|
21
13
|
display: inline-flex;
|
|
@@ -57,8 +49,6 @@ export const Avatar = vui<'span', AvatarProps>((props, ref) => {
|
|
|
57
49
|
const borderRadius = isSquare ? (props.size === 'sm' ? '3px' : '6px') : '50%'
|
|
58
50
|
const initials = getInitials(name)
|
|
59
51
|
|
|
60
|
-
const internalIcon = src && !imageExists(src) ? 'falUser' : icon
|
|
61
|
-
|
|
62
52
|
const interactiveProps =
|
|
63
53
|
!disabled && isInteractive
|
|
64
54
|
? ({
|
|
@@ -92,16 +82,53 @@ export const Avatar = vui<'span', AvatarProps>((props, ref) => {
|
|
|
92
82
|
>
|
|
93
83
|
{children ? (
|
|
94
84
|
children
|
|
95
|
-
) : src
|
|
96
|
-
<
|
|
97
|
-
) :
|
|
98
|
-
<Icon name={
|
|
85
|
+
) : src ? (
|
|
86
|
+
<LazyImageOrDefault borderRadius={borderRadius} icon={icon} iconSize={iconSize} initials={initials} src={src} />
|
|
87
|
+
) : icon ? (
|
|
88
|
+
<Icon name={icon} size={iconSize} />
|
|
99
89
|
) : initials ? (
|
|
100
90
|
initials
|
|
101
|
-
) :
|
|
91
|
+
) : (
|
|
92
|
+
<Icon name="falUser" size={iconSize} />
|
|
93
|
+
)}
|
|
102
94
|
</AvatarBase>
|
|
103
95
|
)
|
|
104
96
|
})
|
|
105
97
|
|
|
98
|
+
function LazyImageOrDefault({
|
|
99
|
+
src,
|
|
100
|
+
borderRadius,
|
|
101
|
+
icon,
|
|
102
|
+
iconSize,
|
|
103
|
+
initials
|
|
104
|
+
}: {
|
|
105
|
+
src: string
|
|
106
|
+
borderRadius: string
|
|
107
|
+
icon: IconProp | undefined
|
|
108
|
+
iconSize: IconProps['size']
|
|
109
|
+
initials: string
|
|
110
|
+
}) {
|
|
111
|
+
const [imgLoaded, setImgLoaded] = useState(false)
|
|
112
|
+
useEffect(() => {
|
|
113
|
+
let cancelled = false
|
|
114
|
+
loadImageUrl(src).then(res => {
|
|
115
|
+
if (!cancelled) setImgLoaded(res)
|
|
116
|
+
})
|
|
117
|
+
return () => {
|
|
118
|
+
cancelled = true
|
|
119
|
+
}
|
|
120
|
+
}, [src])
|
|
121
|
+
|
|
122
|
+
return imgLoaded ? (
|
|
123
|
+
<Image borderRadius={borderRadius} src={src} />
|
|
124
|
+
) : icon ? (
|
|
125
|
+
<Icon name={icon} size={iconSize} />
|
|
126
|
+
) : initials ? (
|
|
127
|
+
<>initials</>
|
|
128
|
+
) : (
|
|
129
|
+
<Icon name="falUser" size={iconSize} />
|
|
130
|
+
)
|
|
131
|
+
}
|
|
132
|
+
|
|
106
133
|
Avatar.displayName = 'Avatar'
|
|
107
134
|
export default Avatar
|
package/src/input/input.tsx
CHANGED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
const loadImagePromises = new Map<string, Promise<boolean>>()
|
|
2
|
+
|
|
3
|
+
/** Attempts to load the image and returns a boolean indicating success or not. */
|
|
4
|
+
export function loadImageUrl(url: string) {
|
|
5
|
+
let promise = loadImagePromises.get(url)
|
|
6
|
+
if (promise) return promise
|
|
7
|
+
promise = new Promise(resolve => {
|
|
8
|
+
const img = new Image()
|
|
9
|
+
img.onload = () => {
|
|
10
|
+
// After this event occurs, you can use the url in the DOM. The browser will not make another request for the image; there will be no delay.
|
|
11
|
+
resolve(true)
|
|
12
|
+
}
|
|
13
|
+
img.onerror = () => {
|
|
14
|
+
resolve(false)
|
|
15
|
+
}
|
|
16
|
+
img.src = url
|
|
17
|
+
})
|
|
18
|
+
loadImagePromises.set(url, promise)
|
|
19
|
+
return promise
|
|
20
|
+
}
|