mirror of
https://github.com/iconify/iconify.git
synced 2025-02-13 00:58:30 +00:00
Refactor SVG framework: use ES modules, generate ES module, use Jest for testing
This commit is contained in:
parent
a77c89a545
commit
dfec3add9f
3
packages/iconify/.eslintignore
Normal file
3
packages/iconify/.eslintignore
Normal file
@ -0,0 +1,3 @@
|
||||
lib
|
||||
dist
|
||||
tests-compiled
|
@ -5,7 +5,8 @@
|
||||
"@iconify/types",
|
||||
"@iconify/core",
|
||||
"@iconify/utils",
|
||||
"@cyberalien/redundancy"
|
||||
"@cyberalien/redundancy",
|
||||
"@iconify/api-redundancy"
|
||||
],
|
||||
"compiler": {},
|
||||
"apiReport": {
|
||||
|
@ -5,7 +5,8 @@
|
||||
"@iconify/types",
|
||||
"@iconify/core",
|
||||
"@iconify/utils",
|
||||
"@cyberalien/redundancy"
|
||||
"@cyberalien/redundancy",
|
||||
"@iconify/api-redundancy"
|
||||
],
|
||||
"compiler": {},
|
||||
"apiReport": {
|
||||
|
@ -5,7 +5,8 @@
|
||||
"@iconify/types",
|
||||
"@iconify/core",
|
||||
"@iconify/utils",
|
||||
"@cyberalien/redundancy"
|
||||
"@cyberalien/redundancy",
|
||||
"@iconify/api-redundancy"
|
||||
],
|
||||
"compiler": {},
|
||||
"apiReport": {
|
||||
|
@ -1,3 +1,4 @@
|
||||
/* eslint-disable */
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const child_process = require('child_process');
|
||||
|
28
packages/iconify/package-lock.json
generated
28
packages/iconify/package-lock.json
generated
@ -23,6 +23,7 @@
|
||||
"@types/jest": "^27.0.2",
|
||||
"@types/node": "^10.17.13",
|
||||
"@typescript-eslint/eslint-plugin": "^4.31.2",
|
||||
"cross-env": "^7.0.3",
|
||||
"eslint": "^7.32.0",
|
||||
"jest": "^27.2.1",
|
||||
"rimraf": "^3.0.2",
|
||||
@ -2564,6 +2565,24 @@
|
||||
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/cross-env": {
|
||||
"version": "7.0.3",
|
||||
"resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz",
|
||||
"integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"cross-spawn": "^7.0.1"
|
||||
},
|
||||
"bin": {
|
||||
"cross-env": "src/bin/cross-env.js",
|
||||
"cross-env-shell": "src/bin/cross-env-shell.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10.14",
|
||||
"npm": ">=6",
|
||||
"yarn": ">=1"
|
||||
}
|
||||
},
|
||||
"node_modules/cross-fetch": {
|
||||
"version": "3.1.4",
|
||||
"resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.4.tgz",
|
||||
@ -9451,6 +9470,15 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"cross-env": {
|
||||
"version": "7.0.3",
|
||||
"resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz",
|
||||
"integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"cross-spawn": "^7.0.1"
|
||||
}
|
||||
},
|
||||
"cross-fetch": {
|
||||
"version": "3.1.4",
|
||||
"resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.4.tgz",
|
||||
|
@ -26,7 +26,9 @@
|
||||
"build:api": "api-extractor run --local --verbose",
|
||||
"build:api2": "api-extractor run --local --verbose --config api-extractor.without-api.json",
|
||||
"build:api2min": "api-extractor run --local --config api-extractor.without-api.min.json",
|
||||
"test": "jest --runInBand"
|
||||
"test:jest": "jest --runInBand",
|
||||
"test:mjs": "cross-env NODE_OPTIONS=--experimental-vm-modules node tests/import-test.mjs",
|
||||
"test": "npm run test:jest && npm run test:mjs"
|
||||
},
|
||||
"exports": {
|
||||
"./*": "./*",
|
||||
@ -34,9 +36,17 @@
|
||||
"require": "./dist/iconify.cjs",
|
||||
"import": "./dist/iconify.mjs"
|
||||
},
|
||||
"./dist/iconify": {
|
||||
"require": "./dist/iconify.cjs",
|
||||
"import": "./dist/iconify.mjs"
|
||||
},
|
||||
"./offline": {
|
||||
"require": "./dist/iconify.without-api.cjs",
|
||||
"import": "./dist/iconify.without-api.mjs"
|
||||
},
|
||||
"./dist/iconify.without-api": {
|
||||
"require": "./dist/iconify.without-api.cjs",
|
||||
"import": "./dist/iconify.without-api.mjs"
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
@ -54,6 +64,7 @@
|
||||
"@types/jest": "^27.0.2",
|
||||
"@types/node": "^10.17.13",
|
||||
"@typescript-eslint/eslint-plugin": "^4.31.2",
|
||||
"cross-env": "^7.0.3",
|
||||
"eslint": "^7.32.0",
|
||||
"jest": "^27.2.1",
|
||||
"rimraf": "^3.0.2",
|
||||
|
@ -22,32 +22,29 @@ const header = `/**
|
||||
* @version __iconify_version__
|
||||
*/`;
|
||||
|
||||
const footerJS = `
|
||||
const defaultFooter = `
|
||||
// Export to window or web worker
|
||||
try {
|
||||
if (self.Iconify === void 0) {
|
||||
self.Iconify = Iconify;
|
||||
}
|
||||
} catch (err) {
|
||||
}
|
||||
}`;
|
||||
|
||||
// Export as module
|
||||
const iifeFooter = `
|
||||
// Export as ES module
|
||||
if (typeof exports === 'object') {
|
||||
try {
|
||||
exports.__esModule = true;
|
||||
exports.default = Iconify;
|
||||
for (var key in Iconify) {
|
||||
exports[key] = Iconify[key];
|
||||
}
|
||||
} catch (err) {
|
||||
}
|
||||
}`;
|
||||
}
|
||||
|
||||
const footerMJS = `
|
||||
// Export to window or web worker
|
||||
try {
|
||||
if (self.Iconify === void 0) {
|
||||
self.Iconify = Iconify;
|
||||
}
|
||||
} catch (err) {
|
||||
}`;
|
||||
${defaultFooter}`;
|
||||
|
||||
// Get replacements
|
||||
const replacements = {
|
||||
@ -92,24 +89,30 @@ names.forEach((name) => {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get export format and footer
|
||||
let format = ext;
|
||||
let footer = defaultFooter;
|
||||
switch (ext) {
|
||||
case 'js':
|
||||
format = 'iife';
|
||||
footer = iifeFooter;
|
||||
break;
|
||||
|
||||
case 'mjs':
|
||||
format = 'es';
|
||||
break;
|
||||
}
|
||||
|
||||
const item = {
|
||||
input: `lib/${name}.js`,
|
||||
output: [
|
||||
{
|
||||
file: `dist/${name}${minify ? '.min' : ''}.${ext}`,
|
||||
format,
|
||||
exports: 'named',
|
||||
name: global,
|
||||
banner: header,
|
||||
footer: ext === 'js' ? footerJS : footerMJS,
|
||||
footer,
|
||||
},
|
||||
],
|
||||
plugins: [
|
||||
|
@ -6,50 +6,21 @@ import {
|
||||
mergeCustomisations,
|
||||
} from '@iconify/utils/lib/customisations';
|
||||
import {
|
||||
storageFunctions,
|
||||
getIconData,
|
||||
addCollection,
|
||||
} from '@iconify/core/lib/storage/functions';
|
||||
import type { IconifyIconBuildResult } from '@iconify/utils/lib/svg/build';
|
||||
import { iconToSVG } from '@iconify/utils/lib/svg/build';
|
||||
import { renderIcon } from './modules/render';
|
||||
import {
|
||||
initObserver,
|
||||
pauseObserver,
|
||||
resumeObserver,
|
||||
observeNode,
|
||||
removeObservedNode,
|
||||
} from './modules/observer';
|
||||
import { renderIconInPlaceholder } from './modules/render';
|
||||
import { initObserver } from './modules/observer';
|
||||
import { scanDOM, scanElement } from './modules/scanner';
|
||||
|
||||
// Finders
|
||||
import { addFinder } from './modules/finder';
|
||||
import { finder as iconifyFinder } from './finders/iconify';
|
||||
import { findRootNode, addBodyNode } from './modules/root';
|
||||
import { addBodyNode } from './modules/root';
|
||||
// import { finder as iconifyIconFinder } from './finders/iconify-icon';
|
||||
|
||||
/**
|
||||
* Get SVG data
|
||||
*/
|
||||
function buildIcon(
|
||||
name: string,
|
||||
customisations?: IconifyIconCustomisations
|
||||
): IconifyIconBuildResult | null {
|
||||
// Get icon data
|
||||
const iconData = getIconData(name);
|
||||
if (!iconData) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Clean up customisations
|
||||
const changes = mergeCustomisations(
|
||||
defaults,
|
||||
typeof customisations === 'object' ? customisations : {}
|
||||
);
|
||||
|
||||
// Get data
|
||||
return iconToSVG(iconData, changes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate icon
|
||||
*/
|
||||
@ -74,7 +45,7 @@ function generateIcon(
|
||||
);
|
||||
|
||||
// Get data
|
||||
return renderIcon(
|
||||
return renderIconInPlaceholder(
|
||||
{
|
||||
name: iconName,
|
||||
},
|
||||
@ -145,67 +116,65 @@ export interface IconifyCommonFunctions {
|
||||
}
|
||||
|
||||
/**
|
||||
* Global variable
|
||||
* Get version
|
||||
*/
|
||||
export const commonFunctions: IconifyCommonFunctions = {
|
||||
// Version
|
||||
getVersion: () => '__iconify_version__',
|
||||
export function getVersion(): string {
|
||||
return '__iconify_version__';
|
||||
}
|
||||
|
||||
// Render SVG
|
||||
renderSVG: (name: string, customisations?: IconifyIconCustomisations) => {
|
||||
return generateIcon(name, customisations, false) as SVGElement | null;
|
||||
},
|
||||
/**
|
||||
* Generate SVG element
|
||||
*/
|
||||
export function renderSVG(
|
||||
name: string,
|
||||
customisations?: IconifyIconCustomisations
|
||||
): SVGElement | null {
|
||||
return generateIcon(name, customisations, false) as SVGElement | null;
|
||||
}
|
||||
|
||||
renderHTML: (name: string, customisations?: IconifyIconCustomisations) => {
|
||||
return generateIcon(name, customisations, true) as string | null;
|
||||
},
|
||||
/**
|
||||
* Generate SVG as string
|
||||
*/
|
||||
export function renderHTML(
|
||||
name: string,
|
||||
customisations?: IconifyIconCustomisations
|
||||
): string | null {
|
||||
return generateIcon(name, customisations, true) as string | null;
|
||||
}
|
||||
|
||||
// Get rendered icon as object that can be used to create SVG (use replaceIDs on body)
|
||||
renderIcon: buildIcon,
|
||||
/**
|
||||
* Get rendered icon as object that can be used to create SVG (use replaceIDs on body)
|
||||
*/
|
||||
export function renderIcon(
|
||||
name: string,
|
||||
customisations?: IconifyIconCustomisations
|
||||
): IconifyIconBuildResult | null {
|
||||
// Get icon data
|
||||
const iconData = getIconData(name);
|
||||
if (!iconData) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Scan DOM
|
||||
scan: (root?: HTMLElement) => {
|
||||
if (root) {
|
||||
scanElement(root);
|
||||
} else {
|
||||
scanDOM();
|
||||
}
|
||||
},
|
||||
// Clean up customisations
|
||||
const changes = mergeCustomisations(
|
||||
defaults,
|
||||
typeof customisations === 'object' ? customisations : {}
|
||||
);
|
||||
|
||||
// Add root node
|
||||
observe: (root: HTMLElement) => {
|
||||
observeNode(root);
|
||||
},
|
||||
// Get data
|
||||
return iconToSVG(iconData, changes);
|
||||
}
|
||||
|
||||
// Remove root node
|
||||
stopObserving: (root: HTMLElement) => {
|
||||
removeObservedNode(root);
|
||||
},
|
||||
|
||||
// Pause observer
|
||||
pauseObserver: (root?: HTMLElement) => {
|
||||
if (root) {
|
||||
const node = findRootNode(root);
|
||||
if (node) {
|
||||
pauseObserver(node);
|
||||
}
|
||||
} else {
|
||||
pauseObserver();
|
||||
}
|
||||
},
|
||||
|
||||
// Resume observer
|
||||
resumeObserver: (root?: HTMLElement) => {
|
||||
if (root) {
|
||||
const node = findRootNode(root);
|
||||
if (node) {
|
||||
resumeObserver(node);
|
||||
}
|
||||
} else {
|
||||
resumeObserver();
|
||||
}
|
||||
},
|
||||
};
|
||||
/**
|
||||
* Scan DOM
|
||||
*/
|
||||
export function scan(root?: HTMLElement): void {
|
||||
if (root) {
|
||||
scanElement(root);
|
||||
} else {
|
||||
scanDOM();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialise stuff
|
||||
@ -239,7 +208,7 @@ if (typeof document !== 'undefined' && typeof window !== 'undefined') {
|
||||
typeof item.icons !== 'object' ||
|
||||
typeof item.prefix !== 'string' ||
|
||||
// Add icon set
|
||||
!storageFunctions.addCollection(item)
|
||||
!addCollection(item)
|
||||
) {
|
||||
console.error(err);
|
||||
}
|
||||
|
@ -9,9 +9,17 @@ import type {
|
||||
} from '@iconify/utils/lib/customisations';
|
||||
import type { IconifyIconBuildResult } from '@iconify/utils/lib/svg/build';
|
||||
import type { IconifyStorageFunctions } from '@iconify/core/lib/storage/functions';
|
||||
import { storageFunctions } from '@iconify/core/lib/storage/functions';
|
||||
import {
|
||||
iconExists,
|
||||
getIcon,
|
||||
addIcon,
|
||||
addCollection,
|
||||
} from '@iconify/core/lib/storage/functions';
|
||||
import { listIcons } from '@iconify/core/lib/storage/storage';
|
||||
import type { IconifyBuilderFunctions } from '@iconify/core/lib/builder/functions';
|
||||
import { builderFunctions } from '@iconify/core/lib/builder/functions';
|
||||
import { buildIcon } from '@iconify/core/lib/builder/functions';
|
||||
import { replaceIDs } from '@iconify/utils/lib/svg/id';
|
||||
import { calculateSize } from '@iconify/utils/lib/svg/size';
|
||||
|
||||
// Cache
|
||||
import { storeCache, loadCache } from '@iconify/core/lib/browser-storage/';
|
||||
@ -30,10 +38,6 @@ import type {
|
||||
IconifyAPICustomQueryParams,
|
||||
IconifyAPIMergeQueryParams,
|
||||
} from '@iconify/core/lib/api/functions';
|
||||
import {
|
||||
APIFunctions,
|
||||
APIInternalFunctions,
|
||||
} from '@iconify/core/lib/api/functions';
|
||||
import type {
|
||||
IconifyAPIModule,
|
||||
IconifyAPISendQuery,
|
||||
@ -45,21 +49,34 @@ import type {
|
||||
IconifyAPIConfig,
|
||||
GetAPIConfig,
|
||||
} from '@iconify/core/lib/api/config';
|
||||
import { setAPIConfig } from '@iconify/core/lib/api/config';
|
||||
import {
|
||||
addAPIProvider,
|
||||
getAPIConfig,
|
||||
listAPIProviders,
|
||||
} from '@iconify/core/lib/api/config';
|
||||
import { jsonpAPIModule } from '@iconify/core/lib/api/modules/jsonp';
|
||||
import {
|
||||
fetchAPIModule,
|
||||
getFetch,
|
||||
setFetch,
|
||||
setFetch as setFetchFunction,
|
||||
} from '@iconify/core/lib/api/modules/fetch';
|
||||
import type {
|
||||
IconifyIconLoaderCallback,
|
||||
IconifyIconLoaderAbort,
|
||||
} from '@iconify/core/lib/api/icons';
|
||||
import { loadIcons } from '@iconify/core/lib/api/icons';
|
||||
import { sendAPIQuery } from '@iconify/core/lib/api/query';
|
||||
import { mergeParams } from '@iconify/core/lib/api/params';
|
||||
|
||||
// Other
|
||||
import type { IconifyCommonFunctions } from './common';
|
||||
import { commonFunctions } from './common';
|
||||
import { getVersion, renderSVG, renderHTML, renderIcon, scan } from './common';
|
||||
import {
|
||||
observe,
|
||||
stopObserving,
|
||||
pauseObserver,
|
||||
resumeObserver,
|
||||
} from './modules/observer';
|
||||
|
||||
/**
|
||||
* Export required types
|
||||
@ -118,36 +135,18 @@ export interface IconifyGlobal
|
||||
}
|
||||
|
||||
/**
|
||||
* Browser cache functions
|
||||
* Enable cache
|
||||
*/
|
||||
const browserCacheFunctions: IconifyBrowserCacheFunctions = {
|
||||
// enableCache() has optional second parameter for backwards compatibility
|
||||
enableCache: (storage: IconifyBrowserCacheType, enable?: boolean) =>
|
||||
toggleBrowserCache(storage, enable !== false),
|
||||
disableCache: (storage: IconifyBrowserCacheType) =>
|
||||
toggleBrowserCache(storage, true),
|
||||
};
|
||||
function enableCache(storage: IconifyBrowserCacheType, enable?: boolean): void {
|
||||
toggleBrowserCache(storage, enable !== false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Global variable
|
||||
* Disable cache
|
||||
*/
|
||||
const Iconify = {
|
||||
// Exposed internal API functions
|
||||
_api: APIInternalFunctions,
|
||||
} as unknown as IconifyGlobal;
|
||||
|
||||
// Add functions
|
||||
[
|
||||
storageFunctions,
|
||||
builderFunctions,
|
||||
commonFunctions,
|
||||
browserCacheFunctions,
|
||||
APIFunctions,
|
||||
].forEach((list) => {
|
||||
for (const key in list) {
|
||||
Iconify[key] = list[key];
|
||||
}
|
||||
});
|
||||
function disableCache(storage: IconifyBrowserCacheType): void {
|
||||
toggleBrowserCache(storage, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialise stuff
|
||||
@ -158,10 +157,10 @@ setAPIModule('', getFetch() ? fetchAPIModule : jsonpAPIModule);
|
||||
/**
|
||||
* Function to enable node-fetch for getting icons on server side
|
||||
*/
|
||||
Iconify._api.setFetch = (nodeFetch: typeof fetch) => {
|
||||
setFetch(nodeFetch);
|
||||
function setFetch(nodeFetch: typeof fetch): void {
|
||||
setFetchFunction(nodeFetch);
|
||||
setAPIModule('', fetchAPIModule);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Browser stuff
|
||||
@ -191,7 +190,7 @@ if (typeof document !== 'undefined' && typeof window !== 'undefined') {
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
if (!setAPIConfig(key, value)) {
|
||||
if (!addAPIProvider(key, value)) {
|
||||
console.error(err);
|
||||
}
|
||||
} catch (e) {
|
||||
@ -202,4 +201,89 @@ if (typeof document !== 'undefined' && typeof window !== 'undefined') {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal API
|
||||
*/
|
||||
const _api: IconifyAPIInternalFunctions = {
|
||||
getAPIConfig,
|
||||
setAPIModule,
|
||||
sendAPIQuery,
|
||||
setFetch,
|
||||
listAPIProviders,
|
||||
mergeParams,
|
||||
};
|
||||
|
||||
/**
|
||||
* Global variable
|
||||
*/
|
||||
const Iconify: IconifyGlobal = {
|
||||
// IconifyAPIInternalFunctions
|
||||
_api,
|
||||
|
||||
// IconifyAPIFunctions
|
||||
addAPIProvider,
|
||||
loadIcons,
|
||||
|
||||
// IconifyStorageFunctions
|
||||
iconExists,
|
||||
getIcon,
|
||||
listIcons,
|
||||
addIcon,
|
||||
addCollection,
|
||||
|
||||
// IconifyBuilderFunctions
|
||||
replaceIDs,
|
||||
calculateSize,
|
||||
buildIcon,
|
||||
|
||||
// IconifyCommonFunctions
|
||||
getVersion,
|
||||
renderSVG,
|
||||
renderHTML,
|
||||
renderIcon,
|
||||
scan,
|
||||
observe,
|
||||
stopObserving,
|
||||
pauseObserver,
|
||||
resumeObserver,
|
||||
|
||||
// IconifyBrowserCacheFunctions
|
||||
enableCache,
|
||||
disableCache,
|
||||
};
|
||||
|
||||
/**
|
||||
* Default export
|
||||
*/
|
||||
export default Iconify;
|
||||
|
||||
/**
|
||||
* Named exports
|
||||
*/
|
||||
// IconifyAPIInternalFunctions
|
||||
export { _api };
|
||||
|
||||
// IconifyAPIFunctions
|
||||
export { addAPIProvider, loadIcons };
|
||||
|
||||
// IconifyStorageFunctions
|
||||
export { iconExists, getIcon, listIcons, addIcon, addCollection };
|
||||
|
||||
// IconifyBuilderFunctions
|
||||
export { replaceIDs, calculateSize, buildIcon };
|
||||
|
||||
// IconifyCommonFunctions
|
||||
export {
|
||||
getVersion,
|
||||
renderSVG,
|
||||
renderHTML,
|
||||
renderIcon,
|
||||
scan,
|
||||
observe,
|
||||
stopObserving,
|
||||
pauseObserver,
|
||||
resumeObserver,
|
||||
};
|
||||
|
||||
// IconifyBrowserCacheFunctions
|
||||
export { enableCache, disableCache };
|
||||
|
@ -9,13 +9,27 @@ import type {
|
||||
} from '@iconify/utils/lib/customisations';
|
||||
import type { IconifyIconBuildResult } from '@iconify/utils/lib/svg/build';
|
||||
import type { IconifyStorageFunctions } from '@iconify/core/lib/storage/functions';
|
||||
import { storageFunctions } from '@iconify/core/lib/storage/functions';
|
||||
import {
|
||||
iconExists,
|
||||
getIcon,
|
||||
addIcon,
|
||||
addCollection,
|
||||
} from '@iconify/core/lib/storage/functions';
|
||||
import { listIcons } from '@iconify/core/lib/storage/storage';
|
||||
import type { IconifyBuilderFunctions } from '@iconify/core/lib/builder/functions';
|
||||
import { builderFunctions } from '@iconify/core/lib/builder/functions';
|
||||
import { buildIcon } from '@iconify/core/lib/builder/functions';
|
||||
import { replaceIDs } from '@iconify/utils/lib/svg/id';
|
||||
import { calculateSize } from '@iconify/utils/lib/svg/size';
|
||||
|
||||
// Local code
|
||||
import type { IconifyCommonFunctions } from './common';
|
||||
import { commonFunctions } from './common';
|
||||
import { getVersion, renderSVG, renderHTML, renderIcon, scan } from './common';
|
||||
import {
|
||||
observe,
|
||||
stopObserving,
|
||||
pauseObserver,
|
||||
resumeObserver,
|
||||
} from './modules/observer';
|
||||
|
||||
/**
|
||||
* Export required types
|
||||
@ -45,19 +59,57 @@ export interface IconifyGlobal
|
||||
IconifyBuilderFunctions,
|
||||
IconifyCommonFunctions {}
|
||||
|
||||
// Export dependencies
|
||||
export { IconifyGlobal as IconifyGlobalCommon };
|
||||
|
||||
/**
|
||||
* Global variable
|
||||
*/
|
||||
const Iconify: IconifyGlobal = {} as IconifyGlobal;
|
||||
const Iconify: IconifyGlobal = {
|
||||
// IconifyStorageFunctions
|
||||
iconExists,
|
||||
getIcon,
|
||||
listIcons,
|
||||
addIcon,
|
||||
addCollection,
|
||||
|
||||
// Merge with common functions
|
||||
[storageFunctions, builderFunctions, commonFunctions].forEach((list) => {
|
||||
for (const key in list) {
|
||||
Iconify[key] = list[key];
|
||||
}
|
||||
});
|
||||
// IconifyBuilderFunctions
|
||||
replaceIDs,
|
||||
calculateSize,
|
||||
buildIcon,
|
||||
|
||||
// IconifyCommonFunctions
|
||||
getVersion,
|
||||
renderSVG,
|
||||
renderHTML,
|
||||
renderIcon,
|
||||
scan,
|
||||
observe,
|
||||
stopObserving,
|
||||
pauseObserver,
|
||||
resumeObserver,
|
||||
};
|
||||
|
||||
/**
|
||||
* Default export
|
||||
*/
|
||||
export default Iconify;
|
||||
|
||||
/**
|
||||
* Named exports
|
||||
*/
|
||||
// IconifyStorageFunctions
|
||||
export { iconExists, getIcon, listIcons, addIcon, addCollection };
|
||||
|
||||
// IconifyBuilderFunctions
|
||||
export { replaceIDs, calculateSize, buildIcon };
|
||||
|
||||
// IconifyCommonFunctions
|
||||
export {
|
||||
getVersion,
|
||||
renderSVG,
|
||||
renderHTML,
|
||||
renderIcon,
|
||||
scan,
|
||||
observe,
|
||||
stopObserving,
|
||||
pauseObserver,
|
||||
resumeObserver,
|
||||
};
|
||||
|
@ -79,7 +79,7 @@ function checkMutations(node: ObservedNode, mutations: MutationRecord[]): void {
|
||||
/**
|
||||
* Start/resume observer
|
||||
*/
|
||||
function observe(node: ObservedNode, root: HTMLElement): void {
|
||||
function continueObserving(node: ObservedNode, root: HTMLElement): void {
|
||||
node.observer.instance.observe(root, observerParams);
|
||||
}
|
||||
|
||||
@ -108,7 +108,7 @@ function startObserver(node: ObservedNode): void {
|
||||
|
||||
// Create new instance, observe
|
||||
observer.instance = new MutationObserver(checkMutations.bind(null, node));
|
||||
observe(node, root);
|
||||
continueObserving(node, root);
|
||||
|
||||
// Scan immediately
|
||||
if (!observer.paused) {
|
||||
@ -171,9 +171,9 @@ export function initObserver(cb: ObserverCallback): void {
|
||||
}
|
||||
|
||||
/**
|
||||
* Pause observer
|
||||
* Pause observing node
|
||||
*/
|
||||
export function pauseObserver(node?: ObservedNode): void {
|
||||
export function pauseObservingNode(node?: ObservedNode): void {
|
||||
(node ? [node] : listRootNodes()).forEach((node) => {
|
||||
if (!node.observer) {
|
||||
node.observer = {
|
||||
@ -195,10 +195,24 @@ export function pauseObserver(node?: ObservedNode): void {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Pause observer
|
||||
*/
|
||||
export function pauseObserver(root?: HTMLElement): void {
|
||||
if (root) {
|
||||
const node = findRootNode(root);
|
||||
if (node) {
|
||||
pauseObservingNode(node);
|
||||
}
|
||||
} else {
|
||||
pauseObservingNode();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resume observer
|
||||
*/
|
||||
export function resumeObserver(observer?: ObservedNode): void {
|
||||
export function resumeObservingNode(observer?: ObservedNode): void {
|
||||
(observer ? [observer] : listRootNodes()).forEach((node) => {
|
||||
if (!node.observer) {
|
||||
// Start observer
|
||||
@ -218,7 +232,7 @@ export function resumeObserver(observer?: ObservedNode): void {
|
||||
if (!root) {
|
||||
return;
|
||||
} else if (observer.instance) {
|
||||
observe(node, root);
|
||||
continueObserving(node, root);
|
||||
} else {
|
||||
startObserver(node);
|
||||
}
|
||||
@ -227,13 +241,24 @@ export function resumeObserver(observer?: ObservedNode): void {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Resume observer
|
||||
*/
|
||||
export function resumeObserver(root?: HTMLElement): void {
|
||||
if (root) {
|
||||
const node = findRootNode(root);
|
||||
if (node) {
|
||||
resumeObservingNode(node);
|
||||
}
|
||||
} else {
|
||||
resumeObservingNode();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Observe node
|
||||
*/
|
||||
export function observeNode(
|
||||
root: HTMLElement,
|
||||
autoRemove = false
|
||||
): ObservedNode {
|
||||
export function observe(root: HTMLElement, autoRemove = false): ObservedNode {
|
||||
const node = addRootNode(root, autoRemove);
|
||||
startObserver(node);
|
||||
return node;
|
||||
@ -242,7 +267,7 @@ export function observeNode(
|
||||
/**
|
||||
* Remove observed node
|
||||
*/
|
||||
export function removeObservedNode(root: HTMLElement): void {
|
||||
export function stopObserving(root: HTMLElement): void {
|
||||
const node = findRootNode(root);
|
||||
if (node) {
|
||||
stopObserver(node);
|
||||
|
@ -13,7 +13,7 @@ import { elementDataProperty, elementFinderProperty } from './element';
|
||||
/**
|
||||
* Replace element with SVG
|
||||
*/
|
||||
export function renderIcon(
|
||||
export function renderIconInPlaceholder(
|
||||
placeholder: PlaceholderElement,
|
||||
customisations: IconifyIconCustomisations,
|
||||
iconData: FullIconifyIcon,
|
||||
|
@ -1,17 +1,20 @@
|
||||
import type { IconifyIconName } from '@iconify/utils/lib/icon/name';
|
||||
import { getStorage, getIcon } from '@iconify/core/lib/storage/storage';
|
||||
import {
|
||||
getStorage,
|
||||
getIconFromStorage,
|
||||
} from '@iconify/core/lib/storage/storage';
|
||||
import { isPending, loadIcons } from '@iconify/core/lib/api/icons';
|
||||
import type { FullIconifyIcon } from '@iconify/utils/lib/icon';
|
||||
import { findPlaceholders } from './finder';
|
||||
import type { IconifyElementData } from './element';
|
||||
import { elementDataProperty } from './element';
|
||||
import { renderIcon } from './render';
|
||||
import { renderIconInPlaceholder } from './render';
|
||||
import type { ObservedNode } from './observed-node';
|
||||
import {
|
||||
pauseObserver,
|
||||
resumeObserver,
|
||||
removeObservedNode,
|
||||
observeNode,
|
||||
pauseObservingNode,
|
||||
resumeObservingNode,
|
||||
stopObserving,
|
||||
observe,
|
||||
} from './observer';
|
||||
import { findRootNode, listRootNodes } from './root';
|
||||
|
||||
@ -133,7 +136,7 @@ export function scanDOM(node?: ObservedNode, addTempNode = false): void {
|
||||
if (storage.icons[name] !== void 0) {
|
||||
// Icon exists - pause observer before replacing placeholder
|
||||
if (!paused && node.observer) {
|
||||
pauseObserver(node);
|
||||
pauseObservingNode(node);
|
||||
paused = true;
|
||||
}
|
||||
|
||||
@ -144,10 +147,10 @@ export function scanDOM(node?: ObservedNode, addTempNode = false): void {
|
||||
: item.finder.customisations(element);
|
||||
|
||||
// Render icon
|
||||
renderIcon(
|
||||
renderIconInPlaceholder(
|
||||
item,
|
||||
customisations,
|
||||
getIcon(storage, name) as FullIconifyIcon
|
||||
getIconFromStorage(storage, name) as FullIconifyIcon
|
||||
);
|
||||
|
||||
return;
|
||||
@ -189,13 +192,13 @@ export function scanDOM(node?: ObservedNode, addTempNode = false): void {
|
||||
// Node stuff
|
||||
if (node.temporary && !hasPlaceholders) {
|
||||
// Remove temporary node
|
||||
removeObservedNode(root);
|
||||
stopObserving(root);
|
||||
} else if (addTempNode && hasPlaceholders) {
|
||||
// Add new temporary node
|
||||
observeNode(root, true);
|
||||
observe(root, true);
|
||||
} else if (paused && node.observer) {
|
||||
// Resume observer
|
||||
resumeObserver(node);
|
||||
resumeObservingNode(node);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
import Iconify from '../dist/iconify';
|
||||
import Iconify from '../';
|
||||
|
||||
describe('Testing Iconify API functions with Node.js', () => {
|
||||
it('Cache functions', () => {
|
||||
|
60
packages/iconify/tests/import-test.mjs
Normal file
60
packages/iconify/tests/import-test.mjs
Normal file
@ -0,0 +1,60 @@
|
||||
// Main file: default and named imports
|
||||
import Iconify from '@iconify/iconify';
|
||||
import { addIcon } from '@iconify/iconify';
|
||||
|
||||
// Named import from .mjs
|
||||
import { loadIcons } from '../dist/iconify.mjs';
|
||||
|
||||
// Shortcut for offline module
|
||||
import IconifyOffline from '@iconify/iconify/offline';
|
||||
import { iconExists } from '@iconify/iconify/offline';
|
||||
|
||||
// Direct link to offline module
|
||||
import { addCollection } from '../dist/iconify.without-api.mjs';
|
||||
|
||||
/**
|
||||
* Simple assertion function
|
||||
*/
|
||||
function test(value, expected, message) {
|
||||
if (value !== expected) {
|
||||
console.error(
|
||||
'❌',
|
||||
message + `: expected ${value} to equal ${expected}`
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
console.log('✓', message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test default export
|
||||
*/
|
||||
test(typeof Iconify, 'object', 'Testing default export');
|
||||
test(typeof Iconify.addIcon, 'function', 'Testing addIcon in default export');
|
||||
|
||||
/**
|
||||
* Test default export in offline module
|
||||
*/
|
||||
test(typeof IconifyOffline, 'object', 'Testing default offline export');
|
||||
test(
|
||||
typeof IconifyOffline.iconExists,
|
||||
'function',
|
||||
'Testing iconExists in default offline export'
|
||||
);
|
||||
test(
|
||||
typeof IconifyOffline.loadIcons,
|
||||
'undefined',
|
||||
'Testing loadIcons in default offline export'
|
||||
);
|
||||
|
||||
/**
|
||||
* Test named exports
|
||||
*/
|
||||
test(typeof addIcon, 'function', 'Testing addIcon named export');
|
||||
test(typeof loadIcons, 'function', 'Testing loadIcons named export');
|
||||
|
||||
/**
|
||||
* Test exports without API
|
||||
*/
|
||||
test(typeof iconExists, 'function', 'Testing iconExists named export');
|
||||
test(typeof addCollection, 'function', 'Testing addCollection named export');
|
@ -1,4 +1,4 @@
|
||||
import Iconify, { IconifyIconName } from '../dist/iconify';
|
||||
import Iconify, { IconifyIconName } from '../';
|
||||
import { mockAPIModule, mockAPIData } from '@iconify/core/lib/api/modules/mock';
|
||||
|
||||
// API provider and prefix for test
|
||||
|
@ -1,4 +1,4 @@
|
||||
import Iconify from '../dist/iconify';
|
||||
import Iconify from '../';
|
||||
|
||||
describe('Testing Iconify observer functions with Node.js', () => {
|
||||
it('Observer functions', () => {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import Iconify, { IconifyIconBuildResult } from '../dist/iconify';
|
||||
import Iconify, { IconifyIconBuildResult } from '../';
|
||||
|
||||
describe('Testing Iconify render functions with Node.js', () => {
|
||||
const prefix = 'node-test-render';
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { readFileSync } from 'fs';
|
||||
import { dirname } from 'path';
|
||||
import Iconify, { IconifyIcon } from '../dist/iconify';
|
||||
import Iconify, { IconifyIcon } from '../';
|
||||
|
||||
describe('Testing Iconify with Node.js', () => {
|
||||
it('Basic functions', () => {
|
||||
|
Loading…
x
Reference in New Issue
Block a user