@jupyterlab/ui-components
Advanced tools
Comparing version
@@ -24,2 +24,3 @@ import React from 'react'; | ||
resolveName(name: string): string; | ||
resolveSvg(name: string): HTMLElement | null; | ||
svg(name: string): string; | ||
@@ -26,0 +27,0 @@ static iconClassName(name: string): string; |
@@ -56,12 +56,21 @@ // Copyright (c) Jupyter Development Team. | ||
let resolvedName = this.resolveName(name); | ||
if (!resolvedName || | ||
(container && | ||
container.dataset.icon && | ||
container.dataset.icon === resolvedName)) { | ||
if (!resolvedName) { | ||
// bail if failing silently or icon node is already set | ||
return; | ||
return null; | ||
} | ||
let svgNode = Private.parseSvg(this.svg(resolvedName)); | ||
if (container && | ||
container.dataset.icon && | ||
container.dataset.icon === resolvedName && | ||
container.children[0]) { | ||
// return the existing icon node | ||
return container.children[0]; | ||
} | ||
// ensure that svg html is valid | ||
const svgElement = this.resolveSvg(resolvedName); | ||
if (!svgElement) { | ||
// bail if failing silently | ||
return null; | ||
} | ||
if (title) { | ||
Private.setTitleSvg(svgNode, title); | ||
Private.setTitleSvg(svgElement, title); | ||
} | ||
@@ -72,3 +81,3 @@ if (container) { | ||
container.dataset.icon = resolvedName; | ||
container.appendChild(svgNode); | ||
container.appendChild(svgElement); | ||
let styleClass = propsStyle ? iconStyle(propsStyle) : ''; | ||
@@ -86,5 +95,5 @@ if (className || className === '') { | ||
// add icon styling class directly to the svg node | ||
svgNode.setAttribute('class', classes(className, propsStyle ? iconStyleFlat(propsStyle) : '')); | ||
svgElement.setAttribute('class', classes(className, propsStyle ? iconStyleFlat(propsStyle) : '')); | ||
} | ||
return svgNode; | ||
return svgElement; | ||
} | ||
@@ -99,3 +108,3 @@ /** | ||
// we may have been handed a className in place of name | ||
let resolvedName = this.resolveName(name); | ||
const resolvedName = this.resolveName(name); | ||
if (!resolvedName) { | ||
@@ -105,4 +114,10 @@ // bail if failing silently | ||
} | ||
return (React.createElement(Tag, { className: classes(className, propsStyle ? iconStyle(propsStyle) : ''), dangerouslySetInnerHTML: { | ||
__html: resolvedName ? this.svg(resolvedName) : '' | ||
// ensure that svg html is valid | ||
const svgElement = this.resolveSvg(resolvedName); | ||
if (!svgElement) { | ||
// bail if failing silently | ||
return React.createElement(React.Fragment, null); | ||
} | ||
return (React.createElement(Tag, { className: classes(className, propsStyle ? iconStyle(propsStyle) : ''), "data-icon": resolvedName, dangerouslySetInnerHTML: { | ||
__html: svgElement.outerHTML | ||
} })); | ||
@@ -133,2 +148,33 @@ } | ||
} | ||
resolveSvg(name) { | ||
let svgHtml = this.svg(name); | ||
// workaround for 1.0.x versions of Jlab pulling in 1.1.x versions of ui-components | ||
// TODO: delete workaround in v2.0.0 | ||
const bprefix = 'data:image/svg+xml;base64,'; | ||
if (svgHtml.startsWith(bprefix)) { | ||
// slice off the prefix and covert base64 to string | ||
svgHtml = atob(svgHtml.slice(bprefix.length)); | ||
} | ||
const parser = new DOMParser(); | ||
const svgElement = parser.parseFromString(svgHtml, 'image/svg+xml') | ||
.documentElement; | ||
if (svgElement.getElementsByTagName('parsererror').length > 0) { | ||
const errmsg = `SVG HTML was malformed for icon name: ${name}`; | ||
// parse failed, svgElement will be an error box | ||
if (this._debug) { | ||
// fail noisily, render the error box | ||
console.error(errmsg); | ||
return svgElement; | ||
} | ||
else { | ||
// bad svg is always a real error, fail silently but warn | ||
console.warn(errmsg); | ||
return null; | ||
} | ||
} | ||
else { | ||
// parse succeeded | ||
return svgElement; | ||
} | ||
} | ||
svg(name) { | ||
@@ -153,7 +199,2 @@ return this._svg[name]; | ||
(function (Private) { | ||
function parseSvg(svg) { | ||
let parser = new DOMParser(); | ||
return parser.parseFromString(svg, 'image/svg+xml').documentElement; | ||
} | ||
Private.parseSvg = parseSvg; | ||
function setTitleSvg(svgNode, title) { | ||
@@ -160,0 +201,0 @@ // add a title node to the top level svg node |
@@ -35,2 +35,3 @@ import { h } from '@phosphor/virtualdom'; | ||
className: '', | ||
title: title.iconLabel, | ||
container: iconNode, | ||
@@ -37,0 +38,0 @@ center: true, |
{ | ||
"name": "@jupyterlab/ui-components", | ||
"version": "1.1.0", | ||
"version": "1.1.1", | ||
"description": "JupyterLab - UI components written in React", | ||
@@ -67,3 +67,3 @@ "homepage": "https://github.com/jupyterlab/jupyterlab", | ||
}, | ||
"gitHead": "65af312f8977f050b259b0d1c30901c555c261ad" | ||
"gitHead": "d0099f2bdcac721bbd8739f1d057fa133e61b107" | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
118722
2.2%1096
4.08%