@ipi-soft/ng-components
Version:
Custom Angular Components
202 lines (197 loc) • 8.8 kB
JavaScript
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