diff --git a/packages/browser-tests/tests/20-renderer-v1-test.ts b/packages/browser-tests/tests/20-renderer-v1-test.ts index cd0e200..651034f 100644 --- a/packages/browser-tests/tests/20-renderer-v1-test.ts +++ b/packages/browser-tests/tests/20-renderer-v1-test.ts @@ -8,6 +8,7 @@ import { finder as iconifyIconFinder } from '@iconify/iconify/lib/finders/iconif import { getStorage, addIconSet, getIcon } from '@iconify/core/lib/storage'; import { renderIcon } from '@iconify/iconify/lib/render'; import { stringToIcon } from '@iconify/core/lib/icon/name'; +import { IconifyElement } from '@iconify/iconify/lib/element'; const expect = chai.expect; @@ -97,7 +98,11 @@ describe('Testing legacy renderer', () => { expect(iconData).to.not.be.equal(null); // Render icon - let svg = renderIcon(element, customisations, iconData); + let svg = renderIcon( + element, + customisations, + iconData + ) as IconifyElement; // Test SVG expect(svg.tagName.toUpperCase()).to.be.equal('SVG'); @@ -137,7 +142,7 @@ describe('Testing legacy renderer', () => { expect(iconData).to.not.be.equal(null); // Render icon - svg = renderIcon(element, customisations, iconData); + svg = renderIcon(element, customisations, iconData) as IconifyElement; // Test SVG expect(svg.tagName.toUpperCase()).to.be.equal('SVG'); @@ -180,7 +185,7 @@ describe('Testing legacy renderer', () => { expect(iconData).to.not.be.equal(null); // Render icon - svg = renderIcon(element, customisations, iconData); + svg = renderIcon(element, customisations, iconData) as IconifyElement; // Test SVG expect(svg.tagName.toUpperCase()).to.be.equal('SVG'); @@ -225,7 +230,7 @@ describe('Testing legacy renderer', () => { expect(iconData).to.not.be.equal(null); // Render icon - svg = renderIcon(element, customisations, iconData); + svg = renderIcon(element, customisations, iconData) as IconifyElement; // Test SVG expect(svg.tagName.toUpperCase()).to.be.equal('SVG'); @@ -266,7 +271,7 @@ describe('Testing legacy renderer', () => { expect(iconData).to.not.be.equal(null); // Render icon - svg = renderIcon(element, customisations, iconData); + svg = renderIcon(element, customisations, iconData) as IconifyElement; // Test SVG expect(svg.tagName.toUpperCase()).to.be.equal('SVG'); @@ -314,7 +319,7 @@ describe('Testing legacy renderer', () => { expect(iconData).to.not.be.equal(null); // Render icon - svg = renderIcon(element, customisations, iconData); + svg = renderIcon(element, customisations, iconData) as IconifyElement; // Test SVG expect(svg.tagName.toUpperCase()).to.be.equal('SVG'); @@ -384,7 +389,11 @@ describe('Testing legacy renderer', () => { expect(iconData).to.not.be.equal(null); // Render icon - let svg = renderIcon(element, customisations, iconData); + let svg = renderIcon( + element, + customisations, + iconData + ) as IconifyElement; // Test SVG expect(svg.tagName.toUpperCase()).to.be.equal('SVG'); @@ -433,7 +442,7 @@ describe('Testing legacy renderer', () => { iconData = getIcon(storage, element.name.name); expect(iconData).to.not.be.equal(null); - svg = renderIcon(element, customisations, iconData); + svg = renderIcon(element, customisations, iconData) as IconifyElement; expect(svg).to.not.be.eql(lastSVG); // Test attributes, compare them with last SVG @@ -498,7 +507,7 @@ describe('Testing legacy renderer', () => { iconData = getIcon(storage, element.name.name); expect(iconData).to.not.be.equal(null); - svg = renderIcon(element, customisations, iconData); + svg = renderIcon(element, customisations, iconData) as IconifyElement; expect(svg).to.not.be.eql(lastSVG); // Test changed attributes @@ -544,7 +553,7 @@ describe('Testing legacy renderer', () => { iconData = getIcon(storage, element.name.name); expect(iconData).to.not.be.equal(null); - svg = renderIcon(element, customisations, iconData); + svg = renderIcon(element, customisations, iconData) as IconifyElement; expect(svg).to.not.be.eql(lastSVG); // Test changed attributes @@ -590,7 +599,11 @@ describe('Testing legacy renderer', () => { expect(iconData).to.not.be.equal(null); // Render icon - let svg = renderIcon(element, customisations, iconData); + let svg = renderIcon( + element, + customisations, + iconData + ) as IconifyElement; /** * Change icon name to invalid @@ -634,7 +647,11 @@ describe('Testing legacy renderer', () => { expect(iconData).to.not.be.equal(null); // Render icon - let svg = renderIcon(element, customisations, iconData); + let svg = renderIcon( + element, + customisations, + iconData + ) as IconifyElement; /** * Change icon name to invalid @@ -680,7 +697,11 @@ describe('Testing legacy renderer', () => { ); // Render icon - let svg = renderIcon(element, customisations, iconData); + let svg = renderIcon( + element, + customisations, + iconData + ) as IconifyElement; // Copy variables for next test let lastElement = element; @@ -719,7 +740,7 @@ describe('Testing legacy renderer', () => { 'Wrong icon body: ' + iconData.body ); - svg = renderIcon(element, customisations, iconData); + svg = renderIcon(element, customisations, iconData) as IconifyElement; expect(svg).to.not.be.eql(lastSVG); // Test finder @@ -759,15 +780,23 @@ describe('Testing legacy renderer', () => { expect(iconData).to.not.be.equal(null); // Render icon - let svg = renderIcon(element, customisations, iconData); - if (svg.innerHTML) { - const html = svg.innerHTML; - // Test icon body to make sure icon has no transformation - expect(html.indexOf('transform="')).to.be.equal( - -1, - 'Found transform in icon: ' + html - ); - } + let svg = renderIcon( + element, + customisations, + iconData + ) as IconifyElement; + let html = renderIcon( + element, + customisations, + iconData, + true + ) as string; + + // Test icon body to make sure icon has no transformation + expect(html.indexOf('transform="')).to.be.equal( + -1, + 'Found transform in icon: ' + html + ); // Copy variables for next test let lastElement = element; @@ -800,16 +829,16 @@ describe('Testing legacy renderer', () => { iconData = getIcon(storage, element.name.name); expect(iconData).to.not.be.equal(null); - svg = renderIcon(element, customisations, iconData); + svg = renderIcon(element, customisations, iconData) as IconifyElement; expect(svg).to.not.be.eql(lastSVG); - if (svg.innerHTML) { - const html = svg.innerHTML; - // Test icon body to make sure icon was changed - expect(html.indexOf('transform="')).to.not.be.equal( - -1, - 'Missing transform in icon: ' + html - ); - } + + html = renderIcon(element, customisations, iconData, true) as string; + + // Test icon body to make sure icon was changed + expect(html.indexOf('transform="')).to.not.be.equal( + -1, + 'Missing transform in icon: ' + html + ); // Test finder expect(element.finder.name(svg)).to.be.equal('mdi:home'); @@ -848,7 +877,11 @@ describe('Testing legacy renderer', () => { expect(iconData).to.not.be.equal(null); // Render icon - let svg = renderIcon(element, customisations, iconData); + let svg = renderIcon( + element, + customisations, + iconData + ) as IconifyElement; // Check dimensions expect(svg.getAttribute('width')).to.be.equal('1em'); @@ -885,7 +918,7 @@ describe('Testing legacy renderer', () => { iconData = getIcon(storage, element.name.name); expect(iconData).to.not.be.equal(null); - svg = renderIcon(element, customisations, iconData); + svg = renderIcon(element, customisations, iconData) as IconifyElement; expect(svg).to.not.be.eql(lastSVG); // Check dimensions @@ -931,7 +964,11 @@ describe('Testing legacy renderer', () => { expect(iconData).to.not.be.equal(null); // Render icon - let svg = renderIcon(element, customisations, iconData); + let svg = renderIcon( + element, + customisations, + iconData + ) as IconifyElement; // Check dimensions and alignment expect(svg.getAttribute('width')).to.be.equal('48'); @@ -974,7 +1011,7 @@ describe('Testing legacy renderer', () => { iconData = getIcon(storage, element.name.name); expect(iconData).to.not.be.equal(null); - svg = renderIcon(element, customisations, iconData); + svg = renderIcon(element, customisations, iconData) as IconifyElement; expect(svg).to.not.be.eql(lastSVG); // Check dimensions and alignment diff --git a/packages/browser-tests/tests/20-renderer-v2-test.ts b/packages/browser-tests/tests/20-renderer-v2-test.ts index f1342cd..f88c3a1 100644 --- a/packages/browser-tests/tests/20-renderer-v2-test.ts +++ b/packages/browser-tests/tests/20-renderer-v2-test.ts @@ -8,6 +8,7 @@ import { finder as iconifyIconFinder } from '@iconify/iconify/lib/finders/iconif import { getStorage, addIconSet, getIcon } from '@iconify/core/lib/storage'; import { renderIcon } from '@iconify/iconify/lib/render'; import { stringToIcon } from '@iconify/core/lib/icon/name'; +import { IconifyElement } from '@iconify/iconify/lib/element'; const expect = chai.expect; @@ -97,7 +98,11 @@ describe('Testing renderer', () => { expect(iconData).to.not.be.equal(null); // Render icon - let svg = renderIcon(element, customisations, iconData); + let svg = renderIcon( + element, + customisations, + iconData + ) as IconifyElement; // Test SVG expect(svg.tagName.toUpperCase()).to.be.equal('SVG'); @@ -137,7 +142,7 @@ describe('Testing renderer', () => { expect(iconData).to.not.be.equal(null); // Render icon - svg = renderIcon(element, customisations, iconData); + svg = renderIcon(element, customisations, iconData) as IconifyElement; // Test SVG expect(svg.tagName.toUpperCase()).to.be.equal('SVG'); @@ -180,7 +185,7 @@ describe('Testing renderer', () => { expect(iconData).to.not.be.equal(null); // Render icon - svg = renderIcon(element, customisations, iconData); + svg = renderIcon(element, customisations, iconData) as IconifyElement; // Test SVG expect(svg.tagName.toUpperCase()).to.be.equal('SVG'); @@ -225,7 +230,7 @@ describe('Testing renderer', () => { expect(iconData).to.not.be.equal(null); // Render icon - svg = renderIcon(element, customisations, iconData); + svg = renderIcon(element, customisations, iconData) as IconifyElement; // Test SVG expect(svg.tagName.toUpperCase()).to.be.equal('SVG'); @@ -266,7 +271,7 @@ describe('Testing renderer', () => { expect(iconData).to.not.be.equal(null); // Render icon - svg = renderIcon(element, customisations, iconData); + svg = renderIcon(element, customisations, iconData) as IconifyElement; // Test SVG expect(svg.tagName.toUpperCase()).to.be.equal('SVG'); @@ -316,7 +321,7 @@ describe('Testing renderer', () => { expect(iconData).to.not.be.equal(null); // Render icon - svg = renderIcon(element, customisations, iconData); + svg = renderIcon(element, customisations, iconData) as IconifyElement; // Test SVG expect(svg.tagName.toUpperCase()).to.be.equal('SVG'); @@ -386,7 +391,11 @@ describe('Testing renderer', () => { expect(iconData).to.not.be.equal(null); // Render icon - let svg = renderIcon(element, customisations, iconData); + let svg = renderIcon( + element, + customisations, + iconData + ) as IconifyElement; // Test SVG expect(svg.tagName.toUpperCase()).to.be.equal('SVG'); @@ -437,7 +446,7 @@ describe('Testing renderer', () => { iconData = getIcon(storage, element.name.name); expect(iconData).to.not.be.equal(null); - svg = renderIcon(element, customisations, iconData); + svg = renderIcon(element, customisations, iconData) as IconifyElement; expect(svg).to.not.be.eql(lastSVG); // Test attributes, compare them with last SVG @@ -502,7 +511,7 @@ describe('Testing renderer', () => { iconData = getIcon(storage, element.name.name); expect(iconData).to.not.be.equal(null); - svg = renderIcon(element, customisations, iconData); + svg = renderIcon(element, customisations, iconData) as IconifyElement; expect(svg).to.not.be.eql(lastSVG); // Test changed attributes @@ -548,7 +557,7 @@ describe('Testing renderer', () => { iconData = getIcon(storage, element.name.name); expect(iconData).to.not.be.equal(null); - svg = renderIcon(element, customisations, iconData); + svg = renderIcon(element, customisations, iconData) as IconifyElement; expect(svg).to.not.be.eql(lastSVG); // Test changed attributes @@ -594,7 +603,11 @@ describe('Testing renderer', () => { expect(iconData).to.not.be.equal(null); // Render icon - let svg = renderIcon(element, customisations, iconData); + let svg = renderIcon( + element, + customisations, + iconData + ) as IconifyElement; /** * Change icon name to invalid @@ -638,7 +651,11 @@ describe('Testing renderer', () => { expect(iconData).to.not.be.equal(null); // Render icon - let svg = renderIcon(element, customisations, iconData); + let svg = renderIcon( + element, + customisations, + iconData + ) as IconifyElement; /** * Change icon name to invalid @@ -684,7 +701,11 @@ describe('Testing renderer', () => { ); // Render icon - let svg = renderIcon(element, customisations, iconData); + let svg = renderIcon( + element, + customisations, + iconData + ) as IconifyElement; // Copy variables for next test let lastElement = element; @@ -723,7 +744,7 @@ describe('Testing renderer', () => { 'Wrong icon body: ' + iconData.body ); - svg = renderIcon(element, customisations, iconData); + svg = renderIcon(element, customisations, iconData) as IconifyElement; expect(svg).to.not.be.eql(lastSVG); // Test finder @@ -763,15 +784,23 @@ describe('Testing renderer', () => { expect(iconData).to.not.be.equal(null); // Render icon - let svg = renderIcon(element, customisations, iconData); - if (svg.innerHTML) { - const html = svg.innerHTML; - // Test icon body to make sure icon has no transformation - expect(html.indexOf('transform="')).to.be.equal( - -1, - 'Found transform in icon: ' + html - ); - } + let svg = renderIcon( + element, + customisations, + iconData + ) as IconifyElement; + let html = renderIcon( + element, + customisations, + iconData, + true + ) as string; + + // Test icon body to make sure icon has no transformation + expect(html.indexOf('transform="')).to.be.equal( + -1, + 'Found transform in icon: ' + html + ); // Copy variables for next test let lastElement = element; @@ -804,16 +833,16 @@ describe('Testing renderer', () => { iconData = getIcon(storage, element.name.name); expect(iconData).to.not.be.equal(null); - svg = renderIcon(element, customisations, iconData); + svg = renderIcon(element, customisations, iconData) as IconifyElement; expect(svg).to.not.be.eql(lastSVG); - if (svg.innerHTML) { - const html = svg.innerHTML; - // Test icon body to make sure icon was changed - expect(html.indexOf('transform="')).to.not.be.equal( - -1, - 'Missing transform in icon: ' + html - ); - } + + html = renderIcon(element, customisations, iconData, true) as string; + + // Test icon body to make sure icon was changed + expect(html.indexOf('transform="')).to.not.be.equal( + -1, + 'Missing transform in icon: ' + html + ); // Test finder expect(element.finder.name(svg)).to.be.equal('mdi:home'); @@ -852,7 +881,11 @@ describe('Testing renderer', () => { expect(iconData).to.not.be.equal(null); // Render icon - let svg = renderIcon(element, customisations, iconData); + let svg = renderIcon( + element, + customisations, + iconData + ) as IconifyElement; // Check dimensions expect(svg.getAttribute('width')).to.be.equal('1em'); @@ -889,7 +922,7 @@ describe('Testing renderer', () => { iconData = getIcon(storage, element.name.name); expect(iconData).to.not.be.equal(null); - svg = renderIcon(element, customisations, iconData); + svg = renderIcon(element, customisations, iconData) as IconifyElement; expect(svg).to.not.be.eql(lastSVG); // Check dimensions @@ -935,7 +968,11 @@ describe('Testing renderer', () => { expect(iconData).to.not.be.equal(null); // Render icon - let svg = renderIcon(element, customisations, iconData); + let svg = renderIcon( + element, + customisations, + iconData + ) as IconifyElement; // Check dimensions and alignment expect(svg.getAttribute('width')).to.be.equal('48'); @@ -978,7 +1015,7 @@ describe('Testing renderer', () => { iconData = getIcon(storage, element.name.name); expect(iconData).to.not.be.equal(null); - svg = renderIcon(element, customisations, iconData); + svg = renderIcon(element, customisations, iconData) as IconifyElement; expect(svg).to.not.be.eql(lastSVG); // Check dimensions and alignment diff --git a/packages/browser-tests/tests/30-iconify-basic-test.ts b/packages/browser-tests/tests/30-iconify-basic-test.ts index 8e5ec62..2c09228 100644 --- a/packages/browser-tests/tests/30-iconify-basic-test.ts +++ b/packages/browser-tests/tests/30-iconify-basic-test.ts @@ -51,6 +51,31 @@ describe('Testing Iconify object', () => { height: 128, }); + it('Check iconExists', () => { + expect(Iconify.iconExists(prefix + ':' + 'account')).to.be.equal(true); + expect(Iconify.iconExists(prefix + ':' + 'missing')).to.be.equal(false); + expect(Iconify.iconExists(prefix + '-123:' + 'missing')).to.be.equal( + false + ); + }); + + it('Get SVG node', () => { + const node = Iconify.renderSVG(prefix + ':account', { + inline: true, + }); + expect(node).to.not.be.equal(null); + + const html = node.outerHTML; + console.log('Rendered SVG:', html); + expect(html.indexOf(' { node1.innerHTML = '

Testing Iconify without API

' + diff --git a/packages/iconify/README.md b/packages/iconify/README.md index 7557c5e..f53932c 100644 --- a/packages/iconify/README.md +++ b/packages/iconify/README.md @@ -21,7 +21,7 @@ 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 `` section of page or before ``): ```html - + ``` 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: diff --git a/packages/iconify/package.json b/packages/iconify/package.json index 805fdc4..9252f47 100644 --- a/packages/iconify/package.json +++ b/packages/iconify/package.json @@ -2,7 +2,7 @@ "name": "@iconify/iconify", "description": "Iconify common modules, used in multiple packages", "author": "Vjacheslav Trushkin (https://iconify.design)", - "version": "2.0.0-beta.0", + "version": "2.0.0-beta.1", "license": "(Apache-2.0 OR GPL-2.0)", "main": "./dist/iconify.min.js", "types": "./dist/iconify.d.ts", diff --git a/packages/iconify/src/finder.ts b/packages/iconify/src/finder.ts index 2139ec0..3e10b0d 100644 --- a/packages/iconify/src/finder.ts +++ b/packages/iconify/src/finder.ts @@ -29,9 +29,9 @@ export function addFinder(finder: IconifyFinder): void { * Interface for found elements list */ export interface PlaceholderElement { - element: IconifyElement; - finder: IconifyFinder; name: IconifyIconName; + element?: IconifyElement; + finder?: IconifyFinder; customisations?: IconifyIconCustomisations; } @@ -74,9 +74,9 @@ function compareCustomisations( export function findPlaceholders(root: HTMLElement): PlaceholderElement[] { const results: PlaceholderElement[] = []; - finders.forEach(finder => { + finders.forEach((finder) => { const elements = finder.find(root); - Array.prototype.forEach.call(elements, item => { + Array.prototype.forEach.call(elements, (item) => { const element = item as IconifyElement; if ( element[elementFinderProperty] !== void 0 && @@ -106,7 +106,7 @@ export function findPlaceholders(root: HTMLElement): PlaceholderElement[] { // Find all modified SVG const elements = root.querySelectorAll('svg.iconify'); - Array.prototype.forEach.call(elements, item => { + Array.prototype.forEach.call(elements, (item) => { const element = item as IconifyElement; const finder = element[elementFinderProperty]; const data = element[elementDataProperty]; diff --git a/packages/iconify/src/iconify.ts b/packages/iconify/src/iconify.ts index ca8c8e1..0d3fe41 100644 --- a/packages/iconify/src/iconify.ts +++ b/packages/iconify/src/iconify.ts @@ -42,10 +42,17 @@ import { API } from '@iconify/core/lib/api/'; import { setAPIModule } from '@iconify/core/lib/api/modules'; import { setAPIConfig, IconifyAPIConfig } from '@iconify/core/lib/api/config'; import { prepareQuery, sendQuery } from './modules/api-jsonp'; +import { + IconifyIconLoaderCallback, + IconifyIconLoaderAbort, +} from '@iconify/core/lib/interfaces/loader'; // Observer import { observer } from './modules/observer'; +// Render +import { renderIcon } from './render'; + // Scan import { scanDOM } from './scan'; @@ -67,7 +74,7 @@ export { export { IconifyIconBuildResult }; // API -export { IconifyAPIConfig }; +export { IconifyAPIConfig, IconifyIconLoaderCallback, IconifyIconLoaderAbort }; /** * Cache types @@ -100,7 +107,25 @@ export interface IconifyGlobal { */ listIcons: (prefix?: string) => string[]; + /** + * Load icons + */ + loadIcons: ( + icons: (IconifyIconName | string)[], + callback?: IconifyIconLoaderCallback + ) => IconifyIconLoaderAbort; + /* Rendering icons */ + renderSVG: ( + name: string, + customisations: IconifyIconCustomisations + ) => SVGElement | null; + + renderHTML: ( + name: string, + customisations: IconifyIconCustomisations + ) => string | null; + /** * Get icon data */ @@ -110,7 +135,7 @@ export interface IconifyGlobal { ) => IconifyIconBuildResult | null; /** - * Replace IDs in icon body, should be used when parsing renderIcon() result + * Replace IDs in icon body, should be used when parsing buildIcon() result */ replaceIDs: (body: string) => string; @@ -192,7 +217,7 @@ function getIconData(name: string): FullIconifyIcon | null { /** * Get SVG data */ -function getSVG( +function buildIcon( name: string, customisations: IconifyIconCustomisations ): IconifyIconBuildResult | null { @@ -209,6 +234,37 @@ function getSVG( return iconToSVG(iconData, changes); } +/** + * Generate icon + */ +function generateIcon( + name: string, + customisations: IconifyIconCustomisations, + returnString: boolean +): SVGElement | string | null { + // Get icon data + const iconData = getIconData(name); + if (!iconData) { + return null; + } + + // Split name + const iconName = stringToIcon(name); + + // Clean up customisations + const changes = fullCustomisations(customisations); + + // Get data + return (renderIcon( + { + name: iconName, + }, + changes, + iconData, + returnString + ) as unknown) as SVGElement | string | null; +} + /** * Global variable */ @@ -217,7 +273,7 @@ const Iconify: IconifyGlobal = { getVersion: () => '__iconify_version__', // Check if icon exists - iconExists: (name) => getIconData(name) !== void 0, + iconExists: (name) => getIconData(name) !== null, // Get raw icon data getIcon: (name) => { @@ -248,8 +304,20 @@ const Iconify: IconifyGlobal = { return icons; }, - // Render icon - renderIcon: getSVG, + // Load icons + loadIcons: API.loadIcons, + + // Render SVG + renderSVG: (name: string, customisations: IconifyIconCustomisations) => { + return generateIcon(name, customisations, false) as SVGElement | null; + }, + + renderHTML: (name: string, customisations: IconifyIconCustomisations) => { + 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, // Replace IDs in body replaceIDs: replaceIDs, diff --git a/packages/iconify/src/render.ts b/packages/iconify/src/render.ts index b04f29b..00dee5f 100644 --- a/packages/iconify/src/render.ts +++ b/packages/iconify/src/render.ts @@ -19,19 +19,28 @@ import { export function renderIcon( placeholder: PlaceholderElement, customisations: IconifyIconCustomisations, - iconData: FullIconifyIcon -): IconifyElement | null { + iconData: FullIconifyIcon, + returnString?: boolean +): IconifyElement | string | null { const data = iconToSVG(iconData, fullCustomisations(customisations)); - // Get class name + // Placeholder properties const placeholderElement = placeholder.element; - const placeholderClassName = placeholderElement.getAttribute('class'); - const filteredClassList = placeholder.finder.classFilter( - placeholderClassName ? placeholderClassName.split(/\s+/) : [] - ); + const finder = placeholder.finder; + const name = placeholder.name; + + // Get class name + const placeholderClassName = placeholderElement + ? placeholderElement.getAttribute('class') + : ''; + const filteredClassList = finder + ? finder.classFilter( + placeholderClassName ? placeholderClassName.split(/\s+/) : [] + ) + : []; const className = 'iconify iconify--' + - placeholder.name.prefix + + name.prefix + (filteredClassList.length ? ' ' + filteredClassList.join(' ') : ''); // Generate SVG as string @@ -62,42 +71,50 @@ export function renderIcon( svgStyle.verticalAlign = '-0.125em'; } - // Copy attributes from placeholder - const placeholderAttributes = placeholderElement.attributes; - for (let i = 0; i < placeholderAttributes.length; i++) { - const item = placeholderAttributes.item(i); - if (item) { - const name = item.name; - if ( - name !== 'class' && - name !== 'style' && - svgAttributes[name] === void 0 - ) { - try { - svg.setAttribute(name, item.value); - } catch (err) {} + // Copy stuff from placeholder + if (placeholderElement) { + // Copy attributes + const placeholderAttributes = placeholderElement.attributes; + for (let i = 0; i < placeholderAttributes.length; i++) { + const item = placeholderAttributes.item(i); + if (item) { + const name = item.name; + if ( + name !== 'class' && + name !== 'style' && + svgAttributes[name] === void 0 + ) { + try { + svg.setAttribute(name, item.value); + } catch (err) {} + } } } + + // Copy styles + const placeholderStyle = placeholderElement.style; + for (let i = 0; i < placeholderStyle.length; i++) { + const attr = placeholderStyle[i]; + svgStyle[attr] = placeholderStyle[attr]; + } } - // Copy styles from placeholder - const placeholderStyle = placeholderElement.style; - for (let i = 0; i < placeholderStyle.length; i++) { - const attr = placeholderStyle[i]; - svgStyle[attr] = placeholderStyle[attr]; + // Store finder specific data + if (finder) { + const elementData: IconifyElementData = { + name: name, + status: 'loaded', + customisations: customisations, + }; + svg[elementDataProperty] = elementData; + svg[elementFinderProperty] = finder; } - // Store data - const elementData: IconifyElementData = { - name: placeholder.name, - status: 'loaded', - customisations: customisations, - }; - svg[elementDataProperty] = elementData; - svg[elementFinderProperty] = placeholder.finder; + // Get result + const result = returnString ? span.innerHTML : svg; // Replace placeholder - if (placeholderElement.parentNode) { + if (placeholderElement && placeholderElement.parentNode) { placeholderElement.parentNode.replaceChild(svg, placeholderElement); } else { // Placeholder has no parent? Remove SVG parent as well @@ -105,5 +122,5 @@ export function renderIcon( } // Return new node - return svg; + return result; }