mirror of
https://github.com/iconify/iconify.git
synced 2025-01-12 01:45:41 +00:00
Rewite API handling and export reusable _api.sendQuery function that can be used without adding API provider first
This commit is contained in:
parent
46988cf994
commit
96ced6e5de
@ -1,26 +1,26 @@
|
||||
import mocha from 'mocha';
|
||||
import chai from 'chai';
|
||||
|
||||
import { FakeData, setFakeData, prepareQuery, sendQuery } from './fake-api';
|
||||
import { API } from '@iconify/core/lib/api/';
|
||||
import { setAPIModule } from '@iconify/core/lib/api/modules';
|
||||
import { setAPIConfig } from '@iconify/core/lib/api/config';
|
||||
import { coreModules } from '@iconify/core/lib/modules';
|
||||
import { loadIcons } from '@iconify/core/lib/api/icons';
|
||||
|
||||
const expect = chai.expect;
|
||||
|
||||
// Set API
|
||||
setAPIModule('', {
|
||||
prepare: prepareQuery,
|
||||
send: sendQuery,
|
||||
});
|
||||
coreModules.api = API;
|
||||
|
||||
let prefixCounter = 0;
|
||||
function nextPrefix(): string {
|
||||
return 'fake-api-' + prefixCounter++;
|
||||
}
|
||||
|
||||
describe('Testing fake API', () => {
|
||||
before(() => {
|
||||
setAPIModule('', {
|
||||
prepare: prepareQuery,
|
||||
send: sendQuery,
|
||||
});
|
||||
});
|
||||
|
||||
it('Loading results', (done) => {
|
||||
const provider = nextPrefix();
|
||||
const prefix = nextPrefix();
|
||||
@ -30,12 +30,10 @@ describe('Testing fake API', () => {
|
||||
prefix,
|
||||
icons: {
|
||||
icon1: {
|
||||
body:
|
||||
'<path d="M10 20v-6h4v6h5v-8h3L12 3L2 12h3v8h5z" fill="currentColor"/>',
|
||||
body: '<path d="M10 20v-6h4v6h5v-8h3L12 3L2 12h3v8h5z" fill="currentColor"/>',
|
||||
},
|
||||
icon2: {
|
||||
body:
|
||||
'<path d="M12 4a4 4 0 0 1 4 4a4 4 0 0 1-4 4a4 4 0 0 1-4-4a4 4 0 0 1 4-4m0 10c4.42 0 8 1.79 8 4v2H4v-2c0-2.21 3.58-4 8-4z" fill="currentColor"/>',
|
||||
body: '<path d="M12 4a4 4 0 0 1 4 4a4 4 0 0 1-4 4a4 4 0 0 1-4-4a4 4 0 0 1 4-4m0 10c4.42 0 8 1.79 8 4v2H4v-2c0-2.21 3.58-4 8-4z" fill="currentColor"/>',
|
||||
},
|
||||
},
|
||||
width: 24,
|
||||
@ -48,7 +46,7 @@ describe('Testing fake API', () => {
|
||||
setFakeData(provider, prefix, data);
|
||||
|
||||
// Attempt to load icons
|
||||
API.loadIcons(
|
||||
loadIcons(
|
||||
[
|
||||
provider + ':' + prefix + ':icon1',
|
||||
provider + ':' + prefix + ':icon2',
|
||||
@ -81,12 +79,10 @@ describe('Testing fake API', () => {
|
||||
prefix,
|
||||
icons: {
|
||||
icon1: {
|
||||
body:
|
||||
'<path d="M10 20v-6h4v6h5v-8h3L12 3L2 12h3v8h5z" fill="currentColor"/>',
|
||||
body: '<path d="M10 20v-6h4v6h5v-8h3L12 3L2 12h3v8h5z" fill="currentColor"/>',
|
||||
},
|
||||
icon2: {
|
||||
body:
|
||||
'<path d="M12 4a4 4 0 0 1 4 4a4 4 0 0 1-4 4a4 4 0 0 1-4-4a4 4 0 0 1 4-4m0 10c4.42 0 8 1.79 8 4v2H4v-2c0-2.21 3.58-4 8-4z" fill="currentColor"/>',
|
||||
body: '<path d="M12 4a4 4 0 0 1 4 4a4 4 0 0 1-4 4a4 4 0 0 1-4-4a4 4 0 0 1 4-4m0 10c4.42 0 8 1.79 8 4v2H4v-2c0-2.21 3.58-4 8-4z" fill="currentColor"/>',
|
||||
},
|
||||
},
|
||||
width: 24,
|
||||
@ -100,7 +96,7 @@ describe('Testing fake API', () => {
|
||||
|
||||
// Attempt to load icons
|
||||
const start = Date.now();
|
||||
API.loadIcons(
|
||||
loadIcons(
|
||||
[
|
||||
{
|
||||
provider,
|
||||
@ -144,8 +140,7 @@ describe('Testing fake API', () => {
|
||||
prefix,
|
||||
icons: {
|
||||
icon1: {
|
||||
body:
|
||||
'<path d="M10 20v-6h4v6h5v-8h3L12 3L2 12h3v8h5z" fill="currentColor"/>',
|
||||
body: '<path d="M10 20v-6h4v6h5v-8h3L12 3L2 12h3v8h5z" fill="currentColor"/>',
|
||||
},
|
||||
},
|
||||
width: 24,
|
||||
@ -161,7 +156,7 @@ describe('Testing fake API', () => {
|
||||
|
||||
// Attempt to load icons
|
||||
let counter = 0;
|
||||
API.loadIcons(
|
||||
loadIcons(
|
||||
[
|
||||
provider + ':' + prefix + ':icon1',
|
||||
provider + ':' + prefix + ':icon2',
|
||||
|
@ -13,11 +13,13 @@ import { IconifyIconName } from '@iconify/utils/lib/icon/name';
|
||||
|
||||
const expect = chai.expect;
|
||||
|
||||
// Add finders
|
||||
addFinder(iconifyFinder);
|
||||
addFinder(iconifyIconFinder);
|
||||
|
||||
describe('Testing legacy finder', () => {
|
||||
before(() => {
|
||||
// Add finders
|
||||
addFinder(iconifyFinder);
|
||||
addFinder(iconifyIconFinder);
|
||||
});
|
||||
|
||||
it('Finding nodes', () => {
|
||||
const node = getNode('finder');
|
||||
node.innerHTML =
|
||||
|
@ -13,11 +13,13 @@ import { IconifyIconName } from '@iconify/utils/lib/icon/name';
|
||||
|
||||
const expect = chai.expect;
|
||||
|
||||
// Add finders
|
||||
addFinder(iconifyFinder);
|
||||
addFinder(iconifyIconFinder);
|
||||
|
||||
describe('Testing finder', () => {
|
||||
before(() => {
|
||||
// Add finders
|
||||
addFinder(iconifyFinder);
|
||||
addFinder(iconifyIconFinder);
|
||||
});
|
||||
|
||||
it('Finding nodes', () => {
|
||||
const node = getNode('finder');
|
||||
node.innerHTML =
|
||||
|
@ -19,31 +19,34 @@ import { IconifyElement } from '@iconify/iconify/lib/modules/element';
|
||||
|
||||
const expect = chai.expect;
|
||||
|
||||
// Add finders
|
||||
addFinder(iconifyIconFinder);
|
||||
addFinder(iconifyFinder);
|
||||
|
||||
describe('Testing legacy renderer', () => {
|
||||
// Add mentioned icons to storage
|
||||
const storage = getStorage('', 'mdi');
|
||||
addIconSet(storage, {
|
||||
prefix: 'mdi',
|
||||
icons: {
|
||||
'account-box': {
|
||||
body: '<path d="M6 17c0-2 4-3.1 6-3.1s6 1.1 6 3.1v1H6m9-9a3 3 0 0 1-3 3a3 3 0 0 1-3-3a3 3 0 0 1 3-3a3 3 0 0 1 3 3M3 5v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2z" fill="currentColor"/>',
|
||||
|
||||
before(() => {
|
||||
// Add finders
|
||||
addFinder(iconifyIconFinder);
|
||||
addFinder(iconifyFinder);
|
||||
|
||||
// Add mentioned icons to storage
|
||||
addIconSet(storage, {
|
||||
prefix: 'mdi',
|
||||
icons: {
|
||||
'account-box': {
|
||||
body: '<path d="M6 17c0-2 4-3.1 6-3.1s6 1.1 6 3.1v1H6m9-9a3 3 0 0 1-3 3a3 3 0 0 1-3-3a3 3 0 0 1 3-3a3 3 0 0 1 3 3M3 5v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2z" fill="currentColor"/>',
|
||||
},
|
||||
'account-cash': {
|
||||
body: '<path d="M11 8c0 2.21-1.79 4-4 4s-4-1.79-4-4s1.79-4 4-4s4 1.79 4 4m0 6.72V20H0v-2c0-2.21 3.13-4 7-4c1.5 0 2.87.27 4 .72M24 20H13V3h11v17m-8-8.5a2.5 2.5 0 0 1 5 0a2.5 2.5 0 0 1-5 0M22 7a2 2 0 0 1-2-2h-3c0 1.11-.89 2-2 2v9a2 2 0 0 1 2 2h3c0-1.1.9-2 2-2V7z" fill="currentColor"/>',
|
||||
},
|
||||
'account': {
|
||||
body: '<path d="M12 4a4 4 0 0 1 4 4a4 4 0 0 1-4 4a4 4 0 0 1-4-4a4 4 0 0 1 4-4m0 10c4.42 0 8 1.79 8 4v2H4v-2c0-2.21 3.58-4 8-4z" fill="currentColor"/>',
|
||||
},
|
||||
'home': {
|
||||
body: '<path d="M10 20v-6h4v6h5v-8h3L12 3L2 12h3v8h5z" fill="currentColor"/>',
|
||||
},
|
||||
},
|
||||
'account-cash': {
|
||||
body: '<path d="M11 8c0 2.21-1.79 4-4 4s-4-1.79-4-4s1.79-4 4-4s4 1.79 4 4m0 6.72V20H0v-2c0-2.21 3.13-4 7-4c1.5 0 2.87.27 4 .72M24 20H13V3h11v17m-8-8.5a2.5 2.5 0 0 1 5 0a2.5 2.5 0 0 1-5 0M22 7a2 2 0 0 1-2-2h-3c0 1.11-.89 2-2 2v9a2 2 0 0 1 2 2h3c0-1.1.9-2 2-2V7z" fill="currentColor"/>',
|
||||
},
|
||||
'account': {
|
||||
body: '<path d="M12 4a4 4 0 0 1 4 4a4 4 0 0 1-4 4a4 4 0 0 1-4-4a4 4 0 0 1 4-4m0 10c4.42 0 8 1.79 8 4v2H4v-2c0-2.21 3.58-4 8-4z" fill="currentColor"/>',
|
||||
},
|
||||
'home': {
|
||||
body: '<path d="M10 20v-6h4v6h5v-8h3L12 3L2 12h3v8h5z" fill="currentColor"/>',
|
||||
},
|
||||
},
|
||||
width: 24,
|
||||
height: 24,
|
||||
width: 24,
|
||||
height: 24,
|
||||
});
|
||||
});
|
||||
|
||||
it('Convert placeholders to SVG', () => {
|
||||
|
@ -19,31 +19,34 @@ import { IconifyElement } from '@iconify/iconify/lib/modules/element';
|
||||
|
||||
const expect = chai.expect;
|
||||
|
||||
// Add finders
|
||||
addFinder(iconifyIconFinder);
|
||||
addFinder(iconifyFinder);
|
||||
|
||||
describe('Testing renderer', () => {
|
||||
// Add mentioned icons to storage
|
||||
const storage = getStorage('', 'mdi');
|
||||
addIconSet(storage, {
|
||||
prefix: 'mdi',
|
||||
icons: {
|
||||
'account-box': {
|
||||
body: '<path d="M6 17c0-2 4-3.1 6-3.1s6 1.1 6 3.1v1H6m9-9a3 3 0 0 1-3 3a3 3 0 0 1-3-3a3 3 0 0 1 3-3a3 3 0 0 1 3 3M3 5v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2z" fill="currentColor"/>',
|
||||
|
||||
before(() => {
|
||||
// Add finders
|
||||
addFinder(iconifyIconFinder);
|
||||
addFinder(iconifyFinder);
|
||||
|
||||
// Add mentioned icons to storage
|
||||
addIconSet(storage, {
|
||||
prefix: 'mdi',
|
||||
icons: {
|
||||
'account-box': {
|
||||
body: '<path d="M6 17c0-2 4-3.1 6-3.1s6 1.1 6 3.1v1H6m9-9a3 3 0 0 1-3 3a3 3 0 0 1-3-3a3 3 0 0 1 3-3a3 3 0 0 1 3 3M3 5v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2z" fill="currentColor"/>',
|
||||
},
|
||||
'account-cash': {
|
||||
body: '<path d="M11 8c0 2.21-1.79 4-4 4s-4-1.79-4-4s1.79-4 4-4s4 1.79 4 4m0 6.72V20H0v-2c0-2.21 3.13-4 7-4c1.5 0 2.87.27 4 .72M24 20H13V3h11v17m-8-8.5a2.5 2.5 0 0 1 5 0a2.5 2.5 0 0 1-5 0M22 7a2 2 0 0 1-2-2h-3c0 1.11-.89 2-2 2v9a2 2 0 0 1 2 2h3c0-1.1.9-2 2-2V7z" fill="currentColor"/>',
|
||||
},
|
||||
'account': {
|
||||
body: '<path d="M12 4a4 4 0 0 1 4 4a4 4 0 0 1-4 4a4 4 0 0 1-4-4a4 4 0 0 1 4-4m0 10c4.42 0 8 1.79 8 4v2H4v-2c0-2.21 3.58-4 8-4z" fill="currentColor"/>',
|
||||
},
|
||||
'home': {
|
||||
body: '<path d="M10 20v-6h4v6h5v-8h3L12 3L2 12h3v8h5z" fill="currentColor"/>',
|
||||
},
|
||||
},
|
||||
'account-cash': {
|
||||
body: '<path d="M11 8c0 2.21-1.79 4-4 4s-4-1.79-4-4s1.79-4 4-4s4 1.79 4 4m0 6.72V20H0v-2c0-2.21 3.13-4 7-4c1.5 0 2.87.27 4 .72M24 20H13V3h11v17m-8-8.5a2.5 2.5 0 0 1 5 0a2.5 2.5 0 0 1-5 0M22 7a2 2 0 0 1-2-2h-3c0 1.11-.89 2-2 2v9a2 2 0 0 1 2 2h3c0-1.1.9-2 2-2V7z" fill="currentColor"/>',
|
||||
},
|
||||
'account': {
|
||||
body: '<path d="M12 4a4 4 0 0 1 4 4a4 4 0 0 1-4 4a4 4 0 0 1-4-4a4 4 0 0 1 4-4m0 10c4.42 0 8 1.79 8 4v2H4v-2c0-2.21 3.58-4 8-4z" fill="currentColor"/>',
|
||||
},
|
||||
'home': {
|
||||
body: '<path d="M10 20v-6h4v6h5v-8h3L12 3L2 12h3v8h5z" fill="currentColor"/>',
|
||||
},
|
||||
},
|
||||
width: 24,
|
||||
height: 24,
|
||||
width: 24,
|
||||
height: 24,
|
||||
});
|
||||
});
|
||||
|
||||
it('Convert placeholders to SVG', () => {
|
||||
|
@ -19,24 +19,21 @@ addFinder(iconifyIconFinder);
|
||||
describe('Scanning DOM', () => {
|
||||
// Add mentioned icons to storage
|
||||
const storage = getStorage('', 'mdi');
|
||||
|
||||
addIconSet(storage, {
|
||||
prefix: 'mdi',
|
||||
icons: {
|
||||
'account-box': {
|
||||
body:
|
||||
'<path d="M6 17c0-2 4-3.1 6-3.1s6 1.1 6 3.1v1H6m9-9a3 3 0 0 1-3 3a3 3 0 0 1-3-3a3 3 0 0 1 3-3a3 3 0 0 1 3 3M3 5v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2z" fill="currentColor"/>',
|
||||
body: '<path d="M6 17c0-2 4-3.1 6-3.1s6 1.1 6 3.1v1H6m9-9a3 3 0 0 1-3 3a3 3 0 0 1-3-3a3 3 0 0 1 3-3a3 3 0 0 1 3 3M3 5v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2z" fill="currentColor"/>',
|
||||
},
|
||||
'account-cash': {
|
||||
body:
|
||||
'<path d="M11 8c0 2.21-1.79 4-4 4s-4-1.79-4-4s1.79-4 4-4s4 1.79 4 4m0 6.72V20H0v-2c0-2.21 3.13-4 7-4c1.5 0 2.87.27 4 .72M24 20H13V3h11v17m-8-8.5a2.5 2.5 0 0 1 5 0a2.5 2.5 0 0 1-5 0M22 7a2 2 0 0 1-2-2h-3c0 1.11-.89 2-2 2v9a2 2 0 0 1 2 2h3c0-1.1.9-2 2-2V7z" fill="currentColor"/>',
|
||||
body: '<path d="M11 8c0 2.21-1.79 4-4 4s-4-1.79-4-4s1.79-4 4-4s4 1.79 4 4m0 6.72V20H0v-2c0-2.21 3.13-4 7-4c1.5 0 2.87.27 4 .72M24 20H13V3h11v17m-8-8.5a2.5 2.5 0 0 1 5 0a2.5 2.5 0 0 1-5 0M22 7a2 2 0 0 1-2-2h-3c0 1.11-.89 2-2 2v9a2 2 0 0 1 2 2h3c0-1.1.9-2 2-2V7z" fill="currentColor"/>',
|
||||
},
|
||||
'account': {
|
||||
body:
|
||||
'<path d="M12 4a4 4 0 0 1 4 4a4 4 0 0 1-4 4a4 4 0 0 1-4-4a4 4 0 0 1 4-4m0 10c4.42 0 8 1.79 8 4v2H4v-2c0-2.21 3.58-4 8-4z" fill="currentColor"/>',
|
||||
body: '<path d="M12 4a4 4 0 0 1 4 4a4 4 0 0 1-4 4a4 4 0 0 1-4-4a4 4 0 0 1 4-4m0 10c4.42 0 8 1.79 8 4v2H4v-2c0-2.21 3.58-4 8-4z" fill="currentColor"/>',
|
||||
},
|
||||
'home': {
|
||||
body:
|
||||
'<path d="M10 20v-6h4v6h5v-8h3L12 3L2 12h3v8h5z" fill="currentColor"/>',
|
||||
body: '<path d="M10 20v-6h4v6h5v-8h3L12 3L2 12h3v8h5z" fill="currentColor"/>',
|
||||
},
|
||||
},
|
||||
width: 24,
|
||||
|
@ -16,35 +16,34 @@ import {
|
||||
|
||||
const expect = chai.expect;
|
||||
|
||||
// Add finders
|
||||
addFinder(iconifyFinder);
|
||||
addFinder(iconifyIconFinder);
|
||||
|
||||
describe('Observe DOM', () => {
|
||||
// Add mentioned icons to storage
|
||||
const storage = getStorage('', 'mdi');
|
||||
addIconSet(storage, {
|
||||
prefix: 'mdi',
|
||||
icons: {
|
||||
'account-box': {
|
||||
body:
|
||||
'<path d="M6 17c0-2 4-3.1 6-3.1s6 1.1 6 3.1v1H6m9-9a3 3 0 0 1-3 3a3 3 0 0 1-3-3a3 3 0 0 1 3-3a3 3 0 0 1 3 3M3 5v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2z" fill="currentColor"/>',
|
||||
|
||||
before(() => {
|
||||
// Add finders
|
||||
addFinder(iconifyFinder);
|
||||
addFinder(iconifyIconFinder);
|
||||
|
||||
// Add mentioned icons to storage
|
||||
addIconSet(storage, {
|
||||
prefix: 'mdi',
|
||||
icons: {
|
||||
'account-box': {
|
||||
body: '<path d="M6 17c0-2 4-3.1 6-3.1s6 1.1 6 3.1v1H6m9-9a3 3 0 0 1-3 3a3 3 0 0 1-3-3a3 3 0 0 1 3-3a3 3 0 0 1 3 3M3 5v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2z" fill="currentColor"/>',
|
||||
},
|
||||
'account-cash': {
|
||||
body: '<path d="M11 8c0 2.21-1.79 4-4 4s-4-1.79-4-4s1.79-4 4-4s4 1.79 4 4m0 6.72V20H0v-2c0-2.21 3.13-4 7-4c1.5 0 2.87.27 4 .72M24 20H13V3h11v17m-8-8.5a2.5 2.5 0 0 1 5 0a2.5 2.5 0 0 1-5 0M22 7a2 2 0 0 1-2-2h-3c0 1.11-.89 2-2 2v9a2 2 0 0 1 2 2h3c0-1.1.9-2 2-2V7z" fill="currentColor"/>',
|
||||
},
|
||||
'account': {
|
||||
body: '<path d="M12 4a4 4 0 0 1 4 4a4 4 0 0 1-4 4a4 4 0 0 1-4-4a4 4 0 0 1 4-4m0 10c4.42 0 8 1.79 8 4v2H4v-2c0-2.21 3.58-4 8-4z" fill="currentColor"/>',
|
||||
},
|
||||
'home': {
|
||||
body: '<path d="M10 20v-6h4v6h5v-8h3L12 3L2 12h3v8h5z" fill="currentColor"/>',
|
||||
},
|
||||
},
|
||||
'account-cash': {
|
||||
body:
|
||||
'<path d="M11 8c0 2.21-1.79 4-4 4s-4-1.79-4-4s1.79-4 4-4s4 1.79 4 4m0 6.72V20H0v-2c0-2.21 3.13-4 7-4c1.5 0 2.87.27 4 .72M24 20H13V3h11v17m-8-8.5a2.5 2.5 0 0 1 5 0a2.5 2.5 0 0 1-5 0M22 7a2 2 0 0 1-2-2h-3c0 1.11-.89 2-2 2v9a2 2 0 0 1 2 2h3c0-1.1.9-2 2-2V7z" fill="currentColor"/>',
|
||||
},
|
||||
'account': {
|
||||
body:
|
||||
'<path d="M12 4a4 4 0 0 1 4 4a4 4 0 0 1-4 4a4 4 0 0 1-4-4a4 4 0 0 1 4-4m0 10c4.42 0 8 1.79 8 4v2H4v-2c0-2.21 3.58-4 8-4z" fill="currentColor"/>',
|
||||
},
|
||||
'home': {
|
||||
body:
|
||||
'<path d="M10 20v-6h4v6h5v-8h3L12 3L2 12h3v8h5z" fill="currentColor"/>',
|
||||
},
|
||||
},
|
||||
width: 24,
|
||||
height: 24,
|
||||
width: 24,
|
||||
height: 24,
|
||||
});
|
||||
});
|
||||
|
||||
it('Basic test', (done) => {
|
||||
|
@ -4,10 +4,8 @@ import chai from 'chai';
|
||||
import { getNode, setRoot } from './node';
|
||||
import { addFinder } from '@iconify/iconify/lib/modules/finder';
|
||||
import { FakeData, setFakeData, prepareQuery, sendQuery } from './fake-api';
|
||||
import { API } from '@iconify/core/lib/api/';
|
||||
import { setAPIModule } from '@iconify/core/lib/api/modules';
|
||||
import { setAPIConfig } from '@iconify/core/lib/api/config';
|
||||
import { coreModules } from '@iconify/core/lib/modules';
|
||||
import { finder as iconifyFinder } from '@iconify/iconify/lib/finders/iconify';
|
||||
import { finder as iconifyIconFinder } from '@iconify/iconify/lib/finders/iconify-icon';
|
||||
import { listRootNodes } from '@iconify/iconify/lib/modules/root';
|
||||
@ -15,23 +13,24 @@ import { scanDOM, scanElement } from '@iconify/iconify/lib/modules/scanner';
|
||||
|
||||
const expect = chai.expect;
|
||||
|
||||
// Add finders
|
||||
addFinder(iconifyFinder);
|
||||
addFinder(iconifyIconFinder);
|
||||
|
||||
// Set API
|
||||
setAPIModule('', {
|
||||
prepare: prepareQuery,
|
||||
send: sendQuery,
|
||||
});
|
||||
coreModules.api = API;
|
||||
|
||||
let prefixCounter = 0;
|
||||
function nextPrefix(): string {
|
||||
return 'scan-dom-api-' + prefixCounter++;
|
||||
}
|
||||
|
||||
describe('Scanning DOM with API', () => {
|
||||
before(() => {
|
||||
// Add finders
|
||||
addFinder(iconifyFinder);
|
||||
addFinder(iconifyIconFinder);
|
||||
|
||||
// Set API
|
||||
setAPIModule('', {
|
||||
prepare: prepareQuery,
|
||||
send: sendQuery,
|
||||
});
|
||||
});
|
||||
|
||||
it('Scan DOM with API', (done) => {
|
||||
const provider = nextPrefix();
|
||||
const prefix1 = nextPrefix();
|
||||
@ -50,12 +49,10 @@ describe('Scanning DOM with API', () => {
|
||||
prefix: prefix1,
|
||||
icons: {
|
||||
'account-cash': {
|
||||
body:
|
||||
'<path d="M11 8c0 2.21-1.79 4-4 4s-4-1.79-4-4s1.79-4 4-4s4 1.79 4 4m0 6.72V20H0v-2c0-2.21 3.13-4 7-4c1.5 0 2.87.27 4 .72M24 20H13V3h11v17m-8-8.5a2.5 2.5 0 0 1 5 0a2.5 2.5 0 0 1-5 0M22 7a2 2 0 0 1-2-2h-3c0 1.11-.89 2-2 2v9a2 2 0 0 1 2 2h3c0-1.1.9-2 2-2V7z" fill="currentColor"/>',
|
||||
body: '<path d="M11 8c0 2.21-1.79 4-4 4s-4-1.79-4-4s1.79-4 4-4s4 1.79 4 4m0 6.72V20H0v-2c0-2.21 3.13-4 7-4c1.5 0 2.87.27 4 .72M24 20H13V3h11v17m-8-8.5a2.5 2.5 0 0 1 5 0a2.5 2.5 0 0 1-5 0M22 7a2 2 0 0 1-2-2h-3c0 1.11-.89 2-2 2v9a2 2 0 0 1 2 2h3c0-1.1.9-2 2-2V7z" fill="currentColor"/>',
|
||||
},
|
||||
'home': {
|
||||
body:
|
||||
'<path d="M10 20v-6h4v6h5v-8h3L12 3L2 12h3v8h5z" fill="currentColor"/>',
|
||||
body: '<path d="M10 20v-6h4v6h5v-8h3L12 3L2 12h3v8h5z" fill="currentColor"/>',
|
||||
},
|
||||
},
|
||||
width: 24,
|
||||
@ -71,12 +68,10 @@ describe('Scanning DOM with API', () => {
|
||||
prefix: prefix2,
|
||||
icons: {
|
||||
'account-box': {
|
||||
body:
|
||||
'<path d="M6 17c0-2 4-3.1 6-3.1s6 1.1 6 3.1v1H6m9-9a3 3 0 0 1-3 3a3 3 0 0 1-3-3a3 3 0 0 1 3-3a3 3 0 0 1 3 3M3 5v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2z" fill="currentColor"/>',
|
||||
body: '<path d="M6 17c0-2 4-3.1 6-3.1s6 1.1 6 3.1v1H6m9-9a3 3 0 0 1-3 3a3 3 0 0 1-3-3a3 3 0 0 1 3-3a3 3 0 0 1 3 3M3 5v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2z" fill="currentColor"/>',
|
||||
},
|
||||
'account': {
|
||||
body:
|
||||
'<path d="M12 4a4 4 0 0 1 4 4a4 4 0 0 1-4 4a4 4 0 0 1-4-4a4 4 0 0 1 4-4m0 10c4.42 0 8 1.79 8 4v2H4v-2c0-2.21 3.58-4 8-4z" fill="currentColor"/>',
|
||||
body: '<path d="M12 4a4 4 0 0 1 4 4a4 4 0 0 1-4 4a4 4 0 0 1-4-4a4 4 0 0 1 4-4m0 10c4.42 0 8 1.79 8 4v2H4v-2c0-2.21 3.58-4 8-4z" fill="currentColor"/>',
|
||||
},
|
||||
},
|
||||
width: 24,
|
||||
@ -163,12 +158,10 @@ describe('Scanning DOM with API', () => {
|
||||
prefix: prefix1,
|
||||
icons: {
|
||||
'account-cash': {
|
||||
body:
|
||||
'<path d="M11 8c0 2.21-1.79 4-4 4s-4-1.79-4-4s1.79-4 4-4s4 1.79 4 4m0 6.72V20H0v-2c0-2.21 3.13-4 7-4c1.5 0 2.87.27 4 .72M24 20H13V3h11v17m-8-8.5a2.5 2.5 0 0 1 5 0a2.5 2.5 0 0 1-5 0M22 7a2 2 0 0 1-2-2h-3c0 1.11-.89 2-2 2v9a2 2 0 0 1 2 2h3c0-1.1.9-2 2-2V7z" fill="currentColor"/>',
|
||||
body: '<path d="M11 8c0 2.21-1.79 4-4 4s-4-1.79-4-4s1.79-4 4-4s4 1.79 4 4m0 6.72V20H0v-2c0-2.21 3.13-4 7-4c1.5 0 2.87.27 4 .72M24 20H13V3h11v17m-8-8.5a2.5 2.5 0 0 1 5 0a2.5 2.5 0 0 1-5 0M22 7a2 2 0 0 1-2-2h-3c0 1.11-.89 2-2 2v9a2 2 0 0 1 2 2h3c0-1.1.9-2 2-2V7z" fill="currentColor"/>',
|
||||
},
|
||||
'home': {
|
||||
body:
|
||||
'<path d="M10 20v-6h4v6h5v-8h3L12 3L2 12h3v8h5z" fill="currentColor"/>',
|
||||
body: '<path d="M10 20v-6h4v6h5v-8h3L12 3L2 12h3v8h5z" fill="currentColor"/>',
|
||||
},
|
||||
},
|
||||
width: 24,
|
||||
@ -184,12 +177,10 @@ describe('Scanning DOM with API', () => {
|
||||
prefix: prefix2,
|
||||
icons: {
|
||||
'account-box': {
|
||||
body:
|
||||
'<path d="M6 17c0-2 4-3.1 6-3.1s6 1.1 6 3.1v1H6m9-9a3 3 0 0 1-3 3a3 3 0 0 1-3-3a3 3 0 0 1 3-3a3 3 0 0 1 3 3M3 5v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2z" fill="currentColor"/>',
|
||||
body: '<path d="M6 17c0-2 4-3.1 6-3.1s6 1.1 6 3.1v1H6m9-9a3 3 0 0 1-3 3a3 3 0 0 1-3-3a3 3 0 0 1 3-3a3 3 0 0 1 3 3M3 5v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2z" fill="currentColor"/>',
|
||||
},
|
||||
'account': {
|
||||
body:
|
||||
'<path d="M12 4a4 4 0 0 1 4 4a4 4 0 0 1-4 4a4 4 0 0 1-4-4a4 4 0 0 1 4-4m0 10c4.42 0 8 1.79 8 4v2H4v-2c0-2.21 3.58-4 8-4z" fill="currentColor"/>',
|
||||
body: '<path d="M12 4a4 4 0 0 1 4 4a4 4 0 0 1-4 4a4 4 0 0 1-4-4a4 4 0 0 1 4-4m0 10c4.42 0 8 1.79 8 4v2H4v-2c0-2.21 3.58-4 8-4z" fill="currentColor"/>',
|
||||
},
|
||||
},
|
||||
width: 24,
|
||||
@ -205,12 +196,10 @@ describe('Scanning DOM with API', () => {
|
||||
prefix: prefix1,
|
||||
icons: {
|
||||
'account-box': {
|
||||
body:
|
||||
'<path d="M6 17c0-2 4-3.1 6-3.1s6 1.1 6 3.1v1H6m9-9a3 3 0 0 1-3 3a3 3 0 0 1-3-3a3 3 0 0 1 3-3a3 3 0 0 1 3 3M3 5v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2z" fill="currentColor"/>',
|
||||
body: '<path d="M6 17c0-2 4-3.1 6-3.1s6 1.1 6 3.1v1H6m9-9a3 3 0 0 1-3 3a3 3 0 0 1-3-3a3 3 0 0 1 3-3a3 3 0 0 1 3 3M3 5v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2z" fill="currentColor"/>',
|
||||
},
|
||||
'account': {
|
||||
body:
|
||||
'<path d="M12 4a4 4 0 0 1 4 4a4 4 0 0 1-4 4a4 4 0 0 1-4-4a4 4 0 0 1 4-4m0 10c4.42 0 8 1.79 8 4v2H4v-2c0-2.21 3.58-4 8-4z" fill="currentColor"/>',
|
||||
body: '<path d="M12 4a4 4 0 0 1 4 4a4 4 0 0 1-4 4a4 4 0 0 1-4-4a4 4 0 0 1 4-4m0 10c4.42 0 8 1.79 8 4v2H4v-2c0-2.21 3.58-4 8-4z" fill="currentColor"/>',
|
||||
},
|
||||
},
|
||||
width: 24,
|
||||
@ -318,12 +307,10 @@ describe('Scanning DOM with API', () => {
|
||||
prefix: prefix1,
|
||||
icons: {
|
||||
'account-cash': {
|
||||
body:
|
||||
'<path d="M11 8c0 2.21-1.79 4-4 4s-4-1.79-4-4s1.79-4 4-4s4 1.79 4 4m0 6.72V20H0v-2c0-2.21 3.13-4 7-4c1.5 0 2.87.27 4 .72M24 20H13V3h11v17m-8-8.5a2.5 2.5 0 0 1 5 0a2.5 2.5 0 0 1-5 0M22 7a2 2 0 0 1-2-2h-3c0 1.11-.89 2-2 2v9a2 2 0 0 1 2 2h3c0-1.1.9-2 2-2V7z" fill="currentColor"/>',
|
||||
body: '<path d="M11 8c0 2.21-1.79 4-4 4s-4-1.79-4-4s1.79-4 4-4s4 1.79 4 4m0 6.72V20H0v-2c0-2.21 3.13-4 7-4c1.5 0 2.87.27 4 .72M24 20H13V3h11v17m-8-8.5a2.5 2.5 0 0 1 5 0a2.5 2.5 0 0 1-5 0M22 7a2 2 0 0 1-2-2h-3c0 1.11-.89 2-2 2v9a2 2 0 0 1 2 2h3c0-1.1.9-2 2-2V7z" fill="currentColor"/>',
|
||||
},
|
||||
'home': {
|
||||
body:
|
||||
'<path d="M10 20v-6h4v6h5v-8h3L12 3L2 12h3v8h5z" fill="currentColor"/>',
|
||||
body: '<path d="M10 20v-6h4v6h5v-8h3L12 3L2 12h3v8h5z" fill="currentColor"/>',
|
||||
},
|
||||
},
|
||||
width: 24,
|
||||
@ -339,12 +326,10 @@ describe('Scanning DOM with API', () => {
|
||||
prefix: prefix2,
|
||||
icons: {
|
||||
'account-box': {
|
||||
body:
|
||||
'<path d="M6 17c0-2 4-3.1 6-3.1s6 1.1 6 3.1v1H6m9-9a3 3 0 0 1-3 3a3 3 0 0 1-3-3a3 3 0 0 1 3-3a3 3 0 0 1 3 3M3 5v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2z" fill="currentColor"/>',
|
||||
body: '<path d="M6 17c0-2 4-3.1 6-3.1s6 1.1 6 3.1v1H6m9-9a3 3 0 0 1-3 3a3 3 0 0 1-3-3a3 3 0 0 1 3-3a3 3 0 0 1 3 3M3 5v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2z" fill="currentColor"/>',
|
||||
},
|
||||
'account': {
|
||||
body:
|
||||
'<path d="M12 4a4 4 0 0 1 4 4a4 4 0 0 1-4 4a4 4 0 0 1-4-4a4 4 0 0 1 4-4m0 10c4.42 0 8 1.79 8 4v2H4v-2c0-2.21 3.58-4 8-4z" fill="currentColor"/>',
|
||||
body: '<path d="M12 4a4 4 0 0 1 4 4a4 4 0 0 1-4 4a4 4 0 0 1-4-4a4 4 0 0 1 4-4m0 10c4.42 0 8 1.79 8 4v2H4v-2c0-2.21 3.58-4 8-4z" fill="currentColor"/>',
|
||||
},
|
||||
},
|
||||
width: 24,
|
||||
@ -423,8 +408,7 @@ describe('Scanning DOM with API', () => {
|
||||
prefix,
|
||||
icons: {
|
||||
home: {
|
||||
body:
|
||||
'<path d="M10 20v-6h4v6h5v-8h3L12 3L2 12h3v8h5z" fill="currentColor"/>',
|
||||
body: '<path d="M10 20v-6h4v6h5v-8h3L12 3L2 12h3v8h5z" fill="currentColor"/>',
|
||||
},
|
||||
},
|
||||
width: 24,
|
||||
|
@ -1,7 +1,8 @@
|
||||
import { PendingQueryItem } from '@cyberalien/redundancy';
|
||||
import {
|
||||
APIQueryParams,
|
||||
IconifyAPIPrepareQuery,
|
||||
IconifyAPIIconsQueryParams,
|
||||
IconifyAPIQueryParams,
|
||||
IconifyAPIPrepareIconsQuery,
|
||||
IconifyAPISendQuery,
|
||||
} from '@iconify/core/lib/api/modules';
|
||||
import { IconifyJSON } from '@iconify/types';
|
||||
@ -38,20 +39,20 @@ export function setFakeData(
|
||||
providerFakeData[prefix].push(item);
|
||||
}
|
||||
|
||||
interface FakeAPIQueryParams extends APIQueryParams {
|
||||
interface FakeAPIQueryParams extends IconifyAPIIconsQueryParams {
|
||||
data: FakeData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare params
|
||||
*/
|
||||
export const prepareQuery: IconifyAPIPrepareQuery = (
|
||||
export const prepareQuery: IconifyAPIPrepareIconsQuery = (
|
||||
provider: string,
|
||||
prefix: string,
|
||||
icons: string[]
|
||||
): APIQueryParams[] => {
|
||||
): IconifyAPIIconsQueryParams[] => {
|
||||
// Find items that have query
|
||||
const items: APIQueryParams[] = [];
|
||||
const items: IconifyAPIIconsQueryParams[] = [];
|
||||
let missing = icons.slice(0);
|
||||
|
||||
if (fakeData[provider] === void 0) {
|
||||
@ -59,6 +60,7 @@ export const prepareQuery: IconifyAPIPrepareQuery = (
|
||||
}
|
||||
const providerFakeData = fakeData[provider];
|
||||
|
||||
const type = 'icons';
|
||||
if (providerFakeData[prefix] !== void 0) {
|
||||
providerFakeData[prefix].forEach((item) => {
|
||||
const matches = item.icons.filter(
|
||||
@ -72,6 +74,7 @@ export const prepareQuery: IconifyAPIPrepareQuery = (
|
||||
// Contains at least one matching icon
|
||||
missing = missing.filter((icon) => matches.indexOf(icon) === -1);
|
||||
const query: FakeAPIQueryParams = {
|
||||
type,
|
||||
provider,
|
||||
prefix,
|
||||
icons: matches,
|
||||
@ -89,9 +92,15 @@ export const prepareQuery: IconifyAPIPrepareQuery = (
|
||||
*/
|
||||
export const sendQuery: IconifyAPISendQuery = (
|
||||
host: string,
|
||||
params: APIQueryParams,
|
||||
params: IconifyAPIQueryParams,
|
||||
status: PendingQueryItem
|
||||
): void => {
|
||||
if (params.type !== 'icons') {
|
||||
// Fake API supports only icons
|
||||
status.done(void 0, 400);
|
||||
return;
|
||||
}
|
||||
|
||||
const provider = params.provider;
|
||||
const prefix = params.prefix;
|
||||
const icons = params.icons;
|
||||
|
@ -2,7 +2,7 @@
|
||||
"name": "@iconify/core",
|
||||
"description": "Reusable files used by multiple Iconify packages",
|
||||
"author": "Vjacheslav Trushkin <cyberalien@gmail.com> (https://iconify.design)",
|
||||
"version": "1.1.3",
|
||||
"version": "1.2.0",
|
||||
"license": "(Apache-2.0 OR GPL-2.0)",
|
||||
"bugs": "https://github.com/iconify/iconify/issues",
|
||||
"homepage": "https://iconify.design/",
|
||||
|
@ -1,7 +1,7 @@
|
||||
import type {
|
||||
IconifyIconLoaderCallback,
|
||||
IconifyIconLoaderAbort,
|
||||
} from '../interfaces/loader';
|
||||
} from './icons';
|
||||
import { getStorage } from '../storage/storage';
|
||||
import type { SortedIcons } from '../icon/sort';
|
||||
import type { IconifyIconSource } from '@iconify/utils/lib/icon/name';
|
||||
@ -25,10 +25,13 @@ interface CallbackItem {
|
||||
|
||||
// Records sorted by provider and prefix
|
||||
// This export is only for unit testing, should not be used
|
||||
export const callbacks: Record<string, Record<string, CallbackItem[]>> =
|
||||
Object.create(null);
|
||||
const pendingUpdates: Record<string, Record<string, boolean>> =
|
||||
Object.create(null);
|
||||
export const callbacks: Record<
|
||||
string,
|
||||
Record<string, CallbackItem[]>
|
||||
> = Object.create(null);
|
||||
const pendingUpdates: Record<string, Record<string, boolean>> = Object.create(
|
||||
null
|
||||
);
|
||||
|
||||
/**
|
||||
* Remove callback
|
||||
|
@ -16,7 +16,7 @@ export type PartialIconifyAPIConfig = Partial<IconifyAPIConfig>;
|
||||
/**
|
||||
* Create full API configuration from partial data
|
||||
*/
|
||||
function createConfig(
|
||||
export function createAPIConfig(
|
||||
source: PartialIconifyAPIConfig
|
||||
): IconifyAPIConfig | null {
|
||||
let resources;
|
||||
@ -99,7 +99,7 @@ while (fallBackAPISources.length > 0) {
|
||||
}
|
||||
|
||||
// Add default API
|
||||
configStorage[''] = createConfig({
|
||||
configStorage[''] = createAPIConfig({
|
||||
resources: ['https://api.iconify.design'].concat(fallBackAPI),
|
||||
}) as IconifyAPIConfig;
|
||||
|
||||
@ -110,7 +110,7 @@ export function setAPIConfig(
|
||||
provider: string,
|
||||
customConfig: PartialIconifyAPIConfig
|
||||
): boolean {
|
||||
const config = createConfig(customConfig);
|
||||
const config = createAPIConfig(customConfig);
|
||||
if (config === null) {
|
||||
return false;
|
||||
}
|
||||
@ -126,9 +126,9 @@ export type GetAPIConfig = (provider: string) => IconifyAPIConfig | undefined;
|
||||
/**
|
||||
* Get API configuration
|
||||
*/
|
||||
export const getAPIConfig: GetAPIConfig = (
|
||||
provider: string
|
||||
): IconifyAPIConfig | undefined => configStorage[provider];
|
||||
export function getAPIConfig(provider: string): IconifyAPIConfig | undefined {
|
||||
return configStorage[provider];
|
||||
}
|
||||
|
||||
/**
|
||||
* List API providers
|
||||
|
@ -1,19 +1,28 @@
|
||||
import { API } from '.';
|
||||
import type { IconifyIconName } from '@iconify/utils/lib/icon/name';
|
||||
import { sendAPIQuery } from './query';
|
||||
import { loadIcons } from './icons';
|
||||
import type {
|
||||
IconifyIconLoaderAbort,
|
||||
IconifyIconLoaderCallback,
|
||||
} from '../interfaces/loader';
|
||||
import type { GetAPIConfig, IconifyAPIConfig } from './config';
|
||||
} from './icons';
|
||||
import type {
|
||||
GetAPIConfig,
|
||||
IconifyAPIConfig,
|
||||
PartialIconifyAPIConfig,
|
||||
} from './config';
|
||||
import { getAPIConfig, setAPIConfig } from './config';
|
||||
import type {
|
||||
IconifyAPIModule,
|
||||
IconifyAPIQueryParams,
|
||||
IconifyAPICustomQueryParams,
|
||||
} from './modules';
|
||||
import { setAPIModule, getAPIModule } from './modules';
|
||||
import { setAPIModule } from './modules';
|
||||
import type { MergeParams, IconifyAPIMergeQueryParams } from './params';
|
||||
import { mergeParams } from './params';
|
||||
import type {
|
||||
QueryAbortCallback,
|
||||
QueryDoneCallback,
|
||||
} from '@cyberalien/redundancy';
|
||||
|
||||
/**
|
||||
* Iconify API functions
|
||||
@ -37,7 +46,7 @@ export interface IconifyAPIFunctions {
|
||||
}
|
||||
|
||||
export const APIFunctions: IconifyAPIFunctions = {
|
||||
loadIcons: API.loadIcons,
|
||||
loadIcons,
|
||||
addAPIProvider: setAPIConfig,
|
||||
};
|
||||
|
||||
@ -55,14 +64,18 @@ export interface IconifyAPIInternalFunctions {
|
||||
getAPIConfig: GetAPIConfig;
|
||||
|
||||
/**
|
||||
* Set API module
|
||||
* Set custom API module
|
||||
*/
|
||||
setAPIModule: (provider: string, item: IconifyAPIModule) => void;
|
||||
|
||||
/**
|
||||
* Get API module
|
||||
* Send API query
|
||||
*/
|
||||
getAPIModule: (provider: string) => IconifyAPIModule | undefined;
|
||||
sendAPIQuery: (
|
||||
target: string | PartialIconifyAPIConfig,
|
||||
query: IconifyAPIQueryParams,
|
||||
callback: QueryDoneCallback
|
||||
) => QueryAbortCallback;
|
||||
|
||||
/**
|
||||
* Optional setFetch and getFetch (should be imported from ./modules/fetch if fetch is used)
|
||||
@ -79,7 +92,7 @@ export interface IconifyAPIInternalFunctions {
|
||||
export const APIInternalFunctions: IconifyAPIInternalFunctions = {
|
||||
getAPIConfig,
|
||||
setAPIModule,
|
||||
getAPIModule,
|
||||
sendAPIQuery,
|
||||
mergeParams,
|
||||
};
|
||||
|
||||
|
@ -1,32 +1,53 @@
|
||||
import type { Redundancy, QueryModuleCallback } from '@cyberalien/redundancy';
|
||||
import type { IconifyJSON } from '@iconify/types';
|
||||
import { initRedundancy } from '@cyberalien/redundancy';
|
||||
import type { SortedIcons } from '../icon/sort';
|
||||
import { sortIcons } from '../icon/sort';
|
||||
import type {
|
||||
IconifyIconLoaderAbort,
|
||||
IconifyIconLoaderCallback,
|
||||
IconifyLoadIcons,
|
||||
} from '../interfaces/loader';
|
||||
import type { IsPending, IconifyAPI } from '../interfaces/api';
|
||||
import { storeCallback, updateCallbacks } from './callbacks';
|
||||
import { getAPIModule } from './modules';
|
||||
import type { IconifyAPIConfig } from './config';
|
||||
import { getAPIConfig } from './config';
|
||||
import { getStorage, addIconSet } from '../storage/storage';
|
||||
import { coreModules } from '../modules';
|
||||
import type {
|
||||
IconifyIconName,
|
||||
IconifyIconSource,
|
||||
} from '@iconify/utils/lib/icon/name';
|
||||
import { listToIcons } from '../icon/list';
|
||||
import { allowSimpleNames } from '../storage/functions';
|
||||
import { sendAPIQuery } from './query';
|
||||
import { cache } from '../cache';
|
||||
|
||||
// Empty abort callback for loadIcons()
|
||||
function emptyCallback(): void {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to abort loading (usually just removes callback because loading is already in progress)
|
||||
*/
|
||||
export type IconifyIconLoaderAbort = () => void;
|
||||
|
||||
/**
|
||||
* Loader callback
|
||||
*
|
||||
* Provides list of icons that have been loaded
|
||||
*/
|
||||
export type IconifyIconLoaderCallback = (
|
||||
loaded: IconifyIconName[],
|
||||
missing: IconifyIconName[],
|
||||
pending: IconifyIconName[],
|
||||
unsubscribe: IconifyIconLoaderAbort
|
||||
) => void;
|
||||
|
||||
/**
|
||||
* Function to load icons
|
||||
*/
|
||||
export type IconifyLoadIcons = (
|
||||
icons: (IconifyIconName | string)[],
|
||||
callback?: IconifyIconLoaderCallback
|
||||
) => IconifyIconLoaderAbort;
|
||||
|
||||
/**
|
||||
* Function to check if icon is pending
|
||||
*/
|
||||
export type IsPending = (icon: IconifyIconName) => boolean;
|
||||
|
||||
/**
|
||||
* List of icons that are being loaded.
|
||||
*
|
||||
@ -63,38 +84,6 @@ const loaderFlags: Record<string, Record<string, boolean>> = Object.create(
|
||||
);
|
||||
const queueFlags: Record<string, Record<string, boolean>> = Object.create(null);
|
||||
|
||||
// Redundancy instances cache, sorted by provider
|
||||
interface IconifyAPIInternalStorage {
|
||||
config: IconifyAPIConfig;
|
||||
redundancy: Redundancy;
|
||||
}
|
||||
const redundancyCache: Record<string, IconifyAPIInternalStorage> =
|
||||
Object.create(null);
|
||||
|
||||
/**
|
||||
* Get Redundancy instance for provider
|
||||
*/
|
||||
function getRedundancyCache(
|
||||
provider: string
|
||||
): IconifyAPIInternalStorage | undefined {
|
||||
if (redundancyCache[provider] === void 0) {
|
||||
const config = getAPIConfig(provider);
|
||||
if (!config) {
|
||||
// No way to load icons because configuration is not set!
|
||||
return;
|
||||
}
|
||||
|
||||
const redundancy = initRedundancy(config);
|
||||
const cachedReundancy = {
|
||||
config,
|
||||
redundancy,
|
||||
};
|
||||
redundancyCache[provider] = cachedReundancy;
|
||||
}
|
||||
|
||||
return redundancyCache[provider];
|
||||
}
|
||||
|
||||
/**
|
||||
* Function called when new icons have been loaded
|
||||
*/
|
||||
@ -158,9 +147,6 @@ function loadNewIcons(provider: string, prefix: string, icons: string[]): void {
|
||||
.sort();
|
||||
}
|
||||
|
||||
// Redundancy item
|
||||
let cachedReundancy: IconifyAPIInternalStorage;
|
||||
|
||||
// Trigger update on next tick, mering multiple synchronous requests into one asynchronous request
|
||||
if (!providerQueueFlags[prefix]) {
|
||||
providerQueueFlags[prefix] = true;
|
||||
@ -179,72 +165,54 @@ function loadNewIcons(provider: string, prefix: string, icons: string[]): void {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get API config and Redundancy instance
|
||||
if (cachedReundancy === void 0) {
|
||||
const redundancy = getRedundancyCache(provider);
|
||||
if (redundancy === void 0) {
|
||||
// No way to load icons because configuration is not set!
|
||||
err();
|
||||
return;
|
||||
}
|
||||
cachedReundancy = redundancy;
|
||||
}
|
||||
|
||||
// Prepare parameters and run queries
|
||||
const params = api.prepare(provider, prefix, icons);
|
||||
params.forEach((item) => {
|
||||
cachedReundancy.redundancy.query(
|
||||
item,
|
||||
api.send as QueryModuleCallback,
|
||||
(data, error) => {
|
||||
const storage = getStorage(provider, prefix);
|
||||
sendAPIQuery(provider, item, (data, error) => {
|
||||
const storage = getStorage(provider, prefix);
|
||||
|
||||
// Check for error
|
||||
if (typeof data !== 'object') {
|
||||
if (error !== 404) {
|
||||
// Do not handle error unless it is 404
|
||||
// Check for error
|
||||
if (typeof data !== 'object') {
|
||||
if (error !== 404) {
|
||||
// Do not handle error unless it is 404
|
||||
return;
|
||||
}
|
||||
|
||||
// Not found: mark as missing
|
||||
const t = Date.now();
|
||||
item.icons.forEach((name) => {
|
||||
storage.missing[name] = t;
|
||||
});
|
||||
} else {
|
||||
// Add icons to storage
|
||||
try {
|
||||
const added = addIconSet(
|
||||
storage,
|
||||
data as IconifyJSON,
|
||||
'all'
|
||||
);
|
||||
if (typeof added === 'boolean') {
|
||||
return;
|
||||
}
|
||||
|
||||
// Not found: mark as missing
|
||||
const t = Date.now();
|
||||
item.icons.forEach((name) => {
|
||||
storage.missing[name] = t;
|
||||
// Remove added icons from pending list
|
||||
const pending = providerPendingIcons[prefix];
|
||||
added.forEach((name) => {
|
||||
delete pending[name];
|
||||
});
|
||||
} else {
|
||||
// Add icons to storage
|
||||
try {
|
||||
const added = addIconSet(
|
||||
storage,
|
||||
data as IconifyJSON,
|
||||
'all'
|
||||
);
|
||||
if (typeof added === 'boolean') {
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove added icons from pending list
|
||||
const pending = providerPendingIcons[prefix];
|
||||
added.forEach((name) => {
|
||||
delete pending[name];
|
||||
});
|
||||
|
||||
// Cache API response
|
||||
if (coreModules.cache) {
|
||||
coreModules.cache(
|
||||
provider,
|
||||
data as IconifyJSON
|
||||
);
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
// Cache API response
|
||||
if (cache.store) {
|
||||
cache.store(provider, data as IconifyJSON);
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
|
||||
// Trigger update on next tick
|
||||
loadedNewIcons(provider, prefix);
|
||||
}
|
||||
);
|
||||
|
||||
// Trigger update on next tick
|
||||
loadedNewIcons(provider, prefix);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
@ -253,18 +221,20 @@ function loadNewIcons(provider: string, prefix: string, icons: string[]): void {
|
||||
/**
|
||||
* Check if icon is being loaded
|
||||
*/
|
||||
const isPending: IsPending = (icon: IconifyIconName): boolean => {
|
||||
export const isPending: IsPending = (icon: IconifyIconName): boolean => {
|
||||
const provider = icon.provider;
|
||||
const prefix = icon.prefix;
|
||||
return (
|
||||
pendingIcons[icon.provider] !== void 0 &&
|
||||
pendingIcons[icon.provider][icon.prefix] !== void 0 &&
|
||||
pendingIcons[icon.provider][icon.prefix][icon.name] !== void 0
|
||||
pendingIcons[provider] &&
|
||||
pendingIcons[provider][prefix] &&
|
||||
pendingIcons[provider][prefix][icon.name] !== void 0
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Load icons
|
||||
*/
|
||||
const loadIcons: IconifyLoadIcons = (
|
||||
export const loadIcons: IconifyLoadIcons = (
|
||||
icons: (IconifyIconName | string)[],
|
||||
callback?: IconifyIconLoaderCallback
|
||||
): IconifyIconLoaderAbort => {
|
||||
@ -369,11 +339,3 @@ const loadIcons: IconifyLoadIcons = (
|
||||
? storeCallback(callback, sortedIcons, sources)
|
||||
: emptyCallback;
|
||||
};
|
||||
|
||||
/**
|
||||
* Export module
|
||||
*/
|
||||
export const API: IconifyAPI = {
|
||||
isPending,
|
||||
loadIcons,
|
||||
};
|
@ -1,5 +1,4 @@
|
||||
import type { PendingQueryItem } from '@cyberalien/redundancy';
|
||||
import type { GetAPIConfig } from '../api/config';
|
||||
|
||||
/**
|
||||
* Params for sendQuery()
|
||||
@ -12,7 +11,7 @@ export interface IconifyAPIIconsQueryParams {
|
||||
}
|
||||
export interface IconifyAPICustomQueryParams {
|
||||
type: 'custom';
|
||||
provider: string;
|
||||
provider?: string; // Provider is optional. If missing, temporary config is created based on host
|
||||
uri: string;
|
||||
}
|
||||
|
||||
@ -59,12 +58,5 @@ export function setAPIModule(provider: string, item: IconifyAPIModule): void {
|
||||
* Get API module
|
||||
*/
|
||||
export function getAPIModule(provider: string): IconifyAPIModule | undefined {
|
||||
return storage[provider] === void 0 ? storage[''] : storage[provider];
|
||||
return storage[provider] || storage[''];
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to return API interface
|
||||
*/
|
||||
export type GetIconifyAPIModule = (
|
||||
getAPIConfig: GetAPIConfig
|
||||
) => IconifyAPIModule;
|
||||
|
@ -4,10 +4,9 @@ import type {
|
||||
IconifyAPIPrepareIconsQuery,
|
||||
IconifyAPISendQuery,
|
||||
IconifyAPIModule,
|
||||
GetIconifyAPIModule,
|
||||
IconifyAPIIconsQueryParams,
|
||||
} from '../modules';
|
||||
import type { GetAPIConfig } from '../config';
|
||||
import { getAPIConfig } from '../config';
|
||||
import { mergeParams } from '../params';
|
||||
|
||||
/**
|
||||
@ -71,166 +70,190 @@ export function getFetch(): typeof fetchModule {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return API module
|
||||
* Calculate maximum icons list length for prefix
|
||||
*/
|
||||
export const getAPIModule: GetIconifyAPIModule = (
|
||||
getAPIConfig: GetAPIConfig
|
||||
): IconifyAPIModule => {
|
||||
/**
|
||||
* Calculate maximum icons list length for prefix
|
||||
*/
|
||||
function calculateMaxLength(provider: string, prefix: string): number {
|
||||
// Get config and store path
|
||||
const config = getAPIConfig(provider);
|
||||
if (!config) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Calculate
|
||||
let result;
|
||||
if (!config.maxURL) {
|
||||
result = 0;
|
||||
} else {
|
||||
let maxHostLength = 0;
|
||||
config.resources.forEach((item) => {
|
||||
const host = item as string;
|
||||
maxHostLength = Math.max(maxHostLength, host.length);
|
||||
});
|
||||
|
||||
// Get available length
|
||||
const url = mergeParams(prefix + '.json', {
|
||||
icons: '',
|
||||
});
|
||||
|
||||
result =
|
||||
config.maxURL - maxHostLength - config.path.length - url.length;
|
||||
}
|
||||
|
||||
// Cache stuff and return result
|
||||
const cacheKey = provider + ':' + prefix;
|
||||
pathCache[provider] = config.path;
|
||||
maxLengthCache[cacheKey] = result;
|
||||
return result;
|
||||
function calculateMaxLength(provider: string, prefix: string): number {
|
||||
// Get config and store path
|
||||
const config = getAPIConfig(provider);
|
||||
if (!config) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare params
|
||||
*/
|
||||
const prepare: IconifyAPIPrepareIconsQuery = (
|
||||
provider: string,
|
||||
prefix: string,
|
||||
icons: string[]
|
||||
): IconifyAPIIconsQueryParams[] => {
|
||||
const results: IconifyAPIIconsQueryParams[] = [];
|
||||
|
||||
// Get maximum icons list length
|
||||
let maxLength = maxLengthCache[prefix];
|
||||
if (maxLength === void 0) {
|
||||
maxLength = calculateMaxLength(provider, prefix);
|
||||
}
|
||||
|
||||
// Split icons
|
||||
const type = 'icons';
|
||||
let item: IconifyAPIIconsQueryParams = {
|
||||
type,
|
||||
provider,
|
||||
prefix,
|
||||
icons: [],
|
||||
};
|
||||
let length = 0;
|
||||
icons.forEach((name, index) => {
|
||||
length += name.length + 1;
|
||||
if (length >= maxLength && index > 0) {
|
||||
// Next set
|
||||
results.push(item);
|
||||
item = {
|
||||
type,
|
||||
provider,
|
||||
prefix,
|
||||
icons: [],
|
||||
};
|
||||
length = name.length;
|
||||
}
|
||||
|
||||
item.icons.push(name);
|
||||
// Calculate
|
||||
let result;
|
||||
if (!config.maxURL) {
|
||||
result = 0;
|
||||
} else {
|
||||
let maxHostLength = 0;
|
||||
config.resources.forEach((item) => {
|
||||
const host = item as string;
|
||||
maxHostLength = Math.max(maxHostLength, host.length);
|
||||
});
|
||||
results.push(item);
|
||||
|
||||
return results;
|
||||
// Get available length
|
||||
const url = mergeParams(prefix + '.json', {
|
||||
icons: '',
|
||||
});
|
||||
|
||||
result =
|
||||
config.maxURL - maxHostLength - config.path.length - url.length;
|
||||
}
|
||||
|
||||
// Cache stuff and return result
|
||||
const cacheKey = provider + ':' + prefix;
|
||||
pathCache[provider] = config.path;
|
||||
maxLengthCache[cacheKey] = result;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare params
|
||||
*/
|
||||
const prepare: IconifyAPIPrepareIconsQuery = (
|
||||
provider: string,
|
||||
prefix: string,
|
||||
icons: string[]
|
||||
): IconifyAPIIconsQueryParams[] => {
|
||||
const results: IconifyAPIIconsQueryParams[] = [];
|
||||
|
||||
// Get maximum icons list length
|
||||
let maxLength = maxLengthCache[prefix];
|
||||
if (maxLength === void 0) {
|
||||
maxLength = calculateMaxLength(provider, prefix);
|
||||
}
|
||||
|
||||
// Split icons
|
||||
const type = 'icons';
|
||||
let item: IconifyAPIIconsQueryParams = {
|
||||
type,
|
||||
provider,
|
||||
prefix,
|
||||
icons: [],
|
||||
};
|
||||
|
||||
/**
|
||||
* Load icons
|
||||
*/
|
||||
const send: IconifyAPISendQuery = (
|
||||
host: string,
|
||||
params: IconifyAPIQueryParams,
|
||||
status: PendingQueryItem
|
||||
): void => {
|
||||
const provider = params.provider;
|
||||
let path: string;
|
||||
|
||||
switch (params.type) {
|
||||
case 'icons': {
|
||||
const prefix = params.prefix;
|
||||
const icons = params.icons;
|
||||
const iconsList = icons.join(',');
|
||||
|
||||
path =
|
||||
pathCache[provider] +
|
||||
mergeParams(prefix + '.json', {
|
||||
icons: iconsList,
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
||||
case 'custom': {
|
||||
const uri = params.uri;
|
||||
path =
|
||||
pathCache[provider] +
|
||||
(uri.slice(0, 1) === '/' ? uri.slice(1) : uri);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
// Fail: return 400 Bad Request
|
||||
status.done(void 0, 400);
|
||||
return;
|
||||
let length = 0;
|
||||
icons.forEach((name, index) => {
|
||||
length += name.length + 1;
|
||||
if (length >= maxLength && index > 0) {
|
||||
// Next set
|
||||
results.push(item);
|
||||
item = {
|
||||
type,
|
||||
provider,
|
||||
prefix,
|
||||
icons: [],
|
||||
};
|
||||
length = name.length;
|
||||
}
|
||||
|
||||
if (!fetchModule) {
|
||||
// Fail: return 424 Failed Dependency (its not meant to be used like that, but it is the best match)
|
||||
status.done(void 0, 424);
|
||||
return;
|
||||
}
|
||||
item.icons.push(name);
|
||||
});
|
||||
results.push(item);
|
||||
|
||||
// console.log('API query:', host + path);
|
||||
fetchModule(host + path)
|
||||
.then((response) => {
|
||||
if (response.status !== 200) {
|
||||
status.done(void 0, response.status);
|
||||
return;
|
||||
}
|
||||
|
||||
return response.json();
|
||||
})
|
||||
.then((data) => {
|
||||
if (typeof data !== 'object' || data === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Store cache and complete
|
||||
status.done(data);
|
||||
})
|
||||
.catch((err) => {
|
||||
// Error
|
||||
status.done(void 0, err.errno);
|
||||
});
|
||||
};
|
||||
|
||||
// Return functions
|
||||
return {
|
||||
prepare,
|
||||
send,
|
||||
};
|
||||
return results;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get path
|
||||
*/
|
||||
function getPath(provider?: string): string {
|
||||
if (typeof provider === 'string') {
|
||||
if (pathCache[provider] === void 0) {
|
||||
const config = getAPIConfig(provider);
|
||||
if (!config) {
|
||||
return '/';
|
||||
}
|
||||
pathCache[provider] = config.path;
|
||||
}
|
||||
|
||||
return pathCache[provider];
|
||||
}
|
||||
|
||||
// No provider config, assume path is '/'
|
||||
return '/';
|
||||
}
|
||||
|
||||
/**
|
||||
* Load icons
|
||||
*/
|
||||
const send: IconifyAPISendQuery = (
|
||||
host: string,
|
||||
params: IconifyAPIQueryParams,
|
||||
status: PendingQueryItem
|
||||
): void => {
|
||||
if (!fetchModule) {
|
||||
// Fail: return "424 Failed Dependency" (its not meant to be used like that, but it is the closest match)
|
||||
status.done(void 0, 424);
|
||||
return;
|
||||
}
|
||||
|
||||
// Get path
|
||||
let path = getPath(params.provider);
|
||||
switch (params.type) {
|
||||
case 'icons': {
|
||||
const prefix = params.prefix;
|
||||
const icons = params.icons;
|
||||
const iconsList = icons.join(',');
|
||||
|
||||
path += mergeParams(prefix + '.json', {
|
||||
icons: iconsList,
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
||||
case 'custom': {
|
||||
const uri = params.uri;
|
||||
path += uri.slice(0, 1) === '/' ? uri.slice(1) : uri;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
// Fail: return 400 Bad Request
|
||||
status.done(void 0, 400);
|
||||
return;
|
||||
}
|
||||
|
||||
// Error code to return if fetch throws an error: "503 Service Unavailable"
|
||||
let defaultError = 503;
|
||||
|
||||
// console.log('API query:', host + path);
|
||||
fetchModule(host + path)
|
||||
.then((response) => {
|
||||
if (response.status !== 200) {
|
||||
setTimeout(() => {
|
||||
// Complete on next tick to get out of try...catch
|
||||
status.done(void 0, response.status);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// Parse JSON, fail with "501 Not Implemented" if response cannot be decoded
|
||||
defaultError = 501;
|
||||
return response.json();
|
||||
})
|
||||
.then((data) => {
|
||||
if (typeof data !== 'object' || data === null) {
|
||||
setTimeout(() => {
|
||||
// Complete on next tick to get out of try...catch
|
||||
status.done(void 0, defaultError);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// Store cache and complete on next tick
|
||||
setTimeout(() => {
|
||||
// Complete on next tick to get out of try...catch
|
||||
status.done(data);
|
||||
});
|
||||
})
|
||||
.catch(() => {
|
||||
status.done(void 0, defaultError);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Export module
|
||||
*/
|
||||
export const fetchAPIModule: IconifyAPIModule = {
|
||||
prepare,
|
||||
send,
|
||||
};
|
||||
|
@ -5,10 +5,9 @@ import type {
|
||||
IconifyAPIPrepareIconsQuery,
|
||||
IconifyAPISendQuery,
|
||||
IconifyAPIModule,
|
||||
GetIconifyAPIModule,
|
||||
IconifyAPIIconsQueryParams,
|
||||
} from '../modules';
|
||||
import type { GetAPIConfig } from '../config';
|
||||
import { getAPIConfig } from '../config';
|
||||
import { mergeParams } from '../params';
|
||||
|
||||
/**
|
||||
@ -80,160 +79,152 @@ function getGlobal(): JSONPRoot {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return API module
|
||||
* Calculate maximum icons list length for prefix
|
||||
*/
|
||||
export const getAPIModule: GetIconifyAPIModule = (
|
||||
getAPIConfig: GetAPIConfig
|
||||
): IconifyAPIModule => {
|
||||
/**
|
||||
* Calculate maximum icons list length for prefix
|
||||
*/
|
||||
function calculateMaxLength(provider: string, prefix: string): number {
|
||||
// Get config and store path
|
||||
const config = getAPIConfig(provider);
|
||||
if (!config) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Calculate
|
||||
let result;
|
||||
if (!config.maxURL) {
|
||||
result = 0;
|
||||
} else {
|
||||
let maxHostLength = 0;
|
||||
config.resources.forEach((item) => {
|
||||
const host = item as string;
|
||||
maxHostLength = Math.max(maxHostLength, host.length);
|
||||
});
|
||||
|
||||
// Make sure global is set
|
||||
getGlobal();
|
||||
|
||||
// Get available length
|
||||
const url = mergeParams(prefix + '.js', {
|
||||
icons: '',
|
||||
callback: rootVarName!,
|
||||
});
|
||||
result =
|
||||
config.maxURL - maxHostLength - config.path.length - url.length;
|
||||
}
|
||||
|
||||
// Cache stuff and return result
|
||||
const cacheKey = provider + ':' + prefix;
|
||||
pathCache[cacheKey] = config.path;
|
||||
maxLengthCache[cacheKey] = result;
|
||||
return result;
|
||||
function calculateMaxLength(provider: string, prefix: string): number {
|
||||
// Get config and store path
|
||||
const config = getAPIConfig(provider);
|
||||
if (!config) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare params
|
||||
*/
|
||||
const prepare: IconifyAPIPrepareIconsQuery = (
|
||||
provider: string,
|
||||
prefix: string,
|
||||
icons: string[]
|
||||
): IconifyAPIIconsQueryParams[] => {
|
||||
const results: IconifyAPIIconsQueryParams[] = [];
|
||||
|
||||
// Get maximum icons list length
|
||||
const cacheKey = provider + ':' + prefix;
|
||||
let maxLength = maxLengthCache[cacheKey];
|
||||
if (maxLength === void 0) {
|
||||
maxLength = calculateMaxLength(provider, prefix);
|
||||
}
|
||||
|
||||
// Split icons
|
||||
const type = 'icons';
|
||||
let item: IconifyAPIIconsQueryParams = {
|
||||
type,
|
||||
provider,
|
||||
prefix,
|
||||
icons: [],
|
||||
};
|
||||
let length = 0;
|
||||
icons.forEach((name, index) => {
|
||||
length += name.length + 1;
|
||||
if (length >= maxLength && index > 0) {
|
||||
// Next set
|
||||
results.push(item);
|
||||
item = {
|
||||
type,
|
||||
provider,
|
||||
prefix,
|
||||
icons: [],
|
||||
};
|
||||
length = name.length;
|
||||
}
|
||||
|
||||
item.icons.push(name);
|
||||
// Calculate
|
||||
let result;
|
||||
if (!config.maxURL) {
|
||||
result = 0;
|
||||
} else {
|
||||
let maxHostLength = 0;
|
||||
config.resources.forEach((item) => {
|
||||
const host = item as string;
|
||||
maxHostLength = Math.max(maxHostLength, host.length);
|
||||
});
|
||||
results.push(item);
|
||||
|
||||
return results;
|
||||
};
|
||||
|
||||
/**
|
||||
* Load icons
|
||||
*/
|
||||
const send: IconifyAPISendQuery = (
|
||||
host: string,
|
||||
params: IconifyAPIQueryParams,
|
||||
status: PendingQueryItem
|
||||
): void => {
|
||||
if (params.type !== 'icons') {
|
||||
// JSONP supports only icons
|
||||
status.done(void 0, 400);
|
||||
return;
|
||||
}
|
||||
|
||||
const provider = params.provider;
|
||||
const prefix = params.prefix;
|
||||
const icons = params.icons;
|
||||
const iconsList = icons.join(',');
|
||||
const cacheKey = provider + ':' + prefix;
|
||||
|
||||
// Create callback prefix
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
const cbPrefix = prefix.split('-').shift()!.slice(0, 3);
|
||||
|
||||
const global = getGlobal();
|
||||
|
||||
// Callback hash
|
||||
let cbCounter = hash(
|
||||
provider + ':' + host + ':' + prefix + ':' + iconsList
|
||||
);
|
||||
while (global[cbPrefix + cbCounter] !== void 0) {
|
||||
cbCounter++;
|
||||
}
|
||||
const callbackName = cbPrefix + cbCounter;
|
||||
// Make sure global is set
|
||||
getGlobal();
|
||||
|
||||
// Get available length
|
||||
const url = mergeParams(prefix + '.js', {
|
||||
icons: iconsList,
|
||||
callback: rootVarName!.replace('{cb}', callbackName),
|
||||
icons: '',
|
||||
callback: rootVarName!,
|
||||
});
|
||||
const path = pathCache[cacheKey] + url;
|
||||
result =
|
||||
config.maxURL - maxHostLength - config.path.length - url.length;
|
||||
}
|
||||
|
||||
global[callbackName] = (data: unknown): void => {
|
||||
// Remove callback and complete query
|
||||
delete global[callbackName];
|
||||
status.done(data);
|
||||
};
|
||||
// Cache stuff and return result
|
||||
const cacheKey = provider + ':' + prefix;
|
||||
pathCache[cacheKey] = config.path;
|
||||
maxLengthCache[cacheKey] = result;
|
||||
return result;
|
||||
}
|
||||
|
||||
// Create URI
|
||||
const uri = host + path;
|
||||
// console.log('API query:', uri);
|
||||
/**
|
||||
* Prepare params
|
||||
*/
|
||||
const prepare: IconifyAPIPrepareIconsQuery = (
|
||||
provider: string,
|
||||
prefix: string,
|
||||
icons: string[]
|
||||
): IconifyAPIIconsQueryParams[] => {
|
||||
const results: IconifyAPIIconsQueryParams[] = [];
|
||||
|
||||
// Create script and append it to head
|
||||
const script = document.createElement('script');
|
||||
script.type = 'text/javascript';
|
||||
script.async = true;
|
||||
script.src = uri;
|
||||
document.head.appendChild(script);
|
||||
// Get maximum icons list length
|
||||
const cacheKey = provider + ':' + prefix;
|
||||
let maxLength = maxLengthCache[cacheKey];
|
||||
if (maxLength === void 0) {
|
||||
maxLength = calculateMaxLength(provider, prefix);
|
||||
}
|
||||
|
||||
// Split icons
|
||||
const type = 'icons';
|
||||
let item: IconifyAPIIconsQueryParams = {
|
||||
type,
|
||||
provider,
|
||||
prefix,
|
||||
icons: [],
|
||||
};
|
||||
let length = 0;
|
||||
icons.forEach((name, index) => {
|
||||
length += name.length + 1;
|
||||
if (length >= maxLength && index > 0) {
|
||||
// Next set
|
||||
results.push(item);
|
||||
item = {
|
||||
type,
|
||||
provider,
|
||||
prefix,
|
||||
icons: [],
|
||||
};
|
||||
length = name.length;
|
||||
}
|
||||
|
||||
// Return functions
|
||||
return {
|
||||
prepare,
|
||||
send,
|
||||
};
|
||||
item.icons.push(name);
|
||||
});
|
||||
results.push(item);
|
||||
|
||||
return results;
|
||||
};
|
||||
|
||||
/**
|
||||
* Load icons
|
||||
*/
|
||||
const send: IconifyAPISendQuery = (
|
||||
host: string,
|
||||
params: IconifyAPIQueryParams,
|
||||
status: PendingQueryItem
|
||||
): void => {
|
||||
if (params.type !== 'icons') {
|
||||
// JSONP supports only icons
|
||||
status.done(void 0, 400);
|
||||
return;
|
||||
}
|
||||
|
||||
const provider = params.provider;
|
||||
const prefix = params.prefix;
|
||||
const icons = params.icons;
|
||||
const iconsList = icons.join(',');
|
||||
const cacheKey = provider + ':' + prefix;
|
||||
|
||||
// Create callback prefix
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
const cbPrefix = prefix.split('-').shift()!.slice(0, 3);
|
||||
|
||||
const global = getGlobal();
|
||||
|
||||
// Callback hash
|
||||
let cbCounter = hash(
|
||||
provider + ':' + host + ':' + prefix + ':' + iconsList
|
||||
);
|
||||
while (global[cbPrefix + cbCounter] !== void 0) {
|
||||
cbCounter++;
|
||||
}
|
||||
const callbackName = cbPrefix + cbCounter;
|
||||
|
||||
const url = mergeParams(prefix + '.js', {
|
||||
icons: iconsList,
|
||||
callback: rootVarName!.replace('{cb}', callbackName),
|
||||
});
|
||||
const path = pathCache[cacheKey] + url;
|
||||
|
||||
global[callbackName] = (data: unknown): void => {
|
||||
// Remove callback and complete query
|
||||
delete global[callbackName];
|
||||
status.done(data);
|
||||
};
|
||||
|
||||
// Create URI
|
||||
const uri = host + path;
|
||||
// console.log('API query:', uri);
|
||||
|
||||
// Create script and append it to head
|
||||
const script = document.createElement('script');
|
||||
script.type = 'text/javascript';
|
||||
script.async = true;
|
||||
script.src = uri;
|
||||
document.head.appendChild(script);
|
||||
};
|
||||
|
||||
/**
|
||||
* Return API module
|
||||
*/
|
||||
export const jsonpAPIModule: IconifyAPIModule = { prepare, send };
|
||||
|
@ -127,10 +127,7 @@ export const mockAPIModule: IconifyAPIModule = {
|
||||
): IconifyAPIIconsQueryParams[] => {
|
||||
const type = 'icons';
|
||||
|
||||
if (
|
||||
iconsStorage[provider] === void 0 ||
|
||||
iconsStorage[provider][prefix] === void 0
|
||||
) {
|
||||
if (!iconsStorage[provider] || !iconsStorage[provider][prefix]) {
|
||||
// No mock data: bundle all icons in one request that will return 404
|
||||
return [
|
||||
{
|
||||
@ -223,6 +220,12 @@ export const mockAPIModule: IconifyAPIModule = {
|
||||
status: PendingQueryItem
|
||||
) => {
|
||||
const provider = params.provider;
|
||||
if (provider === void 0) {
|
||||
// Fail: return 400 Bad Request
|
||||
status.done(void 0, 400);
|
||||
return;
|
||||
}
|
||||
|
||||
let data: IconifyMockAPI;
|
||||
|
||||
switch (params.type) {
|
||||
|
106
packages/core/src/api/query.ts
Normal file
106
packages/core/src/api/query.ts
Normal file
@ -0,0 +1,106 @@
|
||||
import type {
|
||||
Redundancy,
|
||||
QueryDoneCallback,
|
||||
QueryAbortCallback,
|
||||
QueryModuleCallback,
|
||||
} from '@cyberalien/redundancy';
|
||||
import { initRedundancy } from '@cyberalien/redundancy';
|
||||
import {
|
||||
getAPIModule,
|
||||
IconifyAPIQueryParams,
|
||||
IconifyAPISendQuery,
|
||||
} from './modules';
|
||||
import {
|
||||
createAPIConfig,
|
||||
IconifyAPIConfig,
|
||||
PartialIconifyAPIConfig,
|
||||
} from './config';
|
||||
import { getAPIConfig } from './config';
|
||||
|
||||
// Empty abort callback
|
||||
function emptyCallback(): void {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
// Redundancy instances cache, sorted by provider
|
||||
interface IconifyAPIInternalStorage {
|
||||
config: IconifyAPIConfig;
|
||||
redundancy: Redundancy;
|
||||
}
|
||||
const redundancyCache: Record<string, IconifyAPIInternalStorage> =
|
||||
Object.create(null);
|
||||
|
||||
/**
|
||||
* Get Redundancy instance for provider
|
||||
*/
|
||||
function getRedundancyCache(
|
||||
provider: string
|
||||
): IconifyAPIInternalStorage | undefined {
|
||||
if (redundancyCache[provider] === void 0) {
|
||||
const config = getAPIConfig(provider);
|
||||
if (!config) {
|
||||
// Configuration is not set!
|
||||
return;
|
||||
}
|
||||
|
||||
const redundancy = initRedundancy(config);
|
||||
const cachedReundancy = {
|
||||
config,
|
||||
redundancy,
|
||||
};
|
||||
redundancyCache[provider] = cachedReundancy;
|
||||
}
|
||||
|
||||
return redundancyCache[provider];
|
||||
}
|
||||
|
||||
/**
|
||||
* Send API query
|
||||
*/
|
||||
export function sendAPIQuery(
|
||||
target: string | PartialIconifyAPIConfig,
|
||||
query: IconifyAPIQueryParams,
|
||||
callback: QueryDoneCallback
|
||||
): QueryAbortCallback {
|
||||
let redundancy: Redundancy | undefined;
|
||||
let send: IconifyAPISendQuery | undefined;
|
||||
|
||||
if (typeof target === 'string') {
|
||||
// Get API module
|
||||
const api = getAPIModule(target);
|
||||
if (!api) {
|
||||
// No API module
|
||||
// Return "424 Failed Dependency" (its not meant to be used like that, but it is the closest match)
|
||||
callback(void 0, 424);
|
||||
return emptyCallback;
|
||||
}
|
||||
send = api.send;
|
||||
|
||||
// Get Redundancy instance
|
||||
const cached = getRedundancyCache(target);
|
||||
if (cached) {
|
||||
redundancy = cached.redundancy;
|
||||
}
|
||||
} else {
|
||||
const config = createAPIConfig(target);
|
||||
if (config) {
|
||||
redundancy = initRedundancy(config);
|
||||
|
||||
// Use default API provider
|
||||
const api = getAPIModule('');
|
||||
if (api) {
|
||||
send = api.send;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!redundancy || !send) {
|
||||
// No way to load icons because configuration is not set!
|
||||
callback(void 0, 424);
|
||||
return emptyCallback;
|
||||
}
|
||||
|
||||
// Send API query, return function to abort query
|
||||
return redundancy.query(query, send as QueryModuleCallback, callback)()
|
||||
.abort;
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
import type { IconifyJSON } from '@iconify/types';
|
||||
import type { CacheIcons, LoadIconsCache } from '../interfaces/cache';
|
||||
import type { CacheIcons, LoadIconsCache } from '../cache';
|
||||
import { getStorage, addIconSet } from '../storage/storage';
|
||||
|
||||
interface StorageType<T> {
|
||||
@ -68,7 +68,7 @@ export const emptyList: StorageEmptyList = {
|
||||
type FakeWindow = Record<string, typeof localStorage>;
|
||||
|
||||
let _window: FakeWindow =
|
||||
typeof window === 'undefined' ? {} : ((window as unknown) as FakeWindow);
|
||||
typeof window === 'undefined' ? {} : (window as unknown as FakeWindow);
|
||||
export function mock(fakeWindow: FakeWindow): void {
|
||||
loaded = false;
|
||||
_window = fakeWindow;
|
||||
|
@ -9,3 +9,13 @@ export type CacheIcons = (provider: string, data: IconifyJSON) => void;
|
||||
* Function to load icons from cache
|
||||
*/
|
||||
export type LoadIconsCache = () => void;
|
||||
|
||||
/**
|
||||
* Module
|
||||
*/
|
||||
interface CacheModule {
|
||||
store?: CacheIcons;
|
||||
load?: LoadIconsCache;
|
||||
}
|
||||
|
||||
export const cache: CacheModule = {};
|
@ -1,15 +0,0 @@
|
||||
import type { IconifyLoadIcons } from './loader';
|
||||
import type { IconifyIconName } from '@iconify/utils/lib/icon/name';
|
||||
|
||||
/**
|
||||
* Function to check if icon is pending
|
||||
*/
|
||||
export type IsPending = (icon: IconifyIconName) => boolean;
|
||||
|
||||
/**
|
||||
* API interface
|
||||
*/
|
||||
export interface IconifyAPI {
|
||||
isPending: IsPending;
|
||||
loadIcons: IconifyLoadIcons;
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
import type { IconifyIconName } from '@iconify/utils/lib/icon/name';
|
||||
|
||||
/**
|
||||
* Function to abort loading (usually just removes callback because loading is already in progress)
|
||||
*/
|
||||
export type IconifyIconLoaderAbort = () => void;
|
||||
|
||||
/**
|
||||
* Loader callback
|
||||
*
|
||||
* Provides list of icons that have been loaded
|
||||
*/
|
||||
export type IconifyIconLoaderCallback = (
|
||||
loaded: IconifyIconName[],
|
||||
missing: IconifyIconName[],
|
||||
pending: IconifyIconName[],
|
||||
unsubscribe: IconifyIconLoaderAbort
|
||||
) => void;
|
||||
|
||||
/**
|
||||
* Function to load icons
|
||||
*/
|
||||
export type IconifyLoadIcons = (
|
||||
icons: (IconifyIconName | string)[],
|
||||
callback?: IconifyIconLoaderCallback
|
||||
) => IconifyIconLoaderAbort;
|
@ -1,18 +0,0 @@
|
||||
import type { CacheIcons } from './interfaces/cache';
|
||||
import type { IconifyAPI } from './interfaces/api';
|
||||
|
||||
/**
|
||||
* Dynamic modules.
|
||||
*
|
||||
* Used as storage for optional functions that may or may not exist.
|
||||
* Each module must be set after including correct function for it, see build files as examples.
|
||||
*/
|
||||
interface Modules {
|
||||
// API module
|
||||
api?: IconifyAPI;
|
||||
|
||||
// Cache module (only function that stores cache. loading cache should be done when assigning module)
|
||||
cache?: CacheIcons;
|
||||
}
|
||||
|
||||
export const coreModules: Modules = {};
|
@ -6,8 +6,8 @@ import type { PendingQueryItem } from '@cyberalien/redundancy';
|
||||
import type { IconifyAPIConfig } from '../../lib/api/config';
|
||||
import { setAPIConfig, getAPIConfig } from '../../lib/api/config';
|
||||
import type {
|
||||
APIIconsQueryParams,
|
||||
APIQueryParams,
|
||||
IconifyAPIIconsQueryParams,
|
||||
IconifyAPIQueryParams,
|
||||
IconifyAPIModule,
|
||||
} from '../../lib/api/modules';
|
||||
import { setAPIModule, getAPIModule } from '../../lib/api/modules';
|
||||
@ -25,8 +25,8 @@ describe('Testing API modules', () => {
|
||||
provider: string,
|
||||
prefix: string,
|
||||
icons: string[]
|
||||
): APIIconsQueryParams[] => {
|
||||
const item: APIIconsQueryParams = {
|
||||
): IconifyAPIIconsQueryParams[] => {
|
||||
const item: IconifyAPIIconsQueryParams = {
|
||||
type: 'icons',
|
||||
provider,
|
||||
prefix,
|
||||
@ -37,7 +37,7 @@ describe('Testing API modules', () => {
|
||||
|
||||
const sendQuery = (
|
||||
host: string,
|
||||
params: APIQueryParams,
|
||||
params: IconifyAPIQueryParams,
|
||||
item: PendingQueryItem
|
||||
): void => {
|
||||
throw new Error('Unexpected API call');
|
||||
|
@ -5,11 +5,11 @@ import { expect } from 'chai';
|
||||
import type { PendingQueryItem } from '@cyberalien/redundancy';
|
||||
import { setAPIConfig } from '../../lib/api/config';
|
||||
import type {
|
||||
APIIconsQueryParams,
|
||||
APIQueryParams,
|
||||
IconifyAPIIconsQueryParams,
|
||||
IconifyAPIQueryParams,
|
||||
} from '../../lib/api/modules';
|
||||
import { setAPIModule } from '../../lib/api/modules';
|
||||
import { API } from '../../lib/api/';
|
||||
import { loadIcons, isPending } from '../../lib/api/icons';
|
||||
|
||||
describe('Testing API loadIcons', () => {
|
||||
let prefixCounter = 0;
|
||||
@ -35,8 +35,8 @@ describe('Testing API loadIcons', () => {
|
||||
provider: string,
|
||||
prefix: string,
|
||||
icons: string[]
|
||||
): APIIconsQueryParams[] => {
|
||||
const item: APIIconsQueryParams = {
|
||||
): IconifyAPIIconsQueryParams[] => {
|
||||
const item: IconifyAPIIconsQueryParams = {
|
||||
type: 'icons',
|
||||
provider,
|
||||
prefix,
|
||||
@ -48,7 +48,7 @@ describe('Testing API loadIcons', () => {
|
||||
asyncCounter++;
|
||||
|
||||
// Test input and return as one item
|
||||
const expected: APIIconsQueryParams = {
|
||||
const expected: IconifyAPIIconsQueryParams = {
|
||||
type: 'icons',
|
||||
provider,
|
||||
prefix,
|
||||
@ -61,7 +61,7 @@ describe('Testing API loadIcons', () => {
|
||||
|
||||
const sendQuery = (
|
||||
host: string,
|
||||
params: APIQueryParams,
|
||||
params: IconifyAPIQueryParams,
|
||||
item: PendingQueryItem
|
||||
): void => {
|
||||
// This callback should be called after prepareQuery
|
||||
@ -72,7 +72,7 @@ describe('Testing API loadIcons', () => {
|
||||
|
||||
// Test input
|
||||
expect(host).to.be.equal('https://api1.local');
|
||||
const expected: APIQueryParams = {
|
||||
const expected: IconifyAPIQueryParams = {
|
||||
type: 'icons',
|
||||
provider,
|
||||
prefix,
|
||||
@ -103,7 +103,7 @@ describe('Testing API loadIcons', () => {
|
||||
});
|
||||
|
||||
// Load icons
|
||||
API.loadIcons(
|
||||
loadIcons(
|
||||
[
|
||||
// as icon
|
||||
{
|
||||
@ -135,14 +135,14 @@ describe('Testing API loadIcons', () => {
|
||||
expect(pending).to.be.eql([]);
|
||||
|
||||
expect(
|
||||
API.isPending({
|
||||
isPending({
|
||||
provider,
|
||||
prefix,
|
||||
name: 'icon1',
|
||||
})
|
||||
).to.be.equal(false);
|
||||
expect(
|
||||
API.isPending({ provider, prefix, name: 'icon3' })
|
||||
isPending({ provider, prefix, name: 'icon3' })
|
||||
).to.be.equal(false);
|
||||
|
||||
done();
|
||||
@ -150,10 +150,10 @@ describe('Testing API loadIcons', () => {
|
||||
);
|
||||
|
||||
// Test isPending
|
||||
expect(API.isPending({ provider, prefix, name: 'icon1' })).to.be.equal(
|
||||
expect(isPending({ provider, prefix, name: 'icon1' })).to.be.equal(
|
||||
true
|
||||
);
|
||||
expect(API.isPending({ provider, prefix, name: 'icon3' })).to.be.equal(
|
||||
expect(isPending({ provider, prefix, name: 'icon3' })).to.be.equal(
|
||||
false
|
||||
);
|
||||
|
||||
@ -176,11 +176,11 @@ describe('Testing API loadIcons', () => {
|
||||
provider: string,
|
||||
prefix: string,
|
||||
icons: string[]
|
||||
): APIIconsQueryParams[] => {
|
||||
): IconifyAPIIconsQueryParams[] => {
|
||||
// Split all icons in multiple queries, one icon per query
|
||||
const results: APIIconsQueryParams[] = [];
|
||||
const results: IconifyAPIIconsQueryParams[] = [];
|
||||
icons.forEach((icon) => {
|
||||
const item: APIIconsQueryParams = {
|
||||
const item: IconifyAPIIconsQueryParams = {
|
||||
type: 'icons',
|
||||
provider,
|
||||
prefix,
|
||||
@ -197,7 +197,7 @@ describe('Testing API loadIcons', () => {
|
||||
let queryCounter = 0;
|
||||
const sendQuery = (
|
||||
host: string,
|
||||
params: APIQueryParams,
|
||||
params: IconifyAPIQueryParams,
|
||||
item: PendingQueryItem
|
||||
): void => {
|
||||
// Test input
|
||||
@ -210,7 +210,7 @@ describe('Testing API loadIcons', () => {
|
||||
|
||||
// Icon names should match queryCounter: 'icon1' on first run, 'icon2' on second run
|
||||
queryCounter++;
|
||||
const expected: APIQueryParams = {
|
||||
const expected: IconifyAPIQueryParams = {
|
||||
type: 'icons',
|
||||
provider,
|
||||
prefix,
|
||||
@ -240,7 +240,7 @@ describe('Testing API loadIcons', () => {
|
||||
|
||||
// Load icons
|
||||
let callbackCalled = false;
|
||||
API.loadIcons(
|
||||
loadIcons(
|
||||
[
|
||||
provider + ':' + prefix + ':icon1',
|
||||
provider + ':' + prefix + ':icon2',
|
||||
@ -285,8 +285,8 @@ describe('Testing API loadIcons', () => {
|
||||
provider: string,
|
||||
prefix: string,
|
||||
icons: string[]
|
||||
): APIIconsQueryParams[] => {
|
||||
const item: APIIconsQueryParams = {
|
||||
): IconifyAPIIconsQueryParams[] => {
|
||||
const item: IconifyAPIIconsQueryParams = {
|
||||
type: 'icons',
|
||||
provider,
|
||||
prefix,
|
||||
@ -298,7 +298,7 @@ describe('Testing API loadIcons', () => {
|
||||
let queryCounter = 0;
|
||||
const sendQuery = (
|
||||
host: string,
|
||||
params: APIQueryParams,
|
||||
params: IconifyAPIQueryParams,
|
||||
item: PendingQueryItem
|
||||
): void => {
|
||||
queryCounter++;
|
||||
@ -342,7 +342,7 @@ describe('Testing API loadIcons', () => {
|
||||
|
||||
// Load icons
|
||||
let callbackCalled = false;
|
||||
API.loadIcons(
|
||||
loadIcons(
|
||||
[
|
||||
provider + ':' + prefix + ':icon1',
|
||||
provider + ':' + prefix + ':icon2',
|
||||
@ -388,8 +388,8 @@ describe('Testing API loadIcons', () => {
|
||||
provider: string,
|
||||
prefix: string,
|
||||
icons: string[]
|
||||
): APIIconsQueryParams[] => {
|
||||
const item: APIIconsQueryParams = {
|
||||
): IconifyAPIIconsQueryParams[] => {
|
||||
const item: IconifyAPIIconsQueryParams = {
|
||||
type: 'icons',
|
||||
provider,
|
||||
prefix,
|
||||
@ -401,7 +401,7 @@ describe('Testing API loadIcons', () => {
|
||||
let queryCounter = 0;
|
||||
const sendQuery = (
|
||||
host: string,
|
||||
params: APIQueryParams,
|
||||
params: IconifyAPIQueryParams,
|
||||
item: PendingQueryItem
|
||||
): void => {
|
||||
queryCounter++;
|
||||
@ -472,7 +472,7 @@ describe('Testing API loadIcons', () => {
|
||||
|
||||
// Load icons
|
||||
let callbackCalled = false;
|
||||
API.loadIcons(
|
||||
loadIcons(
|
||||
[
|
||||
provider + ':' + prefix + ':icon1',
|
||||
provider + ':' + prefix + ':icon2',
|
||||
@ -501,7 +501,7 @@ describe('Testing API loadIcons', () => {
|
||||
// Send another query on next tick
|
||||
setTimeout(() => {
|
||||
let callbackCalled = false;
|
||||
API.loadIcons(
|
||||
loadIcons(
|
||||
[
|
||||
provider + ':' + prefix + ':icon3',
|
||||
provider + ':' + prefix + ':icon4',
|
||||
@ -551,8 +551,8 @@ describe('Testing API loadIcons', () => {
|
||||
provider: string,
|
||||
prefix: string,
|
||||
icons: string[]
|
||||
): APIIconsQueryParams[] => {
|
||||
const item: APIIconsQueryParams = {
|
||||
): IconifyAPIIconsQueryParams[] => {
|
||||
const item: IconifyAPIIconsQueryParams = {
|
||||
type: 'icons',
|
||||
provider,
|
||||
prefix,
|
||||
@ -564,7 +564,7 @@ describe('Testing API loadIcons', () => {
|
||||
let queryCounter = 0;
|
||||
const sendQuery = (
|
||||
host: string,
|
||||
params: APIQueryParams,
|
||||
params: IconifyAPIQueryParams,
|
||||
item: PendingQueryItem
|
||||
): void => {
|
||||
queryCounter++;
|
||||
@ -638,7 +638,7 @@ describe('Testing API loadIcons', () => {
|
||||
|
||||
// Load icons
|
||||
let callbackCalled = false;
|
||||
API.loadIcons(
|
||||
loadIcons(
|
||||
[
|
||||
provider + ':' + prefix + ':icon1',
|
||||
provider + ':' + prefix + ':icon2',
|
||||
@ -667,7 +667,7 @@ describe('Testing API loadIcons', () => {
|
||||
// Send another query on next tick for different prefix that shares configuration
|
||||
setTimeout(() => {
|
||||
let callbackCalled = false;
|
||||
API.loadIcons(
|
||||
loadIcons(
|
||||
[
|
||||
provider + ':' + prefix2 + ':icon2',
|
||||
provider + ':' + prefix2 + ':icon4',
|
||||
|
@ -4,7 +4,7 @@ import 'mocha';
|
||||
import { expect } from 'chai';
|
||||
import { setAPIConfig } from '../../lib/api/config';
|
||||
import { setAPIModule } from '../../lib/api/modules';
|
||||
import { API } from '../../lib/api/';
|
||||
import { loadIcons } from '../../lib/api/icons';
|
||||
import type { IconifyMockAPIDelayDoneCallback } from '../../lib/api/modules/mock';
|
||||
import { mockAPIModule, mockAPIData } from '../../lib/api/modules/mock';
|
||||
import { getStorage, iconExists } from '../../lib/storage/storage';
|
||||
@ -37,7 +37,7 @@ describe('Testing mock API module', () => {
|
||||
|
||||
let isSync = true;
|
||||
|
||||
API.loadIcons(
|
||||
loadIcons(
|
||||
[
|
||||
{
|
||||
provider,
|
||||
@ -101,7 +101,7 @@ describe('Testing mock API module', () => {
|
||||
|
||||
let isSync = true;
|
||||
|
||||
API.loadIcons(
|
||||
loadIcons(
|
||||
[
|
||||
{
|
||||
provider,
|
||||
@ -180,7 +180,7 @@ describe('Testing mock API module', () => {
|
||||
|
||||
let callbackCounter = 0;
|
||||
|
||||
API.loadIcons(
|
||||
loadIcons(
|
||||
[
|
||||
{
|
||||
provider,
|
||||
@ -278,7 +278,7 @@ describe('Testing mock API module', () => {
|
||||
});
|
||||
|
||||
// Load icons
|
||||
API.loadIcons([
|
||||
loadIcons([
|
||||
{
|
||||
provider,
|
||||
prefix,
|
||||
|
@ -2,18 +2,14 @@
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars */
|
||||
import 'mocha';
|
||||
import { expect } from 'chai';
|
||||
import { setAPIConfig } from '../../lib/api/config';
|
||||
import { setAPIModule } from '../../lib/api/modules';
|
||||
import { API } from '../../lib/api/';
|
||||
import { loadIcons } from '../../lib/api/icons';
|
||||
import { mockAPIModule, mockAPIData } from '../../lib/api/modules/mock';
|
||||
import { allowSimpleNames } from '../../lib/storage/functions';
|
||||
|
||||
describe('Testing simple names with API module', () => {
|
||||
// Set API config and allow simple names
|
||||
before(() => {
|
||||
setAPIConfig('', {
|
||||
resources: ['https://api1.local'],
|
||||
});
|
||||
allowSimpleNames(true);
|
||||
setAPIModule('', mockAPIModule);
|
||||
});
|
||||
@ -56,7 +52,7 @@ describe('Testing simple names with API module', () => {
|
||||
},
|
||||
});
|
||||
|
||||
API.loadIcons(
|
||||
loadIcons(
|
||||
[
|
||||
{
|
||||
provider: '',
|
||||
|
86
packages/core/tests/30-api/50-fetch-test.ts
Normal file
86
packages/core/tests/30-api/50-fetch-test.ts
Normal file
@ -0,0 +1,86 @@
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars-experimental */
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars */
|
||||
import 'mocha';
|
||||
import { expect } from 'chai';
|
||||
import crossFetch from 'cross-fetch';
|
||||
import { sendAPIQuery } from '../../lib/api/query';
|
||||
import { setAPIModule } from '../../lib/api/modules';
|
||||
import { fetchAPIModule, setFetch } from '../../lib/api/modules/fetch';
|
||||
import { setAPIConfig } from '../../lib/api/config';
|
||||
import { mockAPIModule } from '../../lib/api/modules/mock';
|
||||
|
||||
describe('Testing live API with fetch', () => {
|
||||
let counter = 0;
|
||||
function nextProvider(): string {
|
||||
return 'fetch-' + counter++;
|
||||
}
|
||||
|
||||
const host = 'https://api.iconify.design';
|
||||
|
||||
// Set fetch module
|
||||
before(() => {
|
||||
setFetch(crossFetch);
|
||||
setAPIModule('', fetchAPIModule);
|
||||
});
|
||||
|
||||
after(() => {
|
||||
setAPIModule('', mockAPIModule);
|
||||
});
|
||||
|
||||
it('Missing API configuration', (done) => {
|
||||
const provider = nextProvider();
|
||||
sendAPIQuery(
|
||||
provider,
|
||||
{
|
||||
type: 'custom',
|
||||
provider,
|
||||
uri: '/collections',
|
||||
},
|
||||
(data, error) => {
|
||||
expect(error).to.be.equal(424);
|
||||
expect(data).to.be.equal(void 0);
|
||||
done();
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it('Custom request with provider', (done) => {
|
||||
const provider = nextProvider();
|
||||
expect(
|
||||
setAPIConfig(provider, {
|
||||
resources: [host],
|
||||
})
|
||||
).to.be.equal(true);
|
||||
|
||||
sendAPIQuery(
|
||||
provider,
|
||||
{
|
||||
type: 'custom',
|
||||
provider,
|
||||
uri: '/collections',
|
||||
},
|
||||
(data, error) => {
|
||||
expect(error).to.be.equal(void 0);
|
||||
expect(typeof data).to.be.equal('object');
|
||||
done();
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it('Custom request with host', (done) => {
|
||||
sendAPIQuery(
|
||||
{
|
||||
resources: [host],
|
||||
},
|
||||
{
|
||||
type: 'custom',
|
||||
uri: '/collections',
|
||||
},
|
||||
(data, error) => {
|
||||
expect(error).to.be.equal(void 0);
|
||||
expect(typeof data).to.be.equal('object');
|
||||
done();
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
@ -7,8 +7,7 @@ import { getIconData } from '@iconify/core/lib/storage/functions';
|
||||
import { fullIcon, FullIconifyIcon } from '@iconify/utils/lib/icon';
|
||||
|
||||
// API
|
||||
import { API } from '@iconify/core/lib/api/';
|
||||
import type { IconifyIconLoaderAbort } from '@iconify/core/lib/interfaces/loader';
|
||||
import { loadIcons, IconifyIconLoaderAbort } from '@iconify/core/lib/api/icons';
|
||||
|
||||
// Component stuff
|
||||
import type { IconifyIconProps } from './props';
|
||||
@ -127,7 +126,7 @@ export class IconifyIconComponent extends Component<IconifyIconProps> {
|
||||
this._icon = {
|
||||
name: icon,
|
||||
className,
|
||||
abort: API.loadIcons([iconName], () => {
|
||||
abort: loadIcons([iconName], () => {
|
||||
if (!this.isDestroyed && this._icon?.name === icon) {
|
||||
// Loaded
|
||||
const data = getIconData(iconName);
|
||||
|
@ -18,11 +18,7 @@ import {
|
||||
} from '@iconify/core/lib/builder/functions';
|
||||
import type { IconifyIconBuildResult } from '@iconify/utils/lib/svg/build';
|
||||
|
||||
// Modules
|
||||
import { coreModules } from '@iconify/core/lib/modules';
|
||||
|
||||
// API
|
||||
import { API } from '@iconify/core/lib/api/';
|
||||
import {
|
||||
IconifyAPIFunctions,
|
||||
IconifyAPIInternalFunctions,
|
||||
@ -37,26 +33,26 @@ import {
|
||||
IconifyAPIModule,
|
||||
IconifyAPISendQuery,
|
||||
IconifyAPIPrepareIconsQuery,
|
||||
GetIconifyAPIModule,
|
||||
} from '@iconify/core/lib/api/modules';
|
||||
import { getAPIModule as getJSONPAPIModule } from '@iconify/core/lib/api/modules/jsonp';
|
||||
import { jsonpAPIModule } from '@iconify/core/lib/api/modules/jsonp';
|
||||
import {
|
||||
getAPIModule as getFetchAPIModule,
|
||||
fetchAPIModule,
|
||||
getFetch,
|
||||
setFetch,
|
||||
} from '@iconify/core/lib/api/modules/fetch';
|
||||
import {
|
||||
setAPIConfig,
|
||||
PartialIconifyAPIConfig,
|
||||
IconifyAPIConfig,
|
||||
getAPIConfig,
|
||||
GetAPIConfig,
|
||||
} from '@iconify/core/lib/api/config';
|
||||
import type {
|
||||
IconifyIconLoaderCallback,
|
||||
IconifyIconLoaderAbort,
|
||||
} from '@iconify/core/lib/interfaces/loader';
|
||||
} from '@iconify/core/lib/api/icons';
|
||||
|
||||
// Cache
|
||||
import { cache } from '@iconify/core/lib/cache';
|
||||
import { storeCache, loadCache } from '@iconify/core/lib/browser-storage';
|
||||
import { toggleBrowserCache } from '@iconify/core/lib/browser-storage/functions';
|
||||
import type {
|
||||
@ -194,33 +190,15 @@ export const _api = APIInternalFunctions;
|
||||
// Enable short names
|
||||
allowSimpleNames(true);
|
||||
|
||||
// Set API
|
||||
coreModules.api = API;
|
||||
|
||||
// Use Fetch API by default
|
||||
let getAPIModule: GetIconifyAPIModule = getFetchAPIModule;
|
||||
try {
|
||||
if (typeof document !== 'undefined' && typeof window !== 'undefined') {
|
||||
// If window and document exist, attempt to load whatever module is available, otherwise use Fetch API
|
||||
getAPIModule =
|
||||
typeof fetch === 'function' && typeof Promise === 'function'
|
||||
? getFetchAPIModule
|
||||
: getJSONPAPIModule;
|
||||
}
|
||||
} catch (err) {
|
||||
//
|
||||
}
|
||||
setAPIModule('', getAPIModule(getAPIConfig));
|
||||
// Set API module
|
||||
setAPIModule('', getFetch() ? fetchAPIModule : jsonpAPIModule);
|
||||
|
||||
/**
|
||||
* Function to enable node-fetch for getting icons on server side
|
||||
*/
|
||||
_api.setFetch = (nodeFetch: typeof fetch) => {
|
||||
setFetch(nodeFetch);
|
||||
if (getAPIModule !== getFetchAPIModule) {
|
||||
getAPIModule = getFetchAPIModule;
|
||||
setAPIModule('', getAPIModule(getAPIConfig));
|
||||
}
|
||||
setAPIModule('', fetchAPIModule);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -228,7 +206,7 @@ _api.setFetch = (nodeFetch: typeof fetch) => {
|
||||
*/
|
||||
if (typeof document !== 'undefined' && typeof window !== 'undefined') {
|
||||
// Set cache and load existing cache
|
||||
coreModules.cache = storeCache;
|
||||
cache.store = storeCache;
|
||||
loadCache();
|
||||
|
||||
interface WindowWithIconifyStuff {
|
||||
|
@ -21,13 +21,13 @@ Iconify SVG framework is designed to be as easy to use as possible.
|
||||
Add this line to your page to load Iconify SVG framework (you can add it to `<head>` section of the page or before `</body>`):
|
||||
|
||||
```html
|
||||
<script src="https://code.iconify.design/2/2.0.4/iconify.min.js"></script>
|
||||
<script src="https://code.iconify.design/2/2.1.0/iconify.min.js"></script>
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```html
|
||||
<script src="https://cdn.jsdelivr.net/npm/@iconify/iconify@2.0.4/dist/iconify.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/@iconify/iconify@2.1.0/dist/iconify.min.js"></script>
|
||||
```
|
||||
|
||||
or, if you are building a project with something like WebPack or Rollup, you can include the script by installing `@iconify/iconify` as a dependency and importing it in your project:
|
||||
|
@ -1,8 +1,8 @@
|
||||
{
|
||||
"name": "@iconify/iconify",
|
||||
"description": "Unified SVG framework with over 70,000 icons to choose from",
|
||||
"description": "Unified SVG framework with over 100,000 icons to choose from",
|
||||
"author": "Vjacheslav Trushkin <cyberalien@gmail.com> (https://iconify.design)",
|
||||
"version": "2.0.4",
|
||||
"version": "2.1.0",
|
||||
"license": "(Apache-2.0 OR GPL-2.0)",
|
||||
"main": "./dist/iconify.min.js",
|
||||
"types": "./dist/iconify.d.ts",
|
||||
|
@ -17,11 +17,9 @@ import {
|
||||
builderFunctions,
|
||||
} from '@iconify/core/lib/builder/functions';
|
||||
|
||||
// Modules
|
||||
import { coreModules } from '@iconify/core/lib/modules';
|
||||
|
||||
// Cache
|
||||
import { storeCache, loadCache } from '@iconify/core/lib/browser-storage/';
|
||||
import { cache } from '@iconify/core/lib/cache';
|
||||
import {
|
||||
IconifyBrowserCacheFunctions,
|
||||
IconifyBrowserCacheType,
|
||||
@ -38,30 +36,28 @@ import {
|
||||
IconifyAPICustomQueryParams,
|
||||
IconifyAPIMergeQueryParams,
|
||||
} from '@iconify/core/lib/api/functions';
|
||||
import { API } from '@iconify/core/lib/api/';
|
||||
import {
|
||||
setAPIModule,
|
||||
IconifyAPIModule,
|
||||
IconifyAPISendQuery,
|
||||
IconifyAPIPrepareIconsQuery,
|
||||
GetIconifyAPIModule,
|
||||
} from '@iconify/core/lib/api/modules';
|
||||
import {
|
||||
setAPIConfig,
|
||||
PartialIconifyAPIConfig,
|
||||
IconifyAPIConfig,
|
||||
getAPIConfig,
|
||||
GetAPIConfig,
|
||||
} from '@iconify/core/lib/api/config';
|
||||
import { getAPIModule as getJSONPAPIModule } from '@iconify/core/lib/api/modules/jsonp';
|
||||
import { jsonpAPIModule } from '@iconify/core/lib/api/modules/jsonp';
|
||||
import {
|
||||
getAPIModule as getFetchAPIModule,
|
||||
fetchAPIModule,
|
||||
getFetch,
|
||||
setFetch,
|
||||
} from '@iconify/core/lib/api/modules/fetch';
|
||||
import {
|
||||
IconifyIconLoaderCallback,
|
||||
IconifyIconLoaderAbort,
|
||||
} from '@iconify/core/lib/interfaces/loader';
|
||||
} from '@iconify/core/lib/api/icons';
|
||||
|
||||
// Other
|
||||
import { IconifyCommonFunctions, commonFunctions } from './common';
|
||||
@ -157,33 +153,15 @@ const Iconify = {
|
||||
/**
|
||||
* Initialise stuff
|
||||
*/
|
||||
// Set API
|
||||
coreModules.api = API;
|
||||
|
||||
// Check for Fetch API
|
||||
let getAPIModule: GetIconifyAPIModule = getFetchAPIModule;
|
||||
try {
|
||||
if (typeof document !== 'undefined' && typeof window !== 'undefined') {
|
||||
// If window and document exist, attempt to load whatever module is available, otherwise use Fetch API
|
||||
getAPIModule =
|
||||
typeof fetch === 'function' && typeof Promise === 'function'
|
||||
? getFetchAPIModule
|
||||
: getJSONPAPIModule;
|
||||
}
|
||||
} catch (err) {
|
||||
//
|
||||
}
|
||||
setAPIModule('', getAPIModule(getAPIConfig));
|
||||
// Set API module
|
||||
setAPIModule('', getFetch() ? fetchAPIModule : jsonpAPIModule);
|
||||
|
||||
/**
|
||||
* Function to enable node-fetch for getting icons on server side
|
||||
*/
|
||||
Iconify._api.setFetch = (nodeFetch: typeof fetch) => {
|
||||
setFetch(nodeFetch);
|
||||
if (getAPIModule !== getFetchAPIModule) {
|
||||
getAPIModule = getFetchAPIModule;
|
||||
setAPIModule('', getAPIModule(getAPIConfig));
|
||||
}
|
||||
setAPIModule('', fetchAPIModule);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -191,7 +169,7 @@ Iconify._api.setFetch = (nodeFetch: typeof fetch) => {
|
||||
*/
|
||||
if (typeof document !== 'undefined' && typeof window !== 'undefined') {
|
||||
// Set cache and load existing cache
|
||||
coreModules.cache = storeCache;
|
||||
cache.store = storeCache;
|
||||
loadCache();
|
||||
|
||||
interface WindowWithIconifyStuff {
|
||||
|
@ -6,7 +6,7 @@ interface OldIEElement extends HTMLElement {
|
||||
/**
|
||||
* Execute function when DOM is ready
|
||||
*/
|
||||
export function onReady(callback): void {
|
||||
export function onReady(callback: () => void): void {
|
||||
const doc = document;
|
||||
if (
|
||||
doc.readyState === 'complete' ||
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { IconifyIconName } from '@iconify/utils/lib/icon/name';
|
||||
import { getStorage, getIcon } from '@iconify/core/lib/storage/storage';
|
||||
import { coreModules } from '@iconify/core/lib/modules';
|
||||
import { isPending, loadIcons } from '@iconify/core/lib/api/icons';
|
||||
import { FullIconifyIcon } from '@iconify/utils/lib/icon';
|
||||
import { findPlaceholders } from './finder';
|
||||
import { IconifyElementData, elementDataProperty } from './element';
|
||||
@ -12,7 +12,7 @@ import {
|
||||
removeObservedNode,
|
||||
observeNode,
|
||||
} from './observer';
|
||||
import { findRootNode, addRootNode, listRootNodes } from './root';
|
||||
import { findRootNode, listRootNodes } from './root';
|
||||
|
||||
/**
|
||||
* Flag to avoid scanning DOM too often
|
||||
@ -77,8 +77,10 @@ export function scanDOM(node?: ObservedNode, addTempNode = false): void {
|
||||
scanQueued = false;
|
||||
|
||||
// List of icons to load: [provider][prefix][name] = boolean
|
||||
const loadIcons: Record<string, Record<string, Record<string, boolean>>> =
|
||||
Object.create(null);
|
||||
const iconsToLoad: Record<
|
||||
string,
|
||||
Record<string, Record<string, boolean>>
|
||||
> = Object.create(null);
|
||||
|
||||
// Get placeholders
|
||||
(node ? [node] : listRootNodes()).forEach((node) => {
|
||||
@ -112,8 +114,7 @@ export function scanDOM(node?: ObservedNode, addTempNode = false): void {
|
||||
|
||||
case 'loading':
|
||||
if (
|
||||
coreModules.api &&
|
||||
coreModules.api.isPending({
|
||||
isPending({
|
||||
provider,
|
||||
prefix,
|
||||
name,
|
||||
@ -162,18 +163,16 @@ export function scanDOM(node?: ObservedNode, addTempNode = false): void {
|
||||
return;
|
||||
}
|
||||
|
||||
if (coreModules.api) {
|
||||
if (!coreModules.api.isPending({ provider, prefix, name })) {
|
||||
// Add icon to loading queue
|
||||
if (loadIcons[provider] === void 0) {
|
||||
loadIcons[provider] = Object.create(null);
|
||||
}
|
||||
const providerLoadIcons = loadIcons[provider];
|
||||
if (providerLoadIcons[prefix] === void 0) {
|
||||
providerLoadIcons[prefix] = Object.create(null);
|
||||
}
|
||||
providerLoadIcons[prefix][name] = true;
|
||||
if (!isPending({ provider, prefix, name })) {
|
||||
// Add icon to loading queue
|
||||
if (iconsToLoad[provider] === void 0) {
|
||||
iconsToLoad[provider] = Object.create(null);
|
||||
}
|
||||
const providerIconsToLoad = iconsToLoad[provider];
|
||||
if (providerIconsToLoad[prefix] === void 0) {
|
||||
providerIconsToLoad[prefix] = Object.create(null);
|
||||
}
|
||||
providerIconsToLoad[prefix][name] = true;
|
||||
}
|
||||
|
||||
// Mark as loading
|
||||
@ -200,23 +199,20 @@ export function scanDOM(node?: ObservedNode, addTempNode = false): void {
|
||||
});
|
||||
|
||||
// Load icons
|
||||
if (coreModules.api) {
|
||||
const api = coreModules.api;
|
||||
Object.keys(loadIcons).forEach((provider) => {
|
||||
const providerLoadIcons = loadIcons[provider];
|
||||
Object.keys(providerLoadIcons).forEach((prefix) => {
|
||||
api.loadIcons(
|
||||
Object.keys(providerLoadIcons[prefix]).map((name) => {
|
||||
const icon: IconifyIconName = {
|
||||
provider,
|
||||
prefix,
|
||||
name,
|
||||
};
|
||||
return icon;
|
||||
}),
|
||||
checkPendingIcons
|
||||
);
|
||||
});
|
||||
Object.keys(iconsToLoad).forEach((provider) => {
|
||||
const providerIconsToLoad = iconsToLoad[provider];
|
||||
Object.keys(providerIconsToLoad).forEach((prefix) => {
|
||||
loadIcons(
|
||||
Object.keys(providerIconsToLoad[prefix]).map((name) => {
|
||||
const icon: IconifyIconName = {
|
||||
provider,
|
||||
prefix,
|
||||
name,
|
||||
};
|
||||
return icon;
|
||||
}),
|
||||
checkPendingIcons
|
||||
);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -15,14 +15,14 @@ Iconify._api.setAPIModule(provider, mockAPIModule);
|
||||
|
||||
// Set data
|
||||
mockAPIData({
|
||||
type: 'icons',
|
||||
provider,
|
||||
prefix,
|
||||
response: {
|
||||
prefix,
|
||||
icons: {
|
||||
home: {
|
||||
body:
|
||||
'<path d="M10 20v-6h4v6h5v-8h3L12 3L2 12h3v8h5z" fill="currentColor"/>',
|
||||
body: '<path d="M10 20v-6h4v6h5v-8h3L12 3L2 12h3v8h5z" fill="currentColor"/>',
|
||||
},
|
||||
},
|
||||
width: 24,
|
||||
|
@ -10,7 +10,7 @@ const prefix = 'demo';
|
||||
|
||||
// Set API module for provider
|
||||
addAPIProvider(provider, {
|
||||
resources: 'http://localhost',
|
||||
resources: ['http://localhost'],
|
||||
rotate: 10000,
|
||||
timeout: 10000,
|
||||
});
|
||||
@ -18,6 +18,7 @@ _api.setAPIModule(provider, mockAPIModule);
|
||||
|
||||
// Set mock data
|
||||
mockAPIData({
|
||||
type: 'icons',
|
||||
provider,
|
||||
prefix,
|
||||
response: {
|
||||
|
@ -21,11 +21,7 @@ import {
|
||||
import type { IconifyIconBuildResult } from '@iconify/utils/lib/svg/build';
|
||||
import { fullIcon } from '@iconify/utils/lib/icon';
|
||||
|
||||
// Modules
|
||||
import { coreModules } from '@iconify/core/lib/modules';
|
||||
|
||||
// API
|
||||
import { API } from '@iconify/core/lib/api/';
|
||||
import {
|
||||
IconifyAPIFunctions,
|
||||
IconifyAPIInternalFunctions,
|
||||
@ -40,26 +36,26 @@ import {
|
||||
IconifyAPIModule,
|
||||
IconifyAPISendQuery,
|
||||
IconifyAPIPrepareIconsQuery,
|
||||
GetIconifyAPIModule,
|
||||
} from '@iconify/core/lib/api/modules';
|
||||
import { getAPIModule as getJSONPAPIModule } from '@iconify/core/lib/api/modules/jsonp';
|
||||
import { jsonpAPIModule } from '@iconify/core/lib/api/modules/jsonp';
|
||||
import {
|
||||
getAPIModule as getFetchAPIModule,
|
||||
fetchAPIModule,
|
||||
getFetch,
|
||||
setFetch,
|
||||
} from '@iconify/core/lib/api/modules/fetch';
|
||||
import {
|
||||
setAPIConfig,
|
||||
PartialIconifyAPIConfig,
|
||||
IconifyAPIConfig,
|
||||
getAPIConfig,
|
||||
GetAPIConfig,
|
||||
} from '@iconify/core/lib/api/config';
|
||||
import type {
|
||||
IconifyIconLoaderCallback,
|
||||
IconifyIconLoaderAbort,
|
||||
} from '@iconify/core/lib/interfaces/loader';
|
||||
} from '@iconify/core/lib/api/icons';
|
||||
|
||||
// Cache
|
||||
import { cache } from '@iconify/core/lib/cache';
|
||||
import { storeCache, loadCache } from '@iconify/core/lib/browser-storage';
|
||||
import { toggleBrowserCache } from '@iconify/core/lib/browser-storage/functions';
|
||||
import type {
|
||||
@ -200,33 +196,15 @@ export const _api = APIInternalFunctions;
|
||||
// Enable short names
|
||||
allowSimpleNames(true);
|
||||
|
||||
// Set API
|
||||
coreModules.api = API;
|
||||
|
||||
// Use Fetch API by default
|
||||
let getAPIModule: GetIconifyAPIModule = getFetchAPIModule;
|
||||
try {
|
||||
if (typeof document !== 'undefined' && typeof window !== 'undefined') {
|
||||
// If window and document exist, attempt to load whatever module is available, otherwise use Fetch API
|
||||
getAPIModule =
|
||||
typeof fetch === 'function' && typeof Promise === 'function'
|
||||
? getFetchAPIModule
|
||||
: getJSONPAPIModule;
|
||||
}
|
||||
} catch (err) {
|
||||
//
|
||||
}
|
||||
setAPIModule('', getAPIModule(getAPIConfig));
|
||||
// Set API module
|
||||
setAPIModule('', getFetch() ? fetchAPIModule : jsonpAPIModule);
|
||||
|
||||
/**
|
||||
* Function to enable node-fetch for getting icons on server side
|
||||
*/
|
||||
_api.setFetch = (nodeFetch: typeof fetch) => {
|
||||
setFetch(nodeFetch);
|
||||
if (getAPIModule !== getFetchAPIModule) {
|
||||
getAPIModule = getFetchAPIModule;
|
||||
setAPIModule('', getAPIModule(getAPIConfig));
|
||||
}
|
||||
setAPIModule('', fetchAPIModule);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -234,7 +212,7 @@ _api.setFetch = (nodeFetch: typeof fetch) => {
|
||||
*/
|
||||
if (typeof document !== 'undefined' && typeof window !== 'undefined') {
|
||||
// Set cache and load existing cache
|
||||
coreModules.cache = storeCache;
|
||||
cache.store = storeCache;
|
||||
loadCache();
|
||||
|
||||
interface WindowWithIconifyStuff {
|
||||
@ -402,7 +380,7 @@ class IconComponent extends React.Component<
|
||||
this._setData(null);
|
||||
this._loading = {
|
||||
name: icon,
|
||||
abort: API.loadIcons(
|
||||
abort: loadIcons(
|
||||
[iconName],
|
||||
this._checkIcon.bind(this, false)
|
||||
),
|
||||
|
@ -8,6 +8,7 @@ describe('Testing fake API', () => {
|
||||
const name = 'mock-test';
|
||||
const iconName = `@${provider}:${prefix}:${name}`;
|
||||
mockAPIData({
|
||||
type: 'icons',
|
||||
provider,
|
||||
prefix,
|
||||
response: {
|
||||
|
@ -19,6 +19,7 @@ describe('Rendering icon', () => {
|
||||
let onLoadCalled = false;
|
||||
|
||||
mockAPIData({
|
||||
type: 'icons',
|
||||
provider,
|
||||
prefix,
|
||||
response: {
|
||||
@ -94,6 +95,7 @@ describe('Rendering icon', () => {
|
||||
let onLoadCalled = false;
|
||||
|
||||
mockAPIData({
|
||||
type: 'icons',
|
||||
provider,
|
||||
prefix,
|
||||
response: {
|
||||
@ -187,6 +189,7 @@ describe('Rendering icon', () => {
|
||||
const name = 'missing-icon';
|
||||
const iconName = `@${provider}:${prefix}:${name}`;
|
||||
mockAPIData({
|
||||
type: 'icons',
|
||||
provider,
|
||||
prefix,
|
||||
response: 404,
|
||||
|
@ -46,6 +46,7 @@ describe('Rendering icon', () => {
|
||||
};
|
||||
|
||||
mockAPIData({
|
||||
type: 'icons',
|
||||
provider,
|
||||
prefix,
|
||||
response: {
|
||||
@ -110,6 +111,7 @@ describe('Rendering icon', () => {
|
||||
});
|
||||
|
||||
mockAPIData({
|
||||
type: 'icons',
|
||||
provider,
|
||||
prefix,
|
||||
response: {
|
||||
@ -197,6 +199,7 @@ describe('Rendering icon', () => {
|
||||
let isSync = true;
|
||||
|
||||
mockAPIData({
|
||||
type: 'icons',
|
||||
provider,
|
||||
prefix,
|
||||
response: {
|
||||
@ -215,6 +218,7 @@ describe('Rendering icon', () => {
|
||||
});
|
||||
|
||||
mockAPIData({
|
||||
type: 'icons',
|
||||
provider,
|
||||
prefix,
|
||||
response: {
|
||||
@ -300,6 +304,7 @@ describe('Rendering icon', () => {
|
||||
const className = `iconify iconify--${prefix} iconify--${provider}`;
|
||||
|
||||
mockAPIData({
|
||||
type: 'icons',
|
||||
provider,
|
||||
prefix,
|
||||
response: {
|
||||
|
@ -17,6 +17,7 @@ describe('Testing references', () => {
|
||||
const iconName = `@${provider}:${prefix}:${name}`;
|
||||
|
||||
mockAPIData({
|
||||
type: 'icons',
|
||||
provider,
|
||||
prefix,
|
||||
response: {
|
||||
@ -81,6 +82,7 @@ describe('Testing references', () => {
|
||||
let gotRef = false;
|
||||
|
||||
mockAPIData({
|
||||
type: 'icons',
|
||||
provider,
|
||||
prefix,
|
||||
response: {
|
||||
@ -139,6 +141,7 @@ describe('Testing references', () => {
|
||||
let gotRef = false;
|
||||
|
||||
mockAPIData({
|
||||
type: 'icons',
|
||||
provider,
|
||||
prefix,
|
||||
response: 404,
|
||||
|
@ -20,11 +20,7 @@ import {
|
||||
import type { IconifyIconBuildResult } from '@iconify/utils/lib/svg/build';
|
||||
import { fullIcon, IconifyIcon } from '@iconify/utils/lib/icon';
|
||||
|
||||
// Modules
|
||||
import { coreModules } from '@iconify/core/lib/modules';
|
||||
|
||||
// API
|
||||
import { API } from '@iconify/core/lib/api/';
|
||||
import {
|
||||
IconifyAPIFunctions,
|
||||
IconifyAPIInternalFunctions,
|
||||
@ -39,26 +35,26 @@ import {
|
||||
IconifyAPIModule,
|
||||
IconifyAPISendQuery,
|
||||
IconifyAPIPrepareIconsQuery,
|
||||
GetIconifyAPIModule,
|
||||
} from '@iconify/core/lib/api/modules';
|
||||
import { getAPIModule as getJSONPAPIModule } from '@iconify/core/lib/api/modules/jsonp';
|
||||
import { jsonpAPIModule } from '@iconify/core/lib/api/modules/jsonp';
|
||||
import {
|
||||
getAPIModule as getFetchAPIModule,
|
||||
fetchAPIModule,
|
||||
getFetch,
|
||||
setFetch,
|
||||
} from '@iconify/core/lib/api/modules/fetch';
|
||||
import {
|
||||
setAPIConfig,
|
||||
PartialIconifyAPIConfig,
|
||||
IconifyAPIConfig,
|
||||
getAPIConfig,
|
||||
GetAPIConfig,
|
||||
} from '@iconify/core/lib/api/config';
|
||||
import type {
|
||||
IconifyIconLoaderCallback,
|
||||
IconifyIconLoaderAbort,
|
||||
} from '@iconify/core/lib/interfaces/loader';
|
||||
} from '@iconify/core/lib/api/icons';
|
||||
|
||||
// Cache
|
||||
import { cache } from '@iconify/core/lib/cache';
|
||||
import { storeCache, loadCache } from '@iconify/core/lib/browser-storage';
|
||||
import { toggleBrowserCache } from '@iconify/core/lib/browser-storage/functions';
|
||||
import type {
|
||||
@ -197,33 +193,15 @@ export const _api = APIInternalFunctions;
|
||||
// Enable short names
|
||||
allowSimpleNames(true);
|
||||
|
||||
// Set API
|
||||
coreModules.api = API;
|
||||
|
||||
// Use Fetch API by default
|
||||
let getAPIModule: GetIconifyAPIModule = getFetchAPIModule;
|
||||
try {
|
||||
if (typeof document !== 'undefined' && typeof window !== 'undefined') {
|
||||
// If window and document exist, attempt to load whatever module is available, otherwise use Fetch API
|
||||
getAPIModule =
|
||||
typeof fetch === 'function' && typeof Promise === 'function'
|
||||
? getFetchAPIModule
|
||||
: getJSONPAPIModule;
|
||||
}
|
||||
} catch (err) {
|
||||
//
|
||||
}
|
||||
setAPIModule('', getAPIModule(getAPIConfig));
|
||||
// Set API module
|
||||
setAPIModule('', getFetch() ? fetchAPIModule : jsonpAPIModule);
|
||||
|
||||
/**
|
||||
* Function to enable node-fetch for getting icons on server side
|
||||
*/
|
||||
_api.setFetch = (nodeFetch: typeof fetch) => {
|
||||
setFetch(nodeFetch);
|
||||
if (getAPIModule !== getFetchAPIModule) {
|
||||
getAPIModule = getFetchAPIModule;
|
||||
setAPIModule('', getAPIModule(getAPIConfig));
|
||||
}
|
||||
setAPIModule('', fetchAPIModule);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -231,7 +209,7 @@ _api.setFetch = (nodeFetch: typeof fetch) => {
|
||||
*/
|
||||
if (typeof document !== 'undefined' && typeof window !== 'undefined') {
|
||||
// Set cache and load existing cache
|
||||
coreModules.cache = storeCache;
|
||||
cache.store = storeCache;
|
||||
loadCache();
|
||||
|
||||
interface WindowWithIconifyStuff {
|
||||
@ -380,7 +358,7 @@ export function checkIconState(
|
||||
state.name = '';
|
||||
state.loading = {
|
||||
name: icon,
|
||||
abort: API.loadIcons([iconName], callback),
|
||||
abort: loadIcons([iconName], callback),
|
||||
};
|
||||
}
|
||||
return null;
|
||||
|
@ -8,6 +8,7 @@ describe('Testing fake API', () => {
|
||||
const name = 'mock-test';
|
||||
const iconName = `@${provider}:${prefix}:${name}`;
|
||||
mockAPIData({
|
||||
type: 'icons',
|
||||
provider,
|
||||
prefix,
|
||||
response: {
|
||||
|
@ -18,6 +18,7 @@ describe('Rendering icon', () => {
|
||||
let onLoadCalled = false;
|
||||
|
||||
mockAPIData({
|
||||
type: 'icons',
|
||||
provider,
|
||||
prefix,
|
||||
response: {
|
||||
@ -79,6 +80,7 @@ describe('Rendering icon', () => {
|
||||
let onLoadCalled = false;
|
||||
|
||||
mockAPIData({
|
||||
type: 'icons',
|
||||
provider,
|
||||
prefix,
|
||||
response: {
|
||||
@ -152,6 +154,7 @@ describe('Rendering icon', () => {
|
||||
const iconName = `@${provider}:${prefix}:${name}`;
|
||||
|
||||
mockAPIData({
|
||||
type: 'icons',
|
||||
provider,
|
||||
prefix,
|
||||
response: 404,
|
||||
|
@ -29,6 +29,7 @@ describe('Rendering icon', () => {
|
||||
let triggerSwap;
|
||||
|
||||
mockAPIData({
|
||||
type: 'icons',
|
||||
provider,
|
||||
prefix,
|
||||
response: {
|
||||
@ -78,6 +79,7 @@ describe('Rendering icon', () => {
|
||||
});
|
||||
|
||||
mockAPIData({
|
||||
type: 'icons',
|
||||
provider,
|
||||
prefix,
|
||||
response: {
|
||||
@ -172,6 +174,7 @@ describe('Rendering icon', () => {
|
||||
let triggerSwap;
|
||||
|
||||
mockAPIData({
|
||||
type: 'icons',
|
||||
provider,
|
||||
prefix,
|
||||
response: {
|
||||
@ -193,6 +196,7 @@ describe('Rendering icon', () => {
|
||||
});
|
||||
|
||||
mockAPIData({
|
||||
type: 'icons',
|
||||
provider,
|
||||
prefix,
|
||||
response: {
|
||||
@ -280,6 +284,7 @@ describe('Rendering icon', () => {
|
||||
let triggerSwap;
|
||||
|
||||
mockAPIData({
|
||||
type: 'icons',
|
||||
provider,
|
||||
prefix,
|
||||
response: {
|
||||
|
@ -30,11 +30,7 @@ import {
|
||||
import { IconifyIconBuildResult } from '@iconify/utils/lib/svg/build';
|
||||
import { fullIcon, IconifyIcon } from '@iconify/utils/lib/icon';
|
||||
|
||||
// Modules
|
||||
import { coreModules } from '@iconify/core/lib/modules';
|
||||
|
||||
// API
|
||||
import { API } from '@iconify/core/lib/api/';
|
||||
import {
|
||||
IconifyAPIFunctions,
|
||||
IconifyAPIInternalFunctions,
|
||||
@ -49,26 +45,26 @@ import {
|
||||
IconifyAPIModule,
|
||||
IconifyAPISendQuery,
|
||||
IconifyAPIPrepareIconsQuery,
|
||||
GetIconifyAPIModule,
|
||||
} from '@iconify/core/lib/api/modules';
|
||||
import { getAPIModule as getJSONPAPIModule } from '@iconify/core/lib/api/modules/jsonp';
|
||||
import { jsonpAPIModule } from '@iconify/core/lib/api/modules/jsonp';
|
||||
import {
|
||||
getAPIModule as getFetchAPIModule,
|
||||
fetchAPIModule,
|
||||
getFetch,
|
||||
setFetch,
|
||||
} from '@iconify/core/lib/api/modules/fetch';
|
||||
import {
|
||||
setAPIConfig,
|
||||
PartialIconifyAPIConfig,
|
||||
IconifyAPIConfig,
|
||||
getAPIConfig,
|
||||
GetAPIConfig,
|
||||
} from '@iconify/core/lib/api/config';
|
||||
import {
|
||||
IconifyIconLoaderCallback,
|
||||
IconifyIconLoaderAbort,
|
||||
} from '@iconify/core/lib/interfaces/loader';
|
||||
} from '@iconify/core/lib/api/icons';
|
||||
|
||||
// Cache
|
||||
import { cache } from '@iconify/core/lib/cache';
|
||||
import { storeCache, loadCache } from '@iconify/core/lib/browser-storage';
|
||||
import { toggleBrowserCache } from '@iconify/core/lib/browser-storage/functions';
|
||||
import {
|
||||
@ -208,33 +204,15 @@ export const _api = APIInternalFunctions;
|
||||
// Enable short names
|
||||
allowSimpleNames(true);
|
||||
|
||||
// Set API
|
||||
coreModules.api = API;
|
||||
|
||||
// Use Fetch API by default
|
||||
let getAPIModule: GetIconifyAPIModule = getFetchAPIModule;
|
||||
try {
|
||||
if (typeof document !== 'undefined' && typeof window !== 'undefined') {
|
||||
// If window and document exist, attempt to load whatever module is available, otherwise use Fetch API
|
||||
getAPIModule =
|
||||
typeof fetch === 'function' && typeof Promise === 'function'
|
||||
? getFetchAPIModule
|
||||
: getJSONPAPIModule;
|
||||
}
|
||||
} catch (err) {
|
||||
//
|
||||
}
|
||||
setAPIModule('', getAPIModule(getAPIConfig));
|
||||
// Set API module
|
||||
setAPIModule('', getFetch() ? fetchAPIModule : jsonpAPIModule);
|
||||
|
||||
/**
|
||||
* Function to enable node-fetch for getting icons on server side
|
||||
*/
|
||||
_api.setFetch = (nodeFetch: typeof fetch) => {
|
||||
setFetch(nodeFetch);
|
||||
if (getAPIModule !== getFetchAPIModule) {
|
||||
getAPIModule = getFetchAPIModule;
|
||||
setAPIModule('', getAPIModule(getAPIConfig));
|
||||
}
|
||||
setAPIModule('', fetchAPIModule);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -242,7 +220,7 @@ _api.setFetch = (nodeFetch: typeof fetch) => {
|
||||
*/
|
||||
if (typeof document !== 'undefined' && typeof window !== 'undefined') {
|
||||
// Set cache and load existing cache
|
||||
coreModules.cache = storeCache;
|
||||
cache.store = storeCache;
|
||||
loadCache();
|
||||
|
||||
interface WindowWithIconifyStuff {
|
||||
@ -388,7 +366,7 @@ export const Icon = defineComponent({
|
||||
this._name = '';
|
||||
this._loadingIcon = {
|
||||
name: icon,
|
||||
abort: API.loadIcons([iconName], () => {
|
||||
abort: loadIcons([iconName], () => {
|
||||
this.counter++;
|
||||
}),
|
||||
};
|
||||
|
@ -8,6 +8,7 @@ describe('Testing fake API', () => {
|
||||
const name = 'mock-test';
|
||||
const iconName = `@${provider}:${prefix}:${name}`;
|
||||
mockAPIData({
|
||||
type: 'icons',
|
||||
provider,
|
||||
prefix,
|
||||
response: {
|
||||
|
@ -19,6 +19,7 @@ describe('Rendering icon', () => {
|
||||
let onLoadCalled = false;
|
||||
|
||||
mockAPIData({
|
||||
type: 'icons',
|
||||
provider,
|
||||
prefix,
|
||||
response: {
|
||||
@ -84,6 +85,7 @@ describe('Rendering icon', () => {
|
||||
let onLoadCalled = false;
|
||||
|
||||
mockAPIData({
|
||||
type: 'icons',
|
||||
provider,
|
||||
prefix,
|
||||
response: {
|
||||
@ -163,6 +165,7 @@ describe('Rendering icon', () => {
|
||||
const name = 'missing-icon';
|
||||
const iconName = `@${provider}:${prefix}:${name}`;
|
||||
mockAPIData({
|
||||
type: 'icons',
|
||||
provider,
|
||||
prefix,
|
||||
response: 404,
|
||||
|
@ -47,6 +47,7 @@ describe('Rendering icon', () => {
|
||||
};
|
||||
|
||||
mockAPIData({
|
||||
type: 'icons',
|
||||
provider,
|
||||
prefix,
|
||||
response: {
|
||||
@ -90,6 +91,7 @@ describe('Rendering icon', () => {
|
||||
});
|
||||
|
||||
mockAPIData({
|
||||
type: 'icons',
|
||||
provider,
|
||||
prefix,
|
||||
response: {
|
||||
@ -160,6 +162,7 @@ describe('Rendering icon', () => {
|
||||
let isSync = true;
|
||||
|
||||
mockAPIData({
|
||||
type: 'icons',
|
||||
provider,
|
||||
prefix,
|
||||
response: {
|
||||
@ -178,6 +181,7 @@ describe('Rendering icon', () => {
|
||||
});
|
||||
|
||||
mockAPIData({
|
||||
type: 'icons',
|
||||
provider,
|
||||
prefix,
|
||||
response: {
|
||||
@ -245,6 +249,7 @@ describe('Rendering icon', () => {
|
||||
const className = `iconify iconify--${prefix} iconify--${provider}`;
|
||||
|
||||
mockAPIData({
|
||||
type: 'icons',
|
||||
provider,
|
||||
prefix,
|
||||
response: {
|
||||
|
@ -22,11 +22,7 @@ import {
|
||||
import { IconifyIconBuildResult } from '@iconify/utils/lib/svg/build';
|
||||
import { fullIcon, IconifyIcon } from '@iconify/utils/lib/icon';
|
||||
|
||||
// Modules
|
||||
import { coreModules } from '@iconify/core/lib/modules';
|
||||
|
||||
// API
|
||||
import { API } from '@iconify/core/lib/api/';
|
||||
import {
|
||||
IconifyAPIFunctions,
|
||||
IconifyAPIInternalFunctions,
|
||||
@ -41,26 +37,26 @@ import {
|
||||
IconifyAPIModule,
|
||||
IconifyAPISendQuery,
|
||||
IconifyAPIPrepareIconsQuery,
|
||||
GetIconifyAPIModule,
|
||||
} from '@iconify/core/lib/api/modules';
|
||||
import { getAPIModule as getJSONPAPIModule } from '@iconify/core/lib/api/modules/jsonp';
|
||||
import { jsonpAPIModule } from '@iconify/core/lib/api/modules/jsonp';
|
||||
import {
|
||||
getAPIModule as getFetchAPIModule,
|
||||
fetchAPIModule,
|
||||
getFetch,
|
||||
setFetch,
|
||||
} from '@iconify/core/lib/api/modules/fetch';
|
||||
import {
|
||||
setAPIConfig,
|
||||
PartialIconifyAPIConfig,
|
||||
IconifyAPIConfig,
|
||||
getAPIConfig,
|
||||
GetAPIConfig,
|
||||
} from '@iconify/core/lib/api/config';
|
||||
import {
|
||||
IconifyIconLoaderCallback,
|
||||
IconifyIconLoaderAbort,
|
||||
} from '@iconify/core/lib/interfaces/loader';
|
||||
} from '@iconify/core/lib/api/icons';
|
||||
|
||||
// Cache
|
||||
import { cache } from '@iconify/core/lib/cache';
|
||||
import { storeCache, loadCache } from '@iconify/core/lib/browser-storage';
|
||||
import { toggleBrowserCache } from '@iconify/core/lib/browser-storage/functions';
|
||||
import {
|
||||
@ -200,33 +196,15 @@ export const _api = APIInternalFunctions;
|
||||
// Enable short names
|
||||
allowSimpleNames(true);
|
||||
|
||||
// Set API
|
||||
coreModules.api = API;
|
||||
|
||||
// Use Fetch API by default
|
||||
let getAPIModule: GetIconifyAPIModule = getFetchAPIModule;
|
||||
try {
|
||||
if (typeof document !== 'undefined' && typeof window !== 'undefined') {
|
||||
// If window and document exist, attempt to load whatever module is available, otherwise use Fetch API
|
||||
getAPIModule =
|
||||
typeof fetch === 'function' && typeof Promise === 'function'
|
||||
? getFetchAPIModule
|
||||
: getJSONPAPIModule;
|
||||
}
|
||||
} catch (err) {
|
||||
//
|
||||
}
|
||||
setAPIModule('', getAPIModule(getAPIConfig));
|
||||
// Set API module
|
||||
setAPIModule('', getFetch() ? fetchAPIModule : jsonpAPIModule);
|
||||
|
||||
/**
|
||||
* Function to enable node-fetch for getting icons on server side
|
||||
*/
|
||||
_api.setFetch = (nodeFetch: typeof fetch) => {
|
||||
setFetch(nodeFetch);
|
||||
if (getAPIModule !== getFetchAPIModule) {
|
||||
getAPIModule = getFetchAPIModule;
|
||||
setAPIModule('', getAPIModule(getAPIConfig));
|
||||
}
|
||||
setAPIModule('', fetchAPIModule);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -234,7 +212,7 @@ _api.setFetch = (nodeFetch: typeof fetch) => {
|
||||
*/
|
||||
if (typeof document !== 'undefined' && typeof window !== 'undefined') {
|
||||
// Set cache and load existing cache
|
||||
coreModules.cache = storeCache;
|
||||
cache.store = storeCache;
|
||||
loadCache();
|
||||
|
||||
interface WindowWithIconifyStuff {
|
||||
@ -378,7 +356,7 @@ export const Icon = Vue.extend({
|
||||
this._name = '';
|
||||
this._loadingIcon = {
|
||||
name: icon,
|
||||
abort: API.loadIcons([iconName], () => {
|
||||
abort: loadIcons([iconName], () => {
|
||||
this.$forceUpdate();
|
||||
}),
|
||||
};
|
||||
|
@ -3,11 +3,12 @@ import { mockAPIData } from '@iconify/core/lib/api/modules/mock';
|
||||
import { provider, nextPrefix } from './load';
|
||||
|
||||
describe('Testing fake API', () => {
|
||||
test('using fake API to load icon', done => {
|
||||
test('using fake API to load icon', (done) => {
|
||||
const prefix = nextPrefix();
|
||||
const name = 'mock-test';
|
||||
const iconName = `@${provider}:${prefix}:${name}`;
|
||||
mockAPIData({
|
||||
type: 'icons',
|
||||
provider,
|
||||
prefix,
|
||||
response: {
|
||||
|
@ -18,6 +18,7 @@ describe('Rendering icon', () => {
|
||||
let onLoadCalled = false;
|
||||
|
||||
mockAPIData({
|
||||
type: 'icons',
|
||||
provider,
|
||||
prefix,
|
||||
response: {
|
||||
@ -83,6 +84,7 @@ describe('Rendering icon', () => {
|
||||
let onLoadCalled = false;
|
||||
|
||||
mockAPIData({
|
||||
type: 'icons',
|
||||
provider,
|
||||
prefix,
|
||||
response: {
|
||||
@ -163,6 +165,7 @@ describe('Rendering icon', () => {
|
||||
const name = 'missing-icon';
|
||||
const iconName = `@${provider}:${prefix}:${name}`;
|
||||
mockAPIData({
|
||||
type: 'icons',
|
||||
provider,
|
||||
prefix,
|
||||
response: 404,
|
||||
|
@ -45,6 +45,7 @@ describe('Rendering icon', () => {
|
||||
};
|
||||
|
||||
mockAPIData({
|
||||
type: 'icons',
|
||||
provider,
|
||||
prefix,
|
||||
response: {
|
||||
@ -88,6 +89,7 @@ describe('Rendering icon', () => {
|
||||
});
|
||||
|
||||
mockAPIData({
|
||||
type: 'icons',
|
||||
provider,
|
||||
prefix,
|
||||
response: {
|
||||
@ -156,6 +158,7 @@ describe('Rendering icon', () => {
|
||||
let isSync = true;
|
||||
|
||||
mockAPIData({
|
||||
type: 'icons',
|
||||
provider,
|
||||
prefix,
|
||||
response: {
|
||||
@ -174,6 +177,7 @@ describe('Rendering icon', () => {
|
||||
});
|
||||
|
||||
mockAPIData({
|
||||
type: 'icons',
|
||||
provider,
|
||||
prefix,
|
||||
response: {
|
||||
@ -240,6 +244,7 @@ describe('Rendering icon', () => {
|
||||
const className = `iconify iconify--${prefix} iconify--${provider}`;
|
||||
|
||||
mockAPIData({
|
||||
type: 'icons',
|
||||
provider,
|
||||
prefix,
|
||||
response: {
|
||||
|
Loading…
Reference in New Issue
Block a user