mirror of
https://github.com/iconify/iconify.git
synced 2025-01-28 09:38:41 +00:00
Refactor addCollection in core: move it to separate reusable function. Publish RC.1
This commit is contained in:
parent
d5f199a42e
commit
9e2e2d315e
148
packages/core/package-lock.json
generated
148
packages/core/package-lock.json
generated
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@iconify/core",
|
||||
"version": "1.0.0-beta.5",
|
||||
"version": "1.0.0-rc.1",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
@ -48,6 +48,47 @@
|
||||
"resolved": "https://registry.npmjs.org/@cyberalien/redundancy/-/redundancy-1.0.0.tgz",
|
||||
"integrity": "sha512-/tx5GpGSyMn5FrOSggDSm9yJDLcEXiK0+zdCBssST6w9QgdJjoQ9lRBSxql/3vgQoI+7XbubWsP86jjbuVnFcA=="
|
||||
},
|
||||
"@eslint/eslintrc": {
|
||||
"version": "0.1.3",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.1.3.tgz",
|
||||
"integrity": "sha512-4YVwPkANLeNtRjMekzux1ci8hIaH5eGKktGqR0d3LWsKNn5B2X/1Z6Trxy7jQXl9EBGE6Yj02O+t09FMeRllaA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ajv": "^6.12.4",
|
||||
"debug": "^4.1.1",
|
||||
"espree": "^7.3.0",
|
||||
"globals": "^12.1.0",
|
||||
"ignore": "^4.0.6",
|
||||
"import-fresh": "^3.2.1",
|
||||
"js-yaml": "^3.13.1",
|
||||
"lodash": "^4.17.19",
|
||||
"minimatch": "^3.0.4",
|
||||
"strip-json-comments": "^3.1.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"debug": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
|
||||
"integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ms": "^2.1.1"
|
||||
}
|
||||
},
|
||||
"ignore": {
|
||||
"version": "4.0.6",
|
||||
"resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
|
||||
"integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==",
|
||||
"dev": true
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"@iconify/types": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@iconify/types/-/types-1.0.3.tgz",
|
||||
@ -98,9 +139,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"@types/json-schema": {
|
||||
"version": "7.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.5.tgz",
|
||||
"integrity": "sha512-7+2BITlgjgDhH0vvwZU/HZJVyk+2XUlvxXe8dFMedNX/aMkaOq++rMAFXc0tM7ij15QaWlbdQASBR9dihi+bDQ==",
|
||||
"version": "7.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.6.tgz",
|
||||
"integrity": "sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/mocha": {
|
||||
@ -110,9 +151,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"@types/node": {
|
||||
"version": "14.6.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.6.2.tgz",
|
||||
"integrity": "sha512-onlIwbaeqvZyniGPfdw/TEhKIh79pz66L1q06WUQqJLnAb6wbjvOtepLYTGHTqzdXgBYIE3ZdmqHDGsRsbBz7A==",
|
||||
"version": "14.6.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.6.3.tgz",
|
||||
"integrity": "sha512-pC/hkcREG6YfDfui1FBmj8e20jFU5Exjw4NYDm8kEdrW+mOh0T1Zve8DWKnS7ZIZvgncrctcNCXF4Q2I+loyww==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/request": {
|
||||
@ -134,13 +175,13 @@
|
||||
"dev": true
|
||||
},
|
||||
"@typescript-eslint/eslint-plugin": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.0.0.tgz",
|
||||
"integrity": "sha512-5e6q1TR7gS2P+8W2xndCu7gBh3BzmYEo70OyIdsmCmknHha/yNbz2vdevl+tP1uoaMOcrzg4gyrAijuV3DDBHA==",
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.0.1.tgz",
|
||||
"integrity": "sha512-pQZtXupCn11O4AwpYVUX4PDFfmIJl90ZgrEBg0CEcqlwvPiG0uY81fimr1oMFblZnpKAq6prrT9a59pj1x58rw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@typescript-eslint/experimental-utils": "4.0.0",
|
||||
"@typescript-eslint/scope-manager": "4.0.0",
|
||||
"@typescript-eslint/experimental-utils": "4.0.1",
|
||||
"@typescript-eslint/scope-manager": "4.0.1",
|
||||
"debug": "^4.1.1",
|
||||
"functional-red-black-tree": "^1.0.1",
|
||||
"regexpp": "^3.0.0",
|
||||
@ -166,28 +207,28 @@
|
||||
}
|
||||
},
|
||||
"@typescript-eslint/experimental-utils": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.0.0.tgz",
|
||||
"integrity": "sha512-hbX6zR+a/vcpFVNJYN/Nbd7gmaMosDTxHEKcvmhWeWcq/0UDifrqmCfkkodbAKL46Fn4ekSBMTyq2zlNDzcQxw==",
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.0.1.tgz",
|
||||
"integrity": "sha512-gAqOjLiHoED79iYTt3F4uSHrYmg/GPz/zGezdB0jAdr6S6gwNiR/j7cTZ8nREKVzMVKLd9G3xbg1sV9GClW3sw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/json-schema": "^7.0.3",
|
||||
"@typescript-eslint/scope-manager": "4.0.0",
|
||||
"@typescript-eslint/types": "4.0.0",
|
||||
"@typescript-eslint/typescript-estree": "4.0.0",
|
||||
"@typescript-eslint/scope-manager": "4.0.1",
|
||||
"@typescript-eslint/types": "4.0.1",
|
||||
"@typescript-eslint/typescript-estree": "4.0.1",
|
||||
"eslint-scope": "^5.0.0",
|
||||
"eslint-utils": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"@typescript-eslint/parser": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.0.0.tgz",
|
||||
"integrity": "sha512-KuBwTUzc3G3dD5k9ybTjgqIQjjJPY6WPaEoxdNS5vN5XV/Tixp0itA14+NQlbeswTHvsELaKXZhynxD/O2wHFA==",
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.0.1.tgz",
|
||||
"integrity": "sha512-1+qLmXHNAWSQ7RB6fdSQszAiA7JTwzakj5cNYjBTUmpH2cqilxMZEIV+DRKjVZs8NzP3ALmKexB0w/ExjcK9Iw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@typescript-eslint/scope-manager": "4.0.0",
|
||||
"@typescript-eslint/types": "4.0.0",
|
||||
"@typescript-eslint/typescript-estree": "4.0.0",
|
||||
"@typescript-eslint/scope-manager": "4.0.1",
|
||||
"@typescript-eslint/types": "4.0.1",
|
||||
"@typescript-eslint/typescript-estree": "4.0.1",
|
||||
"debug": "^4.1.1"
|
||||
},
|
||||
"dependencies": {
|
||||
@ -209,29 +250,29 @@
|
||||
}
|
||||
},
|
||||
"@typescript-eslint/scope-manager": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.0.0.tgz",
|
||||
"integrity": "sha512-9gcWUPoWo7gk/+ZQPg7L1ySRmR5HLIy3Vu6/LfhQbuzIkGm6v2CGIjpVRISoDLFRovNRDImd4aP/sa8O4yIEBg==",
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.0.1.tgz",
|
||||
"integrity": "sha512-u3YEXVJ8jsj7QCJk3om0Y457fy2euEOkkzxIB/LKU3MdyI+FJ2gI0M4aKEaXzwCSfNDiZ13a3lDo5DVozc+XLQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@typescript-eslint/types": "4.0.0",
|
||||
"@typescript-eslint/visitor-keys": "4.0.0"
|
||||
"@typescript-eslint/types": "4.0.1",
|
||||
"@typescript-eslint/visitor-keys": "4.0.1"
|
||||
}
|
||||
},
|
||||
"@typescript-eslint/types": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.0.0.tgz",
|
||||
"integrity": "sha512-bK+c2VLzznX2fUWLK6pFDv3cXGTp7nHIuBMq1B9klA+QCsqLHOOqe5TQReAQDl7DN2RfH+neweo0oC5hYlG7Rg==",
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.0.1.tgz",
|
||||
"integrity": "sha512-S+gD3fgbkZYW2rnbjugNMqibm9HpEjqZBZkTiI3PwbbNGWmAcxolWIUwZ0SKeG4Dy2ktpKKaI/6+HGYVH8Qrlg==",
|
||||
"dev": true
|
||||
},
|
||||
"@typescript-eslint/typescript-estree": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.0.0.tgz",
|
||||
"integrity": "sha512-ewFMPi2pMLDNIXGMPdf8r7El2oPSZw9PEYB0j+WcpKd7AX2ARmajGa7RUHTukllWX2bj4vWX6JLE1Oih2BMokA==",
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.0.1.tgz",
|
||||
"integrity": "sha512-zGzleORFXrRWRJAMLTB2iJD1IZbCPkg4hsI8mGdpYlKaqzvKYSEWVAYh14eauaR+qIoZVWrXgYSXqLtTlxotiw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@typescript-eslint/types": "4.0.0",
|
||||
"@typescript-eslint/visitor-keys": "4.0.0",
|
||||
"@typescript-eslint/types": "4.0.1",
|
||||
"@typescript-eslint/visitor-keys": "4.0.1",
|
||||
"debug": "^4.1.1",
|
||||
"globby": "^11.0.1",
|
||||
"is-glob": "^4.0.1",
|
||||
@ -258,12 +299,12 @@
|
||||
}
|
||||
},
|
||||
"@typescript-eslint/visitor-keys": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.0.0.tgz",
|
||||
"integrity": "sha512-sTouJbv6rjVJeTE4lpSBVYXq/u5K3gbB6LKt7ccFEZPTZB/VeQ0ssUz9q5Hx++sCqBbdF8PzrrgvEnicXAR6NQ==",
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.0.1.tgz",
|
||||
"integrity": "sha512-yBSqd6FjnTzbg5RUy9J+9kJEyQjTI34JdGMJz+9ttlJzLCnGkBikxw+N5n2VDcc3CesbIEJ0MnZc5uRYnrEnCw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@typescript-eslint/types": "4.0.0",
|
||||
"@typescript-eslint/types": "4.0.1",
|
||||
"eslint-visitor-keys": "^2.0.0"
|
||||
}
|
||||
},
|
||||
@ -724,12 +765,13 @@
|
||||
"dev": true
|
||||
},
|
||||
"eslint": {
|
||||
"version": "7.7.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint/-/eslint-7.7.0.tgz",
|
||||
"integrity": "sha512-1KUxLzos0ZVsyL81PnRN335nDtQ8/vZUD6uMtWbF+5zDtjKcsklIi78XoE0MVL93QvWTu+E5y44VyyCsOMBrIg==",
|
||||
"version": "7.8.1",
|
||||
"resolved": "https://registry.npmjs.org/eslint/-/eslint-7.8.1.tgz",
|
||||
"integrity": "sha512-/2rX2pfhyUG0y+A123d0ccXtMm7DV7sH1m3lk9nk2DZ2LReq39FXHueR9xZwshE5MdfSf0xunSaMWRqyIA6M1w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/code-frame": "^7.0.0",
|
||||
"@eslint/eslintrc": "^0.1.3",
|
||||
"ajv": "^6.10.0",
|
||||
"chalk": "^4.0.0",
|
||||
"cross-spawn": "^7.0.2",
|
||||
@ -739,7 +781,7 @@
|
||||
"eslint-scope": "^5.1.0",
|
||||
"eslint-utils": "^2.1.0",
|
||||
"eslint-visitor-keys": "^1.3.0",
|
||||
"espree": "^7.2.0",
|
||||
"espree": "^7.3.0",
|
||||
"esquery": "^1.2.0",
|
||||
"esutils": "^2.0.2",
|
||||
"file-entry-cache": "^5.0.1",
|
||||
@ -872,12 +914,20 @@
|
||||
}
|
||||
},
|
||||
"esrecurse": {
|
||||
"version": "4.2.1",
|
||||
"resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz",
|
||||
"integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==",
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
|
||||
"integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"estraverse": "^4.1.0"
|
||||
"estraverse": "^5.2.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"estraverse": {
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz",
|
||||
"integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"estraverse": {
|
||||
|
@ -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.0.0-beta.5",
|
||||
"version": "1.0.0-rc.1",
|
||||
"license": "(Apache-2.0 OR GPL-2.0)",
|
||||
"bugs": "https://github.com/iconify/iconify/issues",
|
||||
"homepage": "https://iconify.design/",
|
||||
@ -24,12 +24,12 @@
|
||||
"devDependencies": {
|
||||
"@types/chai": "^4.2.12",
|
||||
"@types/mocha": "^8.0.3",
|
||||
"@types/node": "^14.6.2",
|
||||
"@types/node": "^14.6.3",
|
||||
"@types/request": "^2.48.5",
|
||||
"@typescript-eslint/eslint-plugin": "^4.0.0",
|
||||
"@typescript-eslint/parser": "^4.0.0",
|
||||
"@typescript-eslint/eslint-plugin": "^4.0.1",
|
||||
"@typescript-eslint/parser": "^4.0.1",
|
||||
"chai": "^4.2.0",
|
||||
"eslint": "^7.7.0",
|
||||
"eslint": "^7.8.1",
|
||||
"mocha": "^8.1.3",
|
||||
"typescript": "^4.0.2"
|
||||
},
|
||||
|
132
packages/core/src/icon/icon-set.ts
Normal file
132
packages/core/src/icon/icon-set.ts
Normal file
@ -0,0 +1,132 @@
|
||||
import {
|
||||
IconifyJSON,
|
||||
IconifyIcon,
|
||||
IconifyOptional,
|
||||
IconifyAlias,
|
||||
IconifyIcons,
|
||||
IconifyAliases,
|
||||
} from '@iconify/types';
|
||||
import { iconDefaults, FullIconifyIcon } from '.';
|
||||
import { merge } from '../misc/merge';
|
||||
import { mergeIcons } from './merge';
|
||||
|
||||
/**
|
||||
* What to track when adding icon set:
|
||||
*
|
||||
* none - do not track anything, return true on success
|
||||
* added - track added icons, return list of added icons on success
|
||||
* all - track added and missing icons, return full list on success
|
||||
*/
|
||||
export type AddIconSetTracking = 'none' | 'added' | 'all';
|
||||
|
||||
/**
|
||||
* Callback to add icon to storage.
|
||||
*
|
||||
* If data === null, icon is missing.
|
||||
*/
|
||||
export type SplitIconSetCallback = (
|
||||
name: string,
|
||||
data: FullIconifyIcon | null
|
||||
) => void;
|
||||
|
||||
/**
|
||||
* Get list of defaults keys
|
||||
*/
|
||||
const defaultsKeys = Object.keys(iconDefaults) as (keyof IconifyOptional)[];
|
||||
|
||||
/**
|
||||
* Resolve alias
|
||||
*/
|
||||
function resolveAlias(
|
||||
alias: IconifyAlias,
|
||||
icons: IconifyIcons,
|
||||
aliases: IconifyAliases,
|
||||
level = 0
|
||||
): IconifyIcon | null {
|
||||
const parent = alias.parent;
|
||||
if (icons[parent] !== void 0) {
|
||||
return mergeIcons(icons[parent], (alias as unknown) as IconifyIcon);
|
||||
}
|
||||
if (aliases[parent] !== void 0) {
|
||||
if (level > 2) {
|
||||
// icon + alias + alias + alias = too much nesting, possibly infinite
|
||||
return null;
|
||||
}
|
||||
const icon = resolveAlias(aliases[parent], icons, aliases, level + 1);
|
||||
if (icon) {
|
||||
return mergeIcons(icon, (alias as unknown) as IconifyIcon);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract icons from an icon set
|
||||
*/
|
||||
export function parseIconSet(
|
||||
data: IconifyJSON,
|
||||
callback: SplitIconSetCallback,
|
||||
list: AddIconSetTracking = 'none'
|
||||
): boolean | string[] {
|
||||
const added: string[] = [];
|
||||
|
||||
// Must be an object
|
||||
if (typeof data !== 'object') {
|
||||
return list === 'none' ? false : added;
|
||||
}
|
||||
|
||||
// Check for missing icons list returned by API
|
||||
if (data.not_found instanceof Array) {
|
||||
data.not_found.forEach((name) => {
|
||||
callback(name, null);
|
||||
if (list === 'all') {
|
||||
added.push(name);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Must have 'icons' object
|
||||
if (typeof data.icons !== 'object') {
|
||||
return list === 'none' ? false : added;
|
||||
}
|
||||
|
||||
// Get default values
|
||||
const defaults = Object.create(null);
|
||||
defaultsKeys.forEach((key) => {
|
||||
if (data[key] !== void 0 && typeof data[key] !== 'object') {
|
||||
defaults[key] = data[key];
|
||||
}
|
||||
});
|
||||
|
||||
// Get icons
|
||||
const icons = data.icons;
|
||||
Object.keys(icons).forEach((name) => {
|
||||
const icon = icons[name];
|
||||
if (typeof icon.body !== 'string') {
|
||||
return;
|
||||
}
|
||||
|
||||
// Freeze icon to make sure it will not be modified
|
||||
callback(name, Object.freeze(merge(iconDefaults, defaults, icon)));
|
||||
added.push(name);
|
||||
});
|
||||
|
||||
// Get aliases
|
||||
if (typeof data.aliases === 'object') {
|
||||
const aliases = data.aliases;
|
||||
Object.keys(aliases).forEach((name) => {
|
||||
const icon = resolveAlias(aliases[name], icons, aliases, 1);
|
||||
if (icon) {
|
||||
// Freeze icon to make sure it will not be modified
|
||||
callback(
|
||||
name,
|
||||
Object.freeze(merge(iconDefaults, defaults, icon))
|
||||
);
|
||||
added.push(name);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return list === 'none' ? added.length > 0 : added;
|
||||
}
|
@ -1,19 +1,6 @@
|
||||
import {
|
||||
IconifyJSON,
|
||||
IconifyIcon,
|
||||
IconifyOptional,
|
||||
IconifyIcons,
|
||||
IconifyAliases,
|
||||
IconifyAlias,
|
||||
} from '@iconify/types';
|
||||
import { FullIconifyIcon, iconDefaults, fullIcon } from '../icon';
|
||||
import { mergeIcons } from '../icon/merge';
|
||||
import { merge } from '../misc/merge';
|
||||
|
||||
/**
|
||||
* Get list of defaults keys
|
||||
*/
|
||||
const defaultsKeys = Object.keys(iconDefaults) as (keyof IconifyOptional)[];
|
||||
import { IconifyJSON, IconifyIcon } from '@iconify/types';
|
||||
import { FullIconifyIcon, fullIcon } from '../icon';
|
||||
import { AddIconSetTracking, parseIconSet } from '../icon/icon-set';
|
||||
|
||||
/**
|
||||
* List of icons
|
||||
@ -63,42 +50,6 @@ export function getStorage(provider: string, prefix: string): IconStorage {
|
||||
return providerStorage[prefix];
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve alias
|
||||
*/
|
||||
function resolveAlias(
|
||||
alias: IconifyAlias,
|
||||
icons: IconifyIcons,
|
||||
aliases: IconifyAliases,
|
||||
level = 0
|
||||
): IconifyIcon | null {
|
||||
const parent = alias.parent;
|
||||
if (icons[parent] !== void 0) {
|
||||
return mergeIcons(icons[parent], (alias as unknown) as IconifyIcon);
|
||||
}
|
||||
if (aliases[parent] !== void 0) {
|
||||
if (level > 2) {
|
||||
// icon + alias + alias + alias = too much nesting, possibly infinite
|
||||
throw new Error('Invalid alias');
|
||||
}
|
||||
const icon = resolveAlias(aliases[parent], icons, aliases, level + 1);
|
||||
if (icon) {
|
||||
return mergeIcons(icon, (alias as unknown) as IconifyIcon);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* What to track when adding icon set:
|
||||
*
|
||||
* none - do not track anything, return true on success
|
||||
* added - track added icons, return list of added icons on success
|
||||
* all - track added and missing icons, return full list on success
|
||||
*/
|
||||
export type AddIconSetTracking = 'none' | 'added' | 'all';
|
||||
|
||||
/**
|
||||
* Add icon set to storage
|
||||
*
|
||||
@ -109,76 +60,18 @@ export function addIconSet(
|
||||
data: IconifyJSON,
|
||||
list: AddIconSetTracking = 'none'
|
||||
): boolean | string[] {
|
||||
const added: string[] = [];
|
||||
|
||||
try {
|
||||
// Must be an object
|
||||
if (typeof data !== 'object') {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check for missing icons list returned by API
|
||||
if (data.not_found instanceof Array) {
|
||||
const t = Date.now();
|
||||
data.not_found.forEach((name) => {
|
||||
const t = Date.now();
|
||||
return parseIconSet(
|
||||
data,
|
||||
(name, icon: FullIconifyIcon | null) => {
|
||||
if (icon === null) {
|
||||
storage.missing[name] = t;
|
||||
if (list === 'all') {
|
||||
added.push(name);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Must have 'icons' object
|
||||
if (typeof data.icons !== 'object') {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get default values
|
||||
const defaults = Object.create(null);
|
||||
defaultsKeys.forEach((key) => {
|
||||
if (data[key] !== void 0 && typeof data[key] !== 'object') {
|
||||
defaults[key] = data[key];
|
||||
} else {
|
||||
storage.icons[name] = icon;
|
||||
}
|
||||
});
|
||||
|
||||
// Get icons
|
||||
const icons = data.icons;
|
||||
Object.keys(icons).forEach((name) => {
|
||||
const icon = icons[name];
|
||||
if (typeof icon.body !== 'string') {
|
||||
throw new Error('Invalid icon');
|
||||
}
|
||||
|
||||
// Freeze icon to make sure it will not be modified
|
||||
storage.icons[name] = Object.freeze(
|
||||
merge(iconDefaults, defaults, icon)
|
||||
);
|
||||
if (list !== 'none') {
|
||||
added.push(name);
|
||||
}
|
||||
});
|
||||
|
||||
// Get aliases
|
||||
if (typeof data.aliases === 'object') {
|
||||
const aliases = data.aliases;
|
||||
Object.keys(aliases).forEach((name) => {
|
||||
const icon = resolveAlias(aliases[name], icons, aliases, 1);
|
||||
if (icon) {
|
||||
// Freeze icon to make sure it will not be modified
|
||||
storage.icons[name] = Object.freeze(
|
||||
merge(iconDefaults, defaults, icon)
|
||||
);
|
||||
if (list !== 'none') {
|
||||
added.push(name);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
} catch (err) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return list === 'none' ? true : added;
|
||||
},
|
||||
list
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
396
packages/core/tests/10-basic/parse-set-test.ts
Normal file
396
packages/core/tests/10-basic/parse-set-test.ts
Normal file
@ -0,0 +1,396 @@
|
||||
import 'mocha';
|
||||
import { expect } from 'chai';
|
||||
import { parseIconSet } from '../../lib/icon/icon-set';
|
||||
import { FullIconifyIcon } from '../../lib/icon';
|
||||
import { IconifyJSON } from '@iconify/types';
|
||||
|
||||
describe('Testing parsing icon set', () => {
|
||||
it('Simple icon set', () => {
|
||||
// Names list
|
||||
const names: string[] = ['missing', 'icon1', 'icon2'];
|
||||
|
||||
// Resolved data
|
||||
const expected: Record<string, FullIconifyIcon | null> = {
|
||||
icon1: {
|
||||
body: '<path d="icon1" />',
|
||||
width: 20,
|
||||
height: 24,
|
||||
top: 0,
|
||||
left: 0,
|
||||
hFlip: false,
|
||||
vFlip: false,
|
||||
rotate: 0,
|
||||
},
|
||||
icon2: {
|
||||
body: '<path d="icon2" />',
|
||||
width: 24,
|
||||
height: 24,
|
||||
top: 0,
|
||||
left: 0,
|
||||
hFlip: false,
|
||||
vFlip: false,
|
||||
rotate: 0,
|
||||
},
|
||||
missing: null,
|
||||
};
|
||||
|
||||
// Do stuff
|
||||
expect(
|
||||
parseIconSet(
|
||||
{
|
||||
prefix: 'foo',
|
||||
not_found: ['missing'],
|
||||
icons: {
|
||||
icon1: {
|
||||
body: '<path d="icon1" />',
|
||||
width: 20,
|
||||
},
|
||||
icon2: {
|
||||
body: '<path d="icon2" />',
|
||||
width: 24,
|
||||
},
|
||||
},
|
||||
height: 24,
|
||||
},
|
||||
(name, data) => {
|
||||
// Make sure name matches
|
||||
expect(names.length).to.be.at.least(1);
|
||||
expect(name).to.be.equal(names.shift());
|
||||
|
||||
// Check icon data
|
||||
expect(data).to.be.eql(expected[name]);
|
||||
}
|
||||
)
|
||||
).to.be.equal(true);
|
||||
|
||||
// All names should have been parsed
|
||||
expect(names).to.be.eql([], 'Not all icons have been parsed');
|
||||
});
|
||||
|
||||
it('Aliases', () => {
|
||||
// Names list
|
||||
const names: string[] = ['icon1', 'icon2', 'alias1', 'alias2'];
|
||||
const namesCopy = names.slice(0);
|
||||
|
||||
// Resolved data
|
||||
const expected: Record<string, FullIconifyIcon | null> = {
|
||||
icon1: {
|
||||
body: '<path d="icon1" />',
|
||||
width: 20,
|
||||
height: 24,
|
||||
top: 0,
|
||||
left: 0,
|
||||
hFlip: false,
|
||||
vFlip: false,
|
||||
rotate: 0,
|
||||
},
|
||||
icon2: {
|
||||
body: '<path d="icon2" />',
|
||||
width: 24,
|
||||
height: 24,
|
||||
top: 0,
|
||||
left: 0,
|
||||
hFlip: false,
|
||||
vFlip: true,
|
||||
rotate: 3,
|
||||
},
|
||||
alias1: {
|
||||
body: '<path d="icon1" />',
|
||||
width: 20,
|
||||
height: 24,
|
||||
top: 0,
|
||||
left: 0,
|
||||
hFlip: false,
|
||||
vFlip: false,
|
||||
rotate: 0,
|
||||
},
|
||||
alias2: {
|
||||
body: '<path d="icon2" />',
|
||||
width: 20,
|
||||
height: 24,
|
||||
top: 0,
|
||||
left: 0,
|
||||
hFlip: true,
|
||||
vFlip: true,
|
||||
rotate: 3,
|
||||
},
|
||||
};
|
||||
|
||||
// Do stuff
|
||||
expect(
|
||||
parseIconSet(
|
||||
{
|
||||
prefix: 'foo',
|
||||
icons: {
|
||||
icon1: {
|
||||
body: '<path d="icon1" />',
|
||||
width: 20,
|
||||
},
|
||||
icon2: {
|
||||
body: '<path d="icon2" />',
|
||||
width: 24,
|
||||
vFlip: true,
|
||||
rotate: 3,
|
||||
},
|
||||
},
|
||||
aliases: {
|
||||
alias1: {
|
||||
parent: 'icon1',
|
||||
},
|
||||
alias2: {
|
||||
parent: 'icon2',
|
||||
hFlip: true,
|
||||
width: 20,
|
||||
},
|
||||
},
|
||||
height: 24,
|
||||
},
|
||||
(name, data) => {
|
||||
// Make sure name matches
|
||||
expect(names.length).to.be.at.least(1);
|
||||
expect(name).to.be.equal(names.shift());
|
||||
|
||||
// Check icon data
|
||||
expect(data).to.be.eql(expected[name]);
|
||||
},
|
||||
'all'
|
||||
)
|
||||
).to.be.eql(namesCopy);
|
||||
|
||||
// All names should have been parsed
|
||||
expect(names).to.be.eql([], 'Not all icons have been parsed');
|
||||
});
|
||||
|
||||
it('Nested aliases', () => {
|
||||
// Names list
|
||||
const names: string[] = [
|
||||
'icon1',
|
||||
'icon2',
|
||||
'alias2a',
|
||||
'alias2f',
|
||||
'alias2z',
|
||||
'alias2z3',
|
||||
];
|
||||
const namesCopy = names.slice(0);
|
||||
|
||||
// Resolved data
|
||||
const expected: Record<string, FullIconifyIcon | null> = {
|
||||
icon1: {
|
||||
body: '<path d="icon1" />',
|
||||
width: 20,
|
||||
height: 20,
|
||||
top: 0,
|
||||
left: 0,
|
||||
hFlip: false,
|
||||
vFlip: false,
|
||||
rotate: 0,
|
||||
},
|
||||
icon2: {
|
||||
body: '<path d="icon2" />',
|
||||
width: 24,
|
||||
height: 24,
|
||||
top: 0,
|
||||
left: 0,
|
||||
hFlip: true,
|
||||
vFlip: false,
|
||||
rotate: 1,
|
||||
},
|
||||
alias2f: {
|
||||
// icon2 + alias2f
|
||||
body: '<path d="icon2" />',
|
||||
width: 22,
|
||||
height: 24,
|
||||
top: 0,
|
||||
left: 0,
|
||||
hFlip: false,
|
||||
vFlip: true,
|
||||
rotate: 2,
|
||||
},
|
||||
alias2a: {
|
||||
// icon2 + alias2f + alias2a
|
||||
body: '<path d="icon2" />',
|
||||
width: 20,
|
||||
height: 20,
|
||||
top: 0,
|
||||
left: 0,
|
||||
hFlip: false,
|
||||
vFlip: true,
|
||||
rotate: 2,
|
||||
},
|
||||
alias2z: {
|
||||
// icon2 + alias2f + alias2z
|
||||
body: '<path d="icon2" />',
|
||||
width: 21,
|
||||
height: 24,
|
||||
top: 0,
|
||||
left: 0,
|
||||
hFlip: false,
|
||||
vFlip: true,
|
||||
rotate: 1,
|
||||
},
|
||||
alias2z3: {
|
||||
// icon2 + alias2f + alias2z
|
||||
body: '<path d="icon2" />',
|
||||
width: 21,
|
||||
height: 24,
|
||||
top: 0,
|
||||
left: 0,
|
||||
hFlip: false,
|
||||
vFlip: true,
|
||||
rotate: 1,
|
||||
},
|
||||
};
|
||||
|
||||
// Do stuff
|
||||
expect(
|
||||
parseIconSet(
|
||||
{
|
||||
prefix: 'foo',
|
||||
icons: {
|
||||
icon1: {
|
||||
body: '<path d="icon1" />',
|
||||
width: 20,
|
||||
height: 20,
|
||||
},
|
||||
icon2: {
|
||||
body: '<path d="icon2" />',
|
||||
width: 24,
|
||||
rotate: 1,
|
||||
hFlip: true,
|
||||
},
|
||||
},
|
||||
aliases: {
|
||||
alias2a: {
|
||||
// Alias before parent
|
||||
parent: 'alias2f',
|
||||
width: 20,
|
||||
height: 20,
|
||||
},
|
||||
alias2f: {
|
||||
parent: 'icon2',
|
||||
width: 22,
|
||||
rotate: 1,
|
||||
hFlip: true,
|
||||
vFlip: true,
|
||||
},
|
||||
alias2z: {
|
||||
// Alias after parent
|
||||
parent: 'alias2f',
|
||||
width: 21,
|
||||
rotate: 3,
|
||||
},
|
||||
alias2z3: {
|
||||
// 3 parents: alias2z, alias2f, icon2
|
||||
parent: 'alias2z',
|
||||
},
|
||||
alias2z4: {
|
||||
// 4 parents: alias2z3, alias2z, alias2f, icon2
|
||||
// nesting is too deep and should not be parsed
|
||||
parent: 'alias2z3',
|
||||
},
|
||||
alias3: {
|
||||
// invalid parent
|
||||
parent: 'icon3',
|
||||
},
|
||||
},
|
||||
height: 24,
|
||||
},
|
||||
(name, data) => {
|
||||
// Make sure name matches
|
||||
expect(names.length).to.be.at.least(
|
||||
1,
|
||||
`Unexpected icon ${name}`
|
||||
);
|
||||
expect(name).to.be.equal(
|
||||
names.shift(),
|
||||
`Expected icon ${name} to be next`
|
||||
);
|
||||
|
||||
// Check icon data
|
||||
expect(data).to.be.eql(
|
||||
expected[name],
|
||||
`Invalid data for ${name}`
|
||||
);
|
||||
},
|
||||
'added'
|
||||
)
|
||||
).to.be.eql(namesCopy);
|
||||
|
||||
// All names should have been parsed
|
||||
expect(names).to.be.eql([], 'Not all icons have been parsed');
|
||||
});
|
||||
|
||||
it('Invalid default values', () => {
|
||||
// Names list
|
||||
const names: string[] = ['icon1', 'icon2'];
|
||||
const namesCopy = names.slice(0);
|
||||
|
||||
// Resolved data
|
||||
const expected: Record<string, FullIconifyIcon | null> = {
|
||||
icon1: {
|
||||
body: '<path d="icon1" />',
|
||||
width: 20,
|
||||
height: 20,
|
||||
top: 0,
|
||||
left: 0,
|
||||
hFlip: false,
|
||||
vFlip: false,
|
||||
rotate: 0,
|
||||
},
|
||||
icon2: {
|
||||
body: '<path d="icon2" />',
|
||||
width: 24,
|
||||
height: 24,
|
||||
top: 0,
|
||||
left: 0,
|
||||
hFlip: false,
|
||||
vFlip: false,
|
||||
rotate: 0,
|
||||
},
|
||||
};
|
||||
|
||||
const iconSet: IconifyJSON = ({
|
||||
icons: {
|
||||
icon1: {
|
||||
body: '<path d="icon1" />',
|
||||
width: 20,
|
||||
// Default should not override this
|
||||
height: 20,
|
||||
},
|
||||
icon2: {
|
||||
body: '<path d="icon2" />',
|
||||
width: 24,
|
||||
},
|
||||
icon3: {
|
||||
// Missing 'body'
|
||||
width: 24,
|
||||
},
|
||||
},
|
||||
height: 24,
|
||||
// Objects should be ignored. Not testing other types because validation is done only for objects
|
||||
rotate: {
|
||||
foo: 1,
|
||||
},
|
||||
hFlip: null,
|
||||
} as unknown) as IconifyJSON;
|
||||
|
||||
// Do stuff
|
||||
expect(
|
||||
parseIconSet(
|
||||
iconSet,
|
||||
(name, data) => {
|
||||
// Make sure name matches
|
||||
expect(names.length).to.be.at.least(1);
|
||||
expect(name).to.be.equal(names.shift());
|
||||
|
||||
// Check icon data
|
||||
expect(data).to.be.eql(expected[name]);
|
||||
},
|
||||
'all'
|
||||
)
|
||||
).to.be.eql(namesCopy);
|
||||
|
||||
// All names should have been parsed
|
||||
expect(names).to.be.eql([], 'Not all icons have been parsed');
|
||||
});
|
||||
});
|
@ -11,7 +11,6 @@ import {
|
||||
listIcons,
|
||||
} from '../../lib/storage';
|
||||
import { FullIconifyIcon, IconifyIcon } from '../../lib/icon';
|
||||
import { IconifyJSON } from '@iconify/types';
|
||||
|
||||
describe('Testing storage', () => {
|
||||
it('Adding icon', () => {
|
||||
@ -139,270 +138,6 @@ describe('Testing storage', () => {
|
||||
expect(getIcon(storage, 'missing')).to.be.equal(null);
|
||||
});
|
||||
|
||||
it('Icon set with invalid default values', () => {
|
||||
const storage = newStorage('', 'foo');
|
||||
|
||||
// Missing prefix, invalid default values
|
||||
expect(
|
||||
addIconSet(storage, ({
|
||||
icons: {
|
||||
icon1: {
|
||||
body: '<path d="icon1" />',
|
||||
width: 20,
|
||||
// Default should not override this
|
||||
height: 20,
|
||||
},
|
||||
icon2: {
|
||||
body: '<path d="icon2" />',
|
||||
width: 24,
|
||||
},
|
||||
icon3: {
|
||||
// Missing 'body'
|
||||
width: 24,
|
||||
},
|
||||
},
|
||||
height: 24,
|
||||
// Objects should be ignored. Not testing other types because validation is done only for objects
|
||||
rotate: {
|
||||
foo: 1,
|
||||
},
|
||||
hFlip: null,
|
||||
} as unknown) as IconifyJSON)
|
||||
// Should return false because of exception, but still add icon1 and icon2 before failing on icon3
|
||||
).to.be.equal(false);
|
||||
|
||||
expect(Object.keys(storage.icons)).to.be.eql(['icon1', 'icon2']);
|
||||
|
||||
// Test iconExists
|
||||
expect(iconExists(storage, 'icon1')).to.be.equal(true);
|
||||
expect(iconExists(storage, 'icon2')).to.be.equal(true);
|
||||
expect(iconExists(storage, 'invalid')).to.be.equal(false);
|
||||
expect(iconExists(storage, 'missing')).to.be.equal(false);
|
||||
|
||||
// Test getIcon
|
||||
let expected: FullIconifyIcon = {
|
||||
body: '<path d="icon1" />',
|
||||
width: 20,
|
||||
height: 20,
|
||||
top: 0,
|
||||
left: 0,
|
||||
hFlip: false,
|
||||
vFlip: false,
|
||||
rotate: 0,
|
||||
};
|
||||
expect(getIcon(storage, 'icon1')).to.be.eql(expected);
|
||||
expected = {
|
||||
body: '<path d="icon2" />',
|
||||
width: 24,
|
||||
height: 24,
|
||||
top: 0,
|
||||
left: 0,
|
||||
hFlip: false,
|
||||
vFlip: false,
|
||||
rotate: 0,
|
||||
};
|
||||
expect(getIcon(storage, 'icon2')).to.be.eql(expected);
|
||||
expect(getIcon(storage, 'invalid')).to.be.equal(null);
|
||||
expect(getIcon(storage, 'missing')).to.be.equal(null);
|
||||
});
|
||||
|
||||
it('Icon set with simple aliases', () => {
|
||||
const storage = newStorage('', 'foo');
|
||||
|
||||
expect(
|
||||
addIconSet(storage, {
|
||||
prefix: 'foo',
|
||||
icons: {
|
||||
icon1: {
|
||||
body: '<path d="icon1" />',
|
||||
width: 20,
|
||||
height: 20,
|
||||
},
|
||||
icon2: {
|
||||
body: '<path d="icon2" />',
|
||||
width: 24,
|
||||
rotate: 1,
|
||||
hFlip: true,
|
||||
},
|
||||
},
|
||||
aliases: {
|
||||
alias1: {
|
||||
parent: 'icon1',
|
||||
},
|
||||
alias2: {
|
||||
parent: 'icon2',
|
||||
rotate: 1,
|
||||
hFlip: true,
|
||||
vFlip: true,
|
||||
},
|
||||
alias3: {
|
||||
parent: 'icon3',
|
||||
},
|
||||
},
|
||||
height: 24,
|
||||
})
|
||||
).to.be.equal(true);
|
||||
|
||||
expect(Object.keys(storage.icons)).to.be.eql([
|
||||
'icon1',
|
||||
'icon2',
|
||||
'alias1',
|
||||
'alias2',
|
||||
]);
|
||||
|
||||
// Test getIcon
|
||||
let expected: FullIconifyIcon = {
|
||||
body: '<path d="icon1" />',
|
||||
width: 20,
|
||||
height: 20,
|
||||
top: 0,
|
||||
left: 0,
|
||||
hFlip: false,
|
||||
vFlip: false,
|
||||
rotate: 0,
|
||||
};
|
||||
expect(getIcon(storage, 'alias1')).to.be.eql(expected);
|
||||
expected = {
|
||||
body: '<path d="icon2" />',
|
||||
width: 24,
|
||||
height: 24,
|
||||
top: 0,
|
||||
left: 0,
|
||||
hFlip: false,
|
||||
vFlip: true,
|
||||
rotate: 2,
|
||||
};
|
||||
expect(getIcon(storage, 'alias2')).to.be.eql(expected);
|
||||
expect(getIcon(storage, 'alias3')).to.be.equal(null);
|
||||
});
|
||||
|
||||
it('Icon set with nested aliases', () => {
|
||||
const storage = newStorage('', 'foo');
|
||||
|
||||
expect(
|
||||
addIconSet(storage, {
|
||||
prefix: 'foo',
|
||||
icons: {
|
||||
icon1: {
|
||||
body: '<path d="icon1" />',
|
||||
width: 20,
|
||||
height: 20,
|
||||
},
|
||||
icon2: {
|
||||
body: '<path d="icon2" />',
|
||||
width: 24,
|
||||
rotate: 1,
|
||||
hFlip: true,
|
||||
},
|
||||
},
|
||||
aliases: {
|
||||
alias2a: {
|
||||
// Alias before parent
|
||||
parent: 'alias2f',
|
||||
width: 20,
|
||||
height: 20,
|
||||
},
|
||||
alias2f: {
|
||||
parent: 'icon2',
|
||||
width: 22,
|
||||
rotate: 1,
|
||||
hFlip: true,
|
||||
vFlip: true,
|
||||
},
|
||||
alias2z: {
|
||||
// Alias after parent
|
||||
parent: 'alias2f',
|
||||
width: 21,
|
||||
rotate: 3,
|
||||
},
|
||||
alias2z3: {
|
||||
// 3 parents: alias2z, alias2f, icon2
|
||||
parent: 'alias2z',
|
||||
},
|
||||
alias2z4: {
|
||||
// 4 parents: alias2z3, alias2z, alias2f, icon2
|
||||
parent: 'alias2z3',
|
||||
},
|
||||
},
|
||||
height: 24,
|
||||
})
|
||||
// Should have thrown exception on 'alias2z4'
|
||||
).to.be.equal(false);
|
||||
|
||||
expect(Object.keys(storage.icons)).to.be.eql([
|
||||
'icon1',
|
||||
'icon2',
|
||||
'alias2a',
|
||||
'alias2f',
|
||||
'alias2z',
|
||||
'alias2z3',
|
||||
]);
|
||||
|
||||
// Test icon
|
||||
let expected: FullIconifyIcon = {
|
||||
body: '<path d="icon2" />',
|
||||
width: 24,
|
||||
height: 24,
|
||||
top: 0,
|
||||
left: 0,
|
||||
hFlip: true,
|
||||
vFlip: false,
|
||||
rotate: 1,
|
||||
};
|
||||
expect(getIcon(storage, 'icon2')).to.be.eql(expected);
|
||||
|
||||
// Test simple alias
|
||||
expected = {
|
||||
body: '<path d="icon2" />',
|
||||
width: 22,
|
||||
height: 24,
|
||||
top: 0,
|
||||
left: 0,
|
||||
hFlip: false,
|
||||
vFlip: true,
|
||||
rotate: 2,
|
||||
};
|
||||
expect(getIcon(storage, 'alias2f')).to.be.eql(expected);
|
||||
|
||||
// Test nested aliases
|
||||
expected = {
|
||||
body: '<path d="icon2" />',
|
||||
width: 21,
|
||||
height: 24,
|
||||
top: 0,
|
||||
left: 0,
|
||||
hFlip: false,
|
||||
vFlip: true,
|
||||
rotate: 1, // 5
|
||||
};
|
||||
expect(getIcon(storage, 'alias2z')).to.be.eql(expected);
|
||||
|
||||
expected = {
|
||||
body: '<path d="icon2" />',
|
||||
width: 20,
|
||||
height: 20,
|
||||
top: 0,
|
||||
left: 0,
|
||||
hFlip: false,
|
||||
vFlip: true,
|
||||
rotate: 2,
|
||||
};
|
||||
expect(getIcon(storage, 'alias2a')).to.be.eql(expected);
|
||||
|
||||
// 3 levels
|
||||
expected = {
|
||||
body: '<path d="icon2" />',
|
||||
width: 21,
|
||||
height: 24,
|
||||
top: 0,
|
||||
left: 0,
|
||||
hFlip: false,
|
||||
vFlip: true,
|
||||
rotate: 1, // 5
|
||||
};
|
||||
expect(getIcon(storage, 'alias2z3')).to.be.eql(expected);
|
||||
});
|
||||
|
||||
it('Icon set with aliases that use transformations', () => {
|
||||
const storage = newStorage('iconify', 'arty-animated');
|
||||
const iconBody =
|
||||
|
Loading…
x
Reference in New Issue
Block a user