@senx/discovery-widgets
Version:
Discovery Widgets Elements
313 lines (309 loc) • 14.3 kB
JavaScript
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