UNPKG

@senx/discovery-widgets

Version:

Discovery Widgets Elements

313 lines (309 loc) 14.3 kB
import { proxyCustomElement, HTMLElement, createEvent, h, Host } from '@stencil/core/internal/client'; import { b as DataModel } from './types.js'; import { P as Param, G as GTSLib, U as Utils, L as Logger } from './utils.js'; import { a as html2canvas } from './html2canvas.js'; import { d as defineCustomElement$1 } from './discovery-spinner2.js'; const discoverySvgCss = "/*!\n * Copyright 2022-2023 SenX S.A.S.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */:host{display:block;width:100%;height:100%;position:relative}:host .hoverable{cursor:pointer}:host .svg-wrapper{position:absolute}:host .svg-wrapper .svg-container{height:100%}:host .svg-wrapper .svg-container svg{display:block;overflow:hidden;height:100%;width:100%}"; const DiscoverySvgStyle0 = discoverySvgCss; const DiscoverySvgComponent = /*@__PURE__*/ proxyCustomElement(class DiscoverySvgComponent extends HTMLElement { constructor() { super(); this.__registerHost(); this.__attachShadow(); this.draw = createEvent(this, "draw", 7); this.discoveryEvent = createEvent(this, "discoveryEvent", 7); this.options = new Param(); this.debug = false; this.unit = ''; this.execTime = 0; this.parsing = false; this.toDisplay = []; this.defOptions = new Param(); this.funqueue = []; this.refs = []; this.listenersAdded = false; } updateRes() { this.innerResult = GTSLib.getData(this.result); this.parseResult(); } optionsUpdate(newValue, oldValue) { var _a, _b; (_a = this.LOG) === null || _a === void 0 ? void 0 : _a.debug(['optionsUpdate'], newValue, oldValue); let opts = newValue; if (!!newValue && typeof newValue === 'string') { opts = JSON.parse(newValue); } if (!Utils.deepEqual(opts, this.innerOptions)) { this.innerOptions = Utils.clone(opts); setTimeout(() => this.parseResult()); (_b = this.LOG) === null || _b === void 0 ? void 0 : _b.debug(['optionsUpdate 2'], { options: this.innerOptions, newValue, oldValue }); } } discoveryEventHandler(event) { this.funqueue.push(this.wrapFunction(this.processEvent.bind(this), this, [event])); } async resize() { const dims = Utils.getContentBounds(this.el.parentElement); this.width = dims.w; this.height = dims.h; return Promise.resolve(); } componentWillLoad() { const dims = Utils.getContentBounds(this.el.parentElement); this.width = dims.w; this.height = dims.h; this.parseResult(); this.processQueue(); } convert(data) { var _a, _b, _c; const toDisplay = []; this.refs = []; (_a = this.LOG) === null || _a === void 0 ? void 0 : _a.debug(['convert'], data); let options = Utils.mergeDeep(this.defOptions, this.innerOptions || {}); options = Utils.mergeDeep(options || {}, data.globalParams); this.innerOptions = Utils.clone(options); if (this.innerOptions.customStyles) { this.innerStyle = Utils.clone(Object.assign(Object.assign({}, this.innerStyle), (_b = this.innerOptions.customStyles) !== null && _b !== void 0 ? _b : {})); } if (GTSLib.isArray(data.data)) { (data.data || []).forEach(img => { var _a; (_a = this.LOG) === null || _a === void 0 ? void 0 : _a.debug(['convert'], DiscoverySvgComponent.isSVG(img)); if (DiscoverySvgComponent.isSVG(img)) { toDisplay.push(this.sanitize(img)); } }); } else if (data.data && DiscoverySvgComponent.isSVG(data.data)) { (_c = this.LOG) === null || _c === void 0 ? void 0 : _c.debug(['convert'], DiscoverySvgComponent.isSVG(data.data)); toDisplay.push(this.sanitize(data.data)); } return toDisplay; } processEvent(event) { return new Promise(resolve => { var _a; const res = Utils.parseEventData(event.detail, this.innerOptions.eventHandler, this.el.id); if (res.style) { this.innerStyle = Object.assign(Object.assign({}, this.innerStyle), res.style); } if (res.xpath) { const toDisplay = []; ((_a = this.toDisplay) !== null && _a !== void 0 ? _a : []).forEach(img => { var _a; (_a = this.LOG) === null || _a === void 0 ? void 0 : _a.debug(['convert'], DiscoverySvgComponent.isSVG(img)); if (DiscoverySvgComponent.isSVG(img)) { toDisplay.push(this.sanitize(img, res.xpath.selector, res.xpath.value)); } }); this.toDisplay = [...toDisplay]; } resolve(true); }); } wrapFunction(fn, context, params) { return () => fn.apply(context, params); } processQueue() { // eslint-disable-next-line no-async-promise-executor void new Promise(async (resolve) => { while (this.funqueue.length > 0) await (this.funqueue.shift())(); resolve(true); }).then(() => setTimeout(() => this.processQueue(), 100)); } parseResult() { var _a, _b; this.parsing = true; this.LOG = new Logger(DiscoverySvgComponent, this.debug); if (typeof this.options === 'string') { this.innerOptions = JSON.parse(this.options); } else { this.innerOptions = this.options; } this.innerResult = GTSLib.getData(this.result); this.toDisplay = this.convert((_a = this.innerResult) !== null && _a !== void 0 ? _a : new DataModel()); (_b = this.LOG) === null || _b === void 0 ? void 0 : _b.debug(['componentWillLoad'], { type: this.type, options: this.innerOptions, toDisplay: this.toDisplay, }); this.parsing = false; this.draw.emit(); } static isSVG(data) { return typeof data === 'string' && /<svg/gi.test(data); } sanitize(svg, xpath, replacement) { var _a, _b, _c; try { const svgDoc = Utils.parseXML(svg.trim(), 'image/svg+xml'); // trim to avoid weird bugs with spaces before xml processing instruction <? ?> (forbidden) const el = svgDoc.getElementsByTagName('svg').item(0); if (xpath) { let nsXpath = xpath.split('/').filter(e => !!e).map(e => 'svg:' + e).join('/'); if (!nsXpath.startsWith('svg:svg')) { nsXpath = '//' + nsXpath; } let nsr = prefix => { if (prefix === 'svg') { return 'http://www.w3.org/2000/svg'; } else if (prefix === 'inkscape') { // allow an easy use of inkscape:label for example, in the xpath. '//*[@inkscape:label="text2"]' return 'http://www.inkscape.org/namespaces/inkscape'; } else { return null; } }; const iterator = svgDoc.evaluate(nsXpath, svgDoc, nsr, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null); let elem = iterator.iterateNext(); const elemsToReplace = []; while (elem) { elemsToReplace.push(elem); elem = iterator.iterateNext(); } for (const e of elemsToReplace) { if (typeof replacement === 'string') { const parent = e.parentElement; const g = document.createElementNS('http://www.w3.org/2000/svg', 'g'); g.innerHTML = replacement.trim(); parent.replaceChild(g.firstChild, e); } else { Object.keys(replacement).forEach(k => { if ('innerHTML' !== k) { e.setAttribute(k, replacement[k].toString()); } else { e.innerHTML = replacement[k].toString(); } }); } } } if (!((_a = el.getAttribute('width')) === null || _a === void 0 ? void 0 : _a.endsWith('px')) && !!el.getAttribute('viewBox')) { const vb = el.getAttribute('viewBox').split(' '); el.setAttribute('width', vb[2] + 'px'); } if (!((_b = el.getAttribute('height')) === null || _b === void 0 ? void 0 : _b.endsWith('px')) && !!el.getAttribute('viewBox')) { const vb = el.getAttribute('viewBox').split(' '); el.setAttribute('height', vb[3] + 'px'); } if (el.getAttribute('width') && el.getAttribute('height')) { el.setAttribute('viewBox', '0 0 ' + el.getAttribute('width').replace(/[a-z]+/gi, '') + ' ' + el.getAttribute('height').replace(/[a-z]+/gi, '')); } if (el.getAttribute('preserveAspectRatio')) { el.removeAttribute('preserveAspectRatio'); } el.setAttribute('preserveAspectRatio', 'xMidYMid meet'); return new XMLSerializer().serializeToString(svgDoc); } catch (e) { (_c = this.LOG) === null || _c === void 0 ? void 0 : _c.error(['exec'], e); return svg; } } triggerEvent(evt) { this.discoveryEvent.emit(Object.assign(Object.assign({}, evt), { source: this.el.id })); } async export(type = 'png') { return type === 'svg' ? this.toDisplay : (await html2canvas(this.el)).toDataURL(); } generateStyle(innerStyle) { return Object.keys(innerStyle || {}).map(k => k + ' { ' + innerStyle[k] + ' }').join('\n'); } // noinspection JSUnusedGlobalSymbols componentDidRender() { this.addHandlers(); } render() { this.listenersAdded = false; return (h(Host, { key: '40e3b0492786284a1bce1cab203419f76e7da9ef' }, h("style", { key: 'cd6d654d19c1b321120cc030914a5226b8ba793c' }, this.generateStyle(this.innerStyle)), h("div", { key: 'bd89ed41d6ec1a3f8461e7ece94a643dbea5de91', class: "svg-wrapper", style: { width: `${this.width}px`, height: `${this.height}px` } }, this.parsing ? h("discovery-spinner", null, "Parsing data...") : this.toDisplay.length > 0 ? this.toDisplay.map(svg => h("div", { class: "svg-container", innerHTML: svg, ref: el => this.refs.push(el) })) : ''))); } addHandlers() { var _a, _b; if (!this.listenersAdded) { for (const svgWrapper of this.refs) { for (const h of (_b = (_a = this.innerOptions.svg) === null || _a === void 0 ? void 0 : _a.handlers) !== null && _b !== void 0 ? _b : []) { if (h.selector) { for (const elem of svgWrapper.querySelectorAll(h.selector)) { elem.classList.add('hoverable'); if (h.click) { elem.addEventListener('click', e => { this.triggerEvent(h.event); e.stopImmediatePropagation(); }); } if (h.hover) { elem.addEventListener('mouseover', e => { this.triggerEvent(h.event); e.stopImmediatePropagation(); }); } } } } } this.listenersAdded = true; } } get el() { return this; } static get watchers() { return { "result": ["updateRes"], "options": ["optionsUpdate"] }; } static get style() { return DiscoverySvgStyle0; } }, [1, "discovery-svg", { "result": [1], "type": [1], "start": [2], "options": [1], "width": [1026], "height": [1026], "debug": [4], "unit": [1], "url": [1], "chartTitle": [1, "chart-title"], "execTime": [32], "bgColor": [32], "fontColor": [32], "parsing": [32], "toDisplay": [32], "innerStyle": [32], "innerResult": [32], "innerOptions": [32], "resize": [64], "export": [64] }, [[8, "discoveryEvent", "discoveryEventHandler"]], { "result": ["updateRes"], "options": ["optionsUpdate"] }]); function defineCustomElement() { if (typeof customElements === "undefined") { return; } const components = ["discovery-svg", "discovery-spinner"]; components.forEach(tagName => { switch (tagName) { case "discovery-svg": if (!customElements.get(tagName)) { customElements.define(tagName, DiscoverySvgComponent); } break; case "discovery-spinner": if (!customElements.get(tagName)) { defineCustomElement$1(); } break; } }); } export { DiscoverySvgComponent as D, defineCustomElement as d }; //# sourceMappingURL=discovery-svg2.js.map