kopia lustrzana https://github.com/shoelace-style/shoelace
Add status to sl-error; rework request logic
rodzic
3bde111277
commit
dcd987b738
|
@ -1982,7 +1982,7 @@ declare namespace LocalJSX {
|
|||
/**
|
||||
* Emitted when the icon failed to load.
|
||||
*/
|
||||
"onSl-error"?: (event: CustomEvent<any>) => void;
|
||||
"onSl-error"?: (event: CustomEvent<{ status?: number }>) => void;
|
||||
/**
|
||||
* Emitted when the icon has loaded.
|
||||
*/
|
||||
|
@ -2046,7 +2046,7 @@ declare namespace LocalJSX {
|
|||
/**
|
||||
* Emitted when the included file fails to load due to an error.
|
||||
*/
|
||||
"onSl-error"?: (event: CustomEvent<{ status: number }>) => void;
|
||||
"onSl-error"?: (event: CustomEvent<{ status?: number }>) => void;
|
||||
/**
|
||||
* Emitted when the included file is loaded.
|
||||
*/
|
||||
|
|
|
@ -38,7 +38,7 @@ export class Icon {
|
|||
@Event({ eventName: 'sl-load' }) slLoad: EventEmitter;
|
||||
|
||||
/** Emitted when the icon failed to load. */
|
||||
@Event({ eventName: 'sl-error' }) slError: EventEmitter;
|
||||
@Event({ eventName: 'sl-error' }) slError: EventEmitter<{ status?: number }>;
|
||||
|
||||
@Watch('name')
|
||||
@Watch('src')
|
||||
|
@ -79,7 +79,7 @@ export class Icon {
|
|||
return label;
|
||||
}
|
||||
|
||||
setIcon() {
|
||||
async setIcon() {
|
||||
const library = getLibrary(this.library);
|
||||
let url = this.src;
|
||||
|
||||
|
@ -88,9 +88,10 @@ export class Icon {
|
|||
}
|
||||
|
||||
if (url) {
|
||||
requestIcon(url)
|
||||
.then(source => {
|
||||
const doc = parser.parseFromString(source, 'text/html');
|
||||
try {
|
||||
const file = await requestIcon(url);
|
||||
if (file.ok) {
|
||||
const doc = parser.parseFromString(file.svg, 'text/html');
|
||||
const svg = doc.body.querySelector('svg');
|
||||
|
||||
if (svg) {
|
||||
|
@ -102,10 +103,12 @@ export class Icon {
|
|||
this.slLoad.emit();
|
||||
} else {
|
||||
this.svg = '';
|
||||
this.slError.emit();
|
||||
this.slError.emit({ status: file.status });
|
||||
}
|
||||
})
|
||||
.catch(error => this.slError.emit(error));
|
||||
}
|
||||
} catch {
|
||||
this.slError.emit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,30 +1,36 @@
|
|||
const cache = new Map<string, string>();
|
||||
const requests = new Map<string, Promise<any>>();
|
||||
interface IconFile {
|
||||
ok: boolean;
|
||||
status: number;
|
||||
svg: string;
|
||||
}
|
||||
|
||||
const iconFiles = new Map<string, Promise<IconFile>>();
|
||||
|
||||
export const requestIcon = (url: string) => {
|
||||
let req = requests.get(url);
|
||||
|
||||
if (!req) {
|
||||
req = fetch(url).then(async res => {
|
||||
if (res.ok) {
|
||||
if (iconFiles.has(url)) {
|
||||
return iconFiles.get(url);
|
||||
} else {
|
||||
const request = fetch(url).then(async response => {
|
||||
if (response.ok) {
|
||||
const div = document.createElement('div');
|
||||
div.innerHTML = await res.text();
|
||||
|
||||
div.innerHTML = await response.text();
|
||||
const svg = div.firstElementChild;
|
||||
if (svg && svg.tagName.toLowerCase() === 'svg') {
|
||||
cache.set(url, div.innerHTML);
|
||||
return svg.outerHTML;
|
||||
} else {
|
||||
console.warn(`Invalid SVG icon: ${url}`);
|
||||
return '';
|
||||
}
|
||||
|
||||
return {
|
||||
ok: response.ok,
|
||||
status: response.status,
|
||||
svg: svg && svg.tagName.toLowerCase() === 'svg' ? svg.outerHTML : ''
|
||||
};
|
||||
} else {
|
||||
return '';
|
||||
return {
|
||||
ok: response.ok,
|
||||
status: response.status,
|
||||
svg: null
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
requests.set(url, req);
|
||||
iconFiles.set(url, request);
|
||||
return request;
|
||||
}
|
||||
|
||||
return req;
|
||||
};
|
||||
|
|
Ładowanie…
Reference in New Issue