UNPKG

@ipi-soft/ng-components

Version:

Custom Angular Components

202 lines (197 loc) 8.8 kB
import * as i0 from '@angular/core'; import { Injectable, Inject, Component, Input } from '@angular/core'; import { DOCUMENT } from '@angular/common'; import { of } from 'rxjs'; import { catchError, map, tap, finalize, share } from 'rxjs/operators'; import * as i1 from '@angular/common/http'; class IpiImgService { constructor(http, document) { this.http = http; this.document = document; this.svgs = new Map(); this.svgsLoading = new Map(); this.defaultSvg = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path d="m 4 1 c -1.644531 0 -3 1.355469 -3 3 v 1 h 1 v -1 c 0 -1.109375 0.890625 -2 2 -2 h 1 v -1 z m 2 0 v 1 h 4 v -1 z m 5 0 v 1 h 1 c 1.109375 0 2 0.890625 2 2 v 1 h 1 v -1 c 0 -1.644531 -1.355469 -3 -3 -3 z m -5 4 c -0.550781 0 -1 0.449219 -1 1 s 0.449219 1 1 1 s 1 -0.449219 1 -1 s -0.449219 -1 -1 -1 z m -5 1 v 4 h 1 v -4 z m 13 0 v 4 h 1 v -4 z m -4.5 2 l -2 2 l -1.5 -1 l -2 2 v 0.5 c 0 0.5 0.5 0.5 0.5 0.5 h 7 s 0.472656 -0.035156 0.5 -0.5 v -1 z m -8.5 3 v 1 c 0 1.644531 1.355469 3 3 3 h 1 v -1 h -1 c -1.109375 0 -2 -0.890625 -2 -2 v -1 z m 13 0 v 1 c 0 1.109375 -0.890625 2 -2 2 h -1 v 1 h 1 c 1.644531 0 3 -1.355469 3 -3 v -1 z m -8 3 v 1 h 4 v -1 z m 0 0" fill="#2e3434" fill-opacity="0.34902"/></svg>'; } loadImg(url) { if (!url.endsWith('.svg')) { return url; } if (this.svgs.has(url)) { return of(this.svgs.get(url)); } if (this.svgsLoading.has(url)) { return this.svgsLoading.get(url); } const observable = this.getSvg(url) .pipe(catchError(() => { return of(this.defaultSvg); }), map(content => this.createSVG(content)), tap(element => this.svgs.set(url, element)), finalize(() => this.svgsLoading.delete(url)), share()); this.svgsLoading.set(url, observable); return observable; } getSvg(url) { return this.http.get(url, { responseType: 'text' }); } createSVG(content) { const div = this.document.createElement('DIV'); div.innerHTML = content; return div.querySelector('svg'); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.4", ngImport: i0, type: IpiImgService, deps: [{ token: i1.HttpClient }, { token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.1.4", ngImport: i0, type: IpiImgService, providedIn: 'root' }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.4", ngImport: i0, type: IpiImgService, decorators: [{ type: Injectable, args: [{ providedIn: 'root' }] }], ctorParameters: () => [{ type: i1.HttpClient }, { type: Document, decorators: [{ type: Inject, args: [DOCUMENT] }] }] }); class ImageHelper { constructor() { this.loaded = false; } } class IpiImageComponent { constructor(element, renderer, imgService, document, changeDetectorRef) { this.element = element; this.renderer = renderer; this.imgService = imgService; this.document = document; this.changeDetectorRef = changeDetectorRef; this.helper = new ImageHelper(); this.changeDetectorRef.detach(); } ngOnInit() { this.init(); } ngOnDestroy() { this.destroy(); } ngOnChanges(changeRecord) { if (!this.helper.loaded) { return; } if (changeRecord['src']) { this.destroy(); this.init(); } if (changeRecord['ariaLabel']) { this.setAriaLabel(changeRecord['ariaLabel'].currentValue); } } init() { if (!this.src || !this.ariaLabel) { return; } const img = this.imgService.loadImg(this.src); if (typeof img === 'string') { this.initImage(img); return; } this.helper.imgSub = img.subscribe(img => { this.initSvg(img); }); } destroy() { if (this.helper.imgSub) { this.helper.imgSub.unsubscribe(); } this.helper = new ImageHelper(); } initImage(url) { const img = this.document.createElement('img'); img.onerror = () => { this.onImgError(elem, img); }; const elem = this.element.nativeElement; elem.innerHTML = ''; this.setStyling(img); img.src = url; this.renderer.appendChild(elem, img); this.setAriaLabel(this.ariaLabel); this.helper.loaded = true; this.copyNgContentAttribute(elem, img); } initSvg(svg) { if (this.helper.loaded || !svg) { return; } const clonedSvg = svg.cloneNode(true); this.setStyling(clonedSvg); const elem = this.element.nativeElement; elem.innerHTML = ''; this.renderer.appendChild(elem, clonedSvg); this.helper.loaded = true; if (!(this.ariaLabel === undefined && elem.firstChild.hasAttribute('aria-label')) && this.ariaLabel) { this.setAriaLabel(this.ariaLabel); } this.copyNgContentAttribute(elem, clonedSvg); } setAriaLabel(label) { const img = this.element.nativeElement.firstChild; if (img) { if (label === '') { this.renderer.setAttribute(img, 'aria-hidden', 'true'); this.renderer.removeAttribute(img, 'aria-label'); } else { this.renderer.removeAttribute(img, 'aria-hidden'); this.renderer.setAttribute(img, 'aria-label', label); } } } setStyling(element) { this.element.nativeElement.style.display = 'flex'; this.element.nativeElement.style.justifyContent = 'center'; this.element.nativeElement.style.alignItems = 'center'; element.style.width = 'inherit'; element.style.maxWidth = 'inherit'; element.style.height = 'inherit'; element.style.maxHeight = 'inherit'; } onImgError(element, img) { this.renderer.removeChild(element, img); let svg = document.createRange().createContextualFragment(this.imgService.defaultSvg); this.renderer.appendChild(element, svg); setTimeout(() => { this.renderer.setAttribute(element.firstChild, 'aria-label', 'A broken or missing image'); }); } copyNgContentAttribute(hostElem, icon) { const attributes = hostElem.attributes; for (let i = 0; i < attributes.length; i += 1) { const attribute = attributes.item(i); if (attribute && attribute.name.startsWith('_ngcontent')) { this.setNgContentAttribute(icon, attribute.name); break; } } } setNgContentAttribute(parent, attributeName) { this.renderer.setAttribute(parent, attributeName, ''); for (let i = 0; i < parent.childNodes.length; i += 1) { const child = parent.childNodes[i]; if (child instanceof Element) { this.setNgContentAttribute(child, attributeName); } } } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.4", ngImport: i0, type: IpiImageComponent, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }, { token: IpiImgService }, { token: DOCUMENT }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.1.4", type: IpiImageComponent, isStandalone: true, selector: "ipi-img", inputs: { src: "src", ariaLabel: "ariaLabel" }, usesOnChanges: true, ngImport: i0, template: '<ng-content></ng-content>', isInline: true }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.4", ngImport: i0, type: IpiImageComponent, decorators: [{ type: Component, args: [{ selector: 'ipi-img', template: '<ng-content></ng-content>', }] }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.Renderer2 }, { type: IpiImgService }, { type: Document, decorators: [{ type: Inject, args: [DOCUMENT] }] }, { type: i0.ChangeDetectorRef }], propDecorators: { src: [{ type: Input }], ariaLabel: [{ type: Input }] } }); /** * Generated bundle index. Do not edit. */ export { IpiImageComponent, IpiImgService }; //# sourceMappingURL=ipi-soft-ng-components-image.mjs.map