@lenne.tech/ng-base 0.3.3 → 0.3.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bundles/lenne.tech-ng-base-src-lib-base.umd.js +739 -702
- package/bundles/lenne.tech-ng-base-src-lib-base.umd.js.map +1 -1
- package/bundles/lenne.tech-ng-base.umd.js +739 -702
- package/bundles/lenne.tech-ng-base.umd.js.map +1 -1
- package/esm2015/lib/base/classes/helper.class.js +19 -1
- package/esm2015/lib/base/directives/match-height.directive.js +27 -10
- package/esm2015/lib/base/services/image.service.js +11 -7
- package/esm2015/src/lib/base/classes/helper.class.js +19 -1
- package/esm2015/src/lib/base/directives/match-height.directive.js +27 -10
- package/esm2015/src/lib/base/services/image.service.js +11 -7
- package/fesm2015/lenne.tech-ng-base-src-lib-base.js +548 -510
- package/fesm2015/lenne.tech-ng-base-src-lib-base.js.map +1 -1
- package/fesm2015/lenne.tech-ng-base.js +548 -510
- package/fesm2015/lenne.tech-ng-base.js.map +1 -1
- package/lib/base/classes/helper.class.d.ts +7 -0
- package/lib/base/directives/match-height.directive.d.ts +4 -3
- package/lib/base/services/image.service.d.ts +1 -1
- package/package.json +1 -1
- package/src/lib/base/classes/helper.class.d.ts +7 -0
- package/src/lib/base/directives/match-height.directive.d.ts +4 -3
- package/src/lib/base/lenne.tech-ng-base-src-lib-base.metadata.json +1 -1
- package/src/lib/base/services/image.service.d.ts +1 -1
|
@@ -2,13 +2,14 @@ import * as i1 from 'apollo-angular';
|
|
|
2
2
|
import { APOLLO_OPTIONS, gql, Apollo } from 'apollo-angular';
|
|
3
3
|
import { HttpLink } from 'apollo-angular/http';
|
|
4
4
|
import * as i0 from '@angular/core';
|
|
5
|
-
import { InjectionToken, Injectable, Inject, Directive, ElementRef, Input, Output, HostBinding,
|
|
5
|
+
import { InjectionToken, Injectable, Inject, Directive, ElementRef, Input, Output, HostBinding, PLATFORM_ID, HostListener, Pipe, NgModule } from '@angular/core';
|
|
6
6
|
import { BehaviorSubject, Observable, of, throwError } from 'rxjs';
|
|
7
7
|
import { ApolloLink, split, concat } from '@apollo/client/core';
|
|
8
8
|
import { InMemoryCache } from '@apollo/client/cache';
|
|
9
9
|
import { WebSocketLink } from '@apollo/client/link/ws';
|
|
10
10
|
import { getMainDefinition } from '@apollo/client/utilities';
|
|
11
11
|
import { __awaiter } from 'tslib';
|
|
12
|
+
import { isPlatformBrowser } from '@angular/common';
|
|
12
13
|
import * as i1$2 from '@angular/platform-browser';
|
|
13
14
|
import { DomSanitizer, Title, Meta } from '@angular/platform-browser';
|
|
14
15
|
import * as i1$1 from '@angular/router';
|
|
@@ -419,362 +420,6 @@ LazyLoadDirective.propDecorators = {
|
|
|
419
420
|
src: [{ type: Input }]
|
|
420
421
|
};
|
|
421
422
|
|
|
422
|
-
/**
|
|
423
|
-
* Image service
|
|
424
|
-
*/
|
|
425
|
-
class ImageService {
|
|
426
|
-
/**
|
|
427
|
-
* Preaload images (for lazy handling)
|
|
428
|
-
*
|
|
429
|
-
* @param options
|
|
430
|
-
* @protected
|
|
431
|
-
*/
|
|
432
|
-
preLoadImages(options) {
|
|
433
|
-
// Init configuration
|
|
434
|
-
const config = Object.assign({ doneFunnction: undefined, elements: document, regExp: undefined, timeout: undefined }, options);
|
|
435
|
-
return new Promise((resolve) => {
|
|
436
|
-
var _a;
|
|
437
|
-
// Init variables
|
|
438
|
-
let resolved = false;
|
|
439
|
-
let timeoutId;
|
|
440
|
-
// HTMLCollection to array
|
|
441
|
-
if (config.elements instanceof HTMLCollection) {
|
|
442
|
-
config.elements = Array.from(config.elements);
|
|
443
|
-
}
|
|
444
|
-
// Single element to array
|
|
445
|
-
if (!Array.isArray(config.elements)) {
|
|
446
|
-
config.elements = [config.elements];
|
|
447
|
-
}
|
|
448
|
-
// Init loading
|
|
449
|
-
const promises = [];
|
|
450
|
-
// Get all images
|
|
451
|
-
let images = [];
|
|
452
|
-
config.elements.forEach((element) => {
|
|
453
|
-
images = images.concat(Array.from(element.getElementsByTagName('img')));
|
|
454
|
-
});
|
|
455
|
-
// Prepare images
|
|
456
|
-
for (const image of images) {
|
|
457
|
-
const src = image.getAttribute('src');
|
|
458
|
-
// Check if changes are necessary and possible
|
|
459
|
-
if ((image.complete && image.naturalHeight !== 0) || // already laoded
|
|
460
|
-
image.getAttribute('loading') !== 'lazy' || // loading attribute !== lazy
|
|
461
|
-
!src || // Image has no src
|
|
462
|
-
((_a = config.regExp) === null || _a === void 0 ? void 0 : _a.test(src)) // Test if src matches regular expression
|
|
463
|
-
) {
|
|
464
|
-
continue;
|
|
465
|
-
}
|
|
466
|
-
// Replace lazy loading image with immediately loading image
|
|
467
|
-
const newImage = document.createElement('img');
|
|
468
|
-
Array.from(image.attributes).forEach((attr) => {
|
|
469
|
-
if (attr.name !== 'loading' && attr.name !== 'src') {
|
|
470
|
-
newImage.setAttribute(attr.name, attr.value);
|
|
471
|
-
}
|
|
472
|
-
});
|
|
473
|
-
image.replaceWith(newImage);
|
|
474
|
-
// Wait for laoding
|
|
475
|
-
promises.push(this.loadImage(newImage, src));
|
|
476
|
-
}
|
|
477
|
-
if (config.timeout) {
|
|
478
|
-
timeoutId = setTimeout(() => __awaiter(this, void 0, void 0, function* () {
|
|
479
|
-
resolved = true;
|
|
480
|
-
if (config.doneFunnction) {
|
|
481
|
-
yield config.doneFunction();
|
|
482
|
-
}
|
|
483
|
-
resolve(undefined);
|
|
484
|
-
}));
|
|
485
|
-
}
|
|
486
|
-
// Wait until all images loaded
|
|
487
|
-
Promise.all(promises)
|
|
488
|
-
.catch((e) => console.error('Error during image loading', e))
|
|
489
|
-
.finally(() => __awaiter(this, void 0, void 0, function* () {
|
|
490
|
-
// Check if already resolved
|
|
491
|
-
if (resolved) {
|
|
492
|
-
return;
|
|
493
|
-
}
|
|
494
|
-
// Stop timeout
|
|
495
|
-
if (timeoutId) {
|
|
496
|
-
clearTimeout(timeoutId);
|
|
497
|
-
}
|
|
498
|
-
// Return result
|
|
499
|
-
let result;
|
|
500
|
-
if (config.doneFunnction) {
|
|
501
|
-
result = yield config.doneFunction();
|
|
502
|
-
}
|
|
503
|
-
resolve(result);
|
|
504
|
-
}));
|
|
505
|
-
});
|
|
506
|
-
}
|
|
507
|
-
/**
|
|
508
|
-
* Load image for image element
|
|
509
|
-
*
|
|
510
|
-
* @param imageElement
|
|
511
|
-
* @param src
|
|
512
|
-
* @protected
|
|
513
|
-
*/
|
|
514
|
-
loadImage(imageElement, src) {
|
|
515
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
516
|
-
src = src || imageElement.src;
|
|
517
|
-
return new Promise((resolve, reject) => {
|
|
518
|
-
imageElement.onload = () => resolve(imageElement);
|
|
519
|
-
imageElement.onerror = reject;
|
|
520
|
-
imageElement.src = src;
|
|
521
|
-
});
|
|
522
|
-
});
|
|
523
|
-
}
|
|
524
|
-
}
|
|
525
|
-
ImageService.ɵprov = i0.ɵɵdefineInjectable({ factory: function ImageService_Factory() { return new ImageService(); }, token: ImageService, providedIn: "root" });
|
|
526
|
-
ImageService.decorators = [
|
|
527
|
-
{ type: Injectable, args: [{
|
|
528
|
-
providedIn: 'root',
|
|
529
|
-
},] }
|
|
530
|
-
];
|
|
531
|
-
|
|
532
|
-
/**
|
|
533
|
-
* Set same height (maximum) to different elements
|
|
534
|
-
*/
|
|
535
|
-
class MatchHeightDirective {
|
|
536
|
-
constructor(el, imageService, zone) {
|
|
537
|
-
this.el = el;
|
|
538
|
-
this.imageService = imageService;
|
|
539
|
-
this.zone = zone;
|
|
540
|
-
this.loadLazyImages = true;
|
|
541
|
-
}
|
|
542
|
-
onResize() {
|
|
543
|
-
this.matchHeight(this.el.nativeElement, this.ltMatchHeight);
|
|
544
|
-
}
|
|
545
|
-
ngAfterViewChecked() {
|
|
546
|
-
this.matchHeight(this.el.nativeElement, this.ltMatchHeight);
|
|
547
|
-
}
|
|
548
|
-
matchHeight(parent, target) {
|
|
549
|
-
// Timeout is set to force Angular to wait for all actions and only continue once the process has run through.
|
|
550
|
-
// Otherwise, an infinite loop will occur.
|
|
551
|
-
setTimeout(() => __awaiter(this, void 0, void 0, function* () {
|
|
552
|
-
if (!parent) {
|
|
553
|
-
return;
|
|
554
|
-
}
|
|
555
|
-
let classNames;
|
|
556
|
-
if (!Array.isArray(target)) {
|
|
557
|
-
classNames = [target];
|
|
558
|
-
}
|
|
559
|
-
else {
|
|
560
|
-
classNames = target;
|
|
561
|
-
}
|
|
562
|
-
for (const className of classNames) {
|
|
563
|
-
// find all child structureElements with the selected class name
|
|
564
|
-
const children = parent.getElementsByClassName(className);
|
|
565
|
-
if (!children || children.length < 2) {
|
|
566
|
-
continue;
|
|
567
|
-
}
|
|
568
|
-
// Load images of children
|
|
569
|
-
if (this.loadLazyImages) {
|
|
570
|
-
yield this.imageService.preLoadImages({ elements: children });
|
|
571
|
-
}
|
|
572
|
-
// reset all children height
|
|
573
|
-
Array.from(children).forEach((element) => {
|
|
574
|
-
element.style.height = 'initial';
|
|
575
|
-
});
|
|
576
|
-
// get all the child structureElements heights
|
|
577
|
-
const itemHeights = Array.from(children).map((x) => x.getBoundingClientRect().height);
|
|
578
|
-
// find out the tallest one
|
|
579
|
-
const maxHeight = itemHeights.reduce((prev, curr) => (curr > prev ? curr : prev), 0);
|
|
580
|
-
// update the child structureElements height to the tallest one
|
|
581
|
-
Array.from(children).forEach((element) => (element.style.height = `${maxHeight}px`));
|
|
582
|
-
}
|
|
583
|
-
}), 1);
|
|
584
|
-
}
|
|
585
|
-
}
|
|
586
|
-
MatchHeightDirective.decorators = [
|
|
587
|
-
{ type: Directive, args: [{
|
|
588
|
-
selector: '[ltMatchHeight]',
|
|
589
|
-
},] }
|
|
590
|
-
];
|
|
591
|
-
MatchHeightDirective.ctorParameters = () => [
|
|
592
|
-
{ type: ElementRef },
|
|
593
|
-
{ type: ImageService },
|
|
594
|
-
{ type: NgZone }
|
|
595
|
-
];
|
|
596
|
-
MatchHeightDirective.propDecorators = {
|
|
597
|
-
ltMatchHeight: [{ type: Input }],
|
|
598
|
-
loadLazyImages: [{ type: Input }],
|
|
599
|
-
onResize: [{ type: HostListener, args: ['window:resize',] }]
|
|
600
|
-
};
|
|
601
|
-
|
|
602
|
-
/**
|
|
603
|
-
* Reszise detection
|
|
604
|
-
* (inpsired by: https://stackblitz.com/edit/angular-resizable)
|
|
605
|
-
*/
|
|
606
|
-
class ResizableDirective {
|
|
607
|
-
constructor(el) {
|
|
608
|
-
this.el = el;
|
|
609
|
-
this.resizableGrabWidth = 8;
|
|
610
|
-
this.resizableMinWidth = 10;
|
|
611
|
-
this.dragging = false;
|
|
612
|
-
}
|
|
613
|
-
ngOnInit() {
|
|
614
|
-
this.addListenerToDocument();
|
|
615
|
-
this.addListenerToElement();
|
|
616
|
-
}
|
|
617
|
-
mouseMoveG(evt) {
|
|
618
|
-
if (!this.dragging) {
|
|
619
|
-
return;
|
|
620
|
-
}
|
|
621
|
-
this.newWidth(evt.clientX - this.el.nativeElement.offsetLeft);
|
|
622
|
-
evt.stopPropagation();
|
|
623
|
-
}
|
|
624
|
-
newWidth(wid) {
|
|
625
|
-
const result = Math.max(this.resizableMinWidth, wid);
|
|
626
|
-
this.el.nativeElement.style.width = result + 'px';
|
|
627
|
-
}
|
|
628
|
-
mouseDown(evt) {
|
|
629
|
-
if (this.inDragRegion(evt)) {
|
|
630
|
-
this.dragging = true;
|
|
631
|
-
this.preventGlobalMouseEvents();
|
|
632
|
-
evt.stopPropagation();
|
|
633
|
-
}
|
|
634
|
-
}
|
|
635
|
-
restoreGlobalMouseEvents() {
|
|
636
|
-
document.body.style['pointer-events'] = 'auto';
|
|
637
|
-
}
|
|
638
|
-
mouseUpG(evt) {
|
|
639
|
-
if (!this.dragging) {
|
|
640
|
-
return;
|
|
641
|
-
}
|
|
642
|
-
this.restoreGlobalMouseEvents();
|
|
643
|
-
this.dragging = false;
|
|
644
|
-
evt.stopPropagation();
|
|
645
|
-
}
|
|
646
|
-
mouseMove(evt) {
|
|
647
|
-
if (this.inDragRegion(evt) || this.dragging) {
|
|
648
|
-
this.el.nativeElement.style.cursor = 'col-resize';
|
|
649
|
-
}
|
|
650
|
-
else {
|
|
651
|
-
this.el.nativeElement.style.cursor = 'default';
|
|
652
|
-
}
|
|
653
|
-
}
|
|
654
|
-
preventGlobalMouseEvents() {
|
|
655
|
-
document.body.style['pointer-events'] = 'none';
|
|
656
|
-
}
|
|
657
|
-
inDragRegion(evt) {
|
|
658
|
-
return this.el.nativeElement.clientWidth - evt.clientX + this.el.nativeElement.offsetLeft < this.resizableGrabWidth;
|
|
659
|
-
}
|
|
660
|
-
addListenerToDocument() {
|
|
661
|
-
document.addEventListener('mousemove', (e) => {
|
|
662
|
-
this.mouseMoveG(e);
|
|
663
|
-
}, true);
|
|
664
|
-
document.addEventListener('mouseup', (e) => {
|
|
665
|
-
this.mouseUpG(e);
|
|
666
|
-
}, true);
|
|
667
|
-
}
|
|
668
|
-
addListenerToElement() {
|
|
669
|
-
this.el.nativeElement.addEventListener('mousedown', (e) => {
|
|
670
|
-
this.mouseDown(e);
|
|
671
|
-
}, true);
|
|
672
|
-
this.el.nativeElement.addEventListener('mousemove', (e) => {
|
|
673
|
-
this.mouseMove(e);
|
|
674
|
-
}, true);
|
|
675
|
-
}
|
|
676
|
-
}
|
|
677
|
-
ResizableDirective.decorators = [
|
|
678
|
-
{ type: Directive, args: [{
|
|
679
|
-
selector: '[ltResizable]',
|
|
680
|
-
},] }
|
|
681
|
-
];
|
|
682
|
-
ResizableDirective.ctorParameters = () => [
|
|
683
|
-
{ type: ElementRef }
|
|
684
|
-
];
|
|
685
|
-
ResizableDirective.propDecorators = {
|
|
686
|
-
resizableGrabWidth: [{ type: Input }],
|
|
687
|
-
resizableMinWidth: [{ type: Input }]
|
|
688
|
-
};
|
|
689
|
-
|
|
690
|
-
/**
|
|
691
|
-
* Truncate string with ellipses
|
|
692
|
-
*/
|
|
693
|
-
class EllipsesPipe {
|
|
694
|
-
transform(value, limit) {
|
|
695
|
-
if (!value) {
|
|
696
|
-
return null;
|
|
697
|
-
}
|
|
698
|
-
return value.length > limit ? value.substring(0, limit) + '...' : value;
|
|
699
|
-
}
|
|
700
|
-
}
|
|
701
|
-
EllipsesPipe.decorators = [
|
|
702
|
-
{ type: Pipe, args: [{
|
|
703
|
-
name: 'ltEllipses',
|
|
704
|
-
},] }
|
|
705
|
-
];
|
|
706
|
-
|
|
707
|
-
/**
|
|
708
|
-
* Declarate html as safe
|
|
709
|
-
*/
|
|
710
|
-
class SafeHtmlPipe {
|
|
711
|
-
constructor(sanitized) {
|
|
712
|
-
this.sanitized = sanitized;
|
|
713
|
-
}
|
|
714
|
-
transform(value) {
|
|
715
|
-
return this.sanitized.bypassSecurityTrustHtml(value);
|
|
716
|
-
}
|
|
717
|
-
}
|
|
718
|
-
SafeHtmlPipe.decorators = [
|
|
719
|
-
{ type: Pipe, args: [{ name: 'ltSafeHtml' },] }
|
|
720
|
-
];
|
|
721
|
-
SafeHtmlPipe.ctorParameters = () => [
|
|
722
|
-
{ type: DomSanitizer }
|
|
723
|
-
];
|
|
724
|
-
|
|
725
|
-
// Imported and exported elements
|
|
726
|
-
const elements = [
|
|
727
|
-
// Directives
|
|
728
|
-
ContextMenuDirective,
|
|
729
|
-
LazyLoadDirective,
|
|
730
|
-
MatchHeightDirective,
|
|
731
|
-
ResizableDirective,
|
|
732
|
-
// Pipes
|
|
733
|
-
EllipsesPipe,
|
|
734
|
-
SafeHtmlPipe,
|
|
735
|
-
];
|
|
736
|
-
/**
|
|
737
|
-
* Base module
|
|
738
|
-
*/
|
|
739
|
-
class BaseModule {
|
|
740
|
-
/**
|
|
741
|
-
* Set configuration of base module in root module of the app
|
|
742
|
-
*/
|
|
743
|
-
static forRoot(baseModuleConfig = {}) {
|
|
744
|
-
// Default config
|
|
745
|
-
const config = Object.assign({ apiUrl: 'localhost:3000', authGuardRedirectUrl: '/auth', logging: false, version: null, prefix: null, scrollDetectionOffset: 200, scrollOffset: 100, storageType: 'local' }, baseModuleConfig);
|
|
746
|
-
// Prepare providers
|
|
747
|
-
const providers = [
|
|
748
|
-
{
|
|
749
|
-
provide: BASE_MODULE_CONFIG,
|
|
750
|
-
useValue: baseModuleConfig,
|
|
751
|
-
},
|
|
752
|
-
];
|
|
753
|
-
// Add apollo features if API URL is set
|
|
754
|
-
if (baseModuleConfig.apiUrl) {
|
|
755
|
-
providers.push({
|
|
756
|
-
provide: APOLLO_OPTIONS,
|
|
757
|
-
useFactory: apolloOptionsFactory,
|
|
758
|
-
deps: [BASE_MODULE_CONFIG, HttpLink, AuthService],
|
|
759
|
-
});
|
|
760
|
-
}
|
|
761
|
-
else if (config.logging) {
|
|
762
|
-
console.log('apiUrl is missing, ApolloLink is not initialized');
|
|
763
|
-
}
|
|
764
|
-
// Return root module
|
|
765
|
-
return {
|
|
766
|
-
ngModule: BaseModule,
|
|
767
|
-
providers,
|
|
768
|
-
};
|
|
769
|
-
}
|
|
770
|
-
}
|
|
771
|
-
BaseModule.decorators = [
|
|
772
|
-
{ type: NgModule, args: [{
|
|
773
|
-
declarations: elements,
|
|
774
|
-
exports: elements,
|
|
775
|
-
},] }
|
|
776
|
-
];
|
|
777
|
-
|
|
778
423
|
/**
|
|
779
424
|
* Helper class
|
|
780
425
|
*/
|
|
@@ -856,196 +501,589 @@ class Helper {
|
|
|
856
501
|
}
|
|
857
502
|
}
|
|
858
503
|
}
|
|
859
|
-
// Return target
|
|
860
|
-
return target;
|
|
504
|
+
// Return target
|
|
505
|
+
return target;
|
|
506
|
+
}
|
|
507
|
+
/**
|
|
508
|
+
* Create Object or Objects of specified type with specified data
|
|
509
|
+
*/
|
|
510
|
+
static maps(data, targetClass) {
|
|
511
|
+
// Check data
|
|
512
|
+
if (!data || typeof data !== 'object') {
|
|
513
|
+
return undefined;
|
|
514
|
+
}
|
|
515
|
+
// Check array
|
|
516
|
+
if (!Array.isArray(data)) {
|
|
517
|
+
data = [data];
|
|
518
|
+
}
|
|
519
|
+
// Map
|
|
520
|
+
return data.map((item) => {
|
|
521
|
+
return targetClass.map(item);
|
|
522
|
+
});
|
|
523
|
+
}
|
|
524
|
+
/**
|
|
525
|
+
* Get plain parameter
|
|
526
|
+
*/
|
|
527
|
+
static getPlainParameter(parameter) {
|
|
528
|
+
var _a, _b, _c;
|
|
529
|
+
if (!parameter) {
|
|
530
|
+
return parameter;
|
|
531
|
+
}
|
|
532
|
+
return (_c = (_b = (_a = parameter === null || parameter === void 0 ? void 0 : parameter.split('?')) === null || _a === void 0 ? void 0 : _a.shift()) === null || _b === void 0 ? void 0 : _b.split('#')) === null || _c === void 0 ? void 0 : _c.shift();
|
|
533
|
+
}
|
|
534
|
+
/**
|
|
535
|
+
* Get ID of an url parameter
|
|
536
|
+
*/
|
|
537
|
+
static getParameterId(parameter) {
|
|
538
|
+
var _a;
|
|
539
|
+
if (!parameter) {
|
|
540
|
+
return parameter;
|
|
541
|
+
}
|
|
542
|
+
return (_a = Helper.getPlainParameter(parameter)) === null || _a === void 0 ? void 0 : _a.split('-').pop();
|
|
543
|
+
}
|
|
544
|
+
/**
|
|
545
|
+
* Delay
|
|
546
|
+
*/
|
|
547
|
+
static delay(ms) {
|
|
548
|
+
const promise = new Promise((resolve) => setTimeout(resolve, ms));
|
|
549
|
+
return promise;
|
|
550
|
+
}
|
|
551
|
+
/**
|
|
552
|
+
* Deep freeze
|
|
553
|
+
* See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze#What_is_shallow_freeze
|
|
554
|
+
*/
|
|
555
|
+
static deepFreeze(object, preparedObjects = []) {
|
|
556
|
+
// Prevent infinit regress
|
|
557
|
+
if (preparedObjects.includes(object)) {
|
|
558
|
+
return object;
|
|
559
|
+
}
|
|
560
|
+
preparedObjects.push(object);
|
|
561
|
+
// Retrieve the property names defined on object
|
|
562
|
+
const propNames = Object.getOwnPropertyNames(object);
|
|
563
|
+
// Freeze properties before freezing self
|
|
564
|
+
for (const name of propNames) {
|
|
565
|
+
const value = object[name];
|
|
566
|
+
if (value && typeof value === 'object') {
|
|
567
|
+
Helper.deepFreeze(value, preparedObjects);
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
return Object.freeze(object);
|
|
571
|
+
}
|
|
572
|
+
/**
|
|
573
|
+
* Generates an unique identifier with 24 characters
|
|
574
|
+
*/
|
|
575
|
+
static getUID() {
|
|
576
|
+
let dt = new Date().getTime();
|
|
577
|
+
const uuid = 'xxxxxxxxxxxxxxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
|
|
578
|
+
// eslint-disable-next-line no-bitwise
|
|
579
|
+
const r = (dt + Math.random() * 16) % 16 | 0;
|
|
580
|
+
dt = Math.floor(dt / 16);
|
|
581
|
+
// eslint-disable-next-line no-bitwise
|
|
582
|
+
return (c === 'x' ? r : (r & 0x3) | 0x8).toString(16);
|
|
583
|
+
});
|
|
584
|
+
return uuid;
|
|
585
|
+
}
|
|
586
|
+
/**
|
|
587
|
+
* Parse date string to date object
|
|
588
|
+
*/
|
|
589
|
+
static parseDate(dateString) {
|
|
590
|
+
const reISO = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*))(?:Z|(\+|-)([\d|:]*))?$/;
|
|
591
|
+
const reMsAjax = /^\/Date\((d|-|.*)\)[\/|\\]$/;
|
|
592
|
+
if (typeof dateString === 'string') {
|
|
593
|
+
const isoExec = reISO.exec(dateString);
|
|
594
|
+
if (isoExec) {
|
|
595
|
+
return new Date(dateString);
|
|
596
|
+
}
|
|
597
|
+
const msAjaxExec = reMsAjax.exec(dateString);
|
|
598
|
+
if (msAjaxExec) {
|
|
599
|
+
const cleaned = msAjaxExec[1].split(/[-+,.]/);
|
|
600
|
+
return new Date(cleaned[0] ? +cleaned[0] : 0 - +cleaned[1]);
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
return dateString;
|
|
604
|
+
}
|
|
605
|
+
/**
|
|
606
|
+
* Get browser name and version
|
|
607
|
+
*/
|
|
608
|
+
static getBrowser() {
|
|
609
|
+
const userAgent = navigator.userAgent;
|
|
610
|
+
let data = userAgent.match(/(opera|chrome|safari|firefox|msie|trident(?=\/))\/?\s*(\d+)/i) || [];
|
|
611
|
+
let version;
|
|
612
|
+
if (/trident/i.test(data[1])) {
|
|
613
|
+
version = /\brv[ :]+(\d+)/g.exec(userAgent) || [];
|
|
614
|
+
return { name: 'IE', version: version[1] || '' };
|
|
615
|
+
}
|
|
616
|
+
if (data[1] === 'Chrome') {
|
|
617
|
+
version = userAgent.match(/\bOPR|Edge\/(\d+)/);
|
|
618
|
+
if (version != null) {
|
|
619
|
+
return { name: 'Opera', version: version[1] };
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
data = data[2] ? [data[1], data[2]] : [navigator.appName, navigator.appVersion, '-?'];
|
|
623
|
+
version = userAgent.match(/version\/(\d+)/i);
|
|
624
|
+
if (version !== null) {
|
|
625
|
+
data.splice(1, 1, version[1]);
|
|
626
|
+
}
|
|
627
|
+
return {
|
|
628
|
+
name: data[0],
|
|
629
|
+
version: data[1],
|
|
630
|
+
};
|
|
631
|
+
}
|
|
632
|
+
/**
|
|
633
|
+
* Whether first parameter is a deep subset of second parameter
|
|
634
|
+
* Hint: functions will be ignored
|
|
635
|
+
*/
|
|
636
|
+
static isSubset(a, b) {
|
|
637
|
+
// Equal
|
|
638
|
+
if (a === b) {
|
|
639
|
+
return true;
|
|
640
|
+
}
|
|
641
|
+
// Different type
|
|
642
|
+
if (typeof a !== typeof b) {
|
|
643
|
+
return false;
|
|
644
|
+
}
|
|
645
|
+
// Process array
|
|
646
|
+
if (Array.isArray(a)) {
|
|
647
|
+
for (const [key, value] of Object.entries(a)) {
|
|
648
|
+
if (Helper.isSubset(value, b[key])) {
|
|
649
|
+
return false;
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
return true;
|
|
653
|
+
}
|
|
654
|
+
// Process object
|
|
655
|
+
if (typeof a === 'object') {
|
|
656
|
+
const plain = JSON.parse(JSON.stringify(a));
|
|
657
|
+
for (const [key, value] of Object.entries(plain)) {
|
|
658
|
+
if (Helper.isSubset(value, b[key])) {
|
|
659
|
+
return false;
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
return true;
|
|
663
|
+
}
|
|
664
|
+
// Else
|
|
665
|
+
return true;
|
|
861
666
|
}
|
|
862
667
|
/**
|
|
863
|
-
*
|
|
668
|
+
* Whether parameters are equal (have equal properties)
|
|
669
|
+
* Hint: functions will be ignored
|
|
864
670
|
*/
|
|
865
|
-
static
|
|
866
|
-
|
|
867
|
-
if (!data || typeof data !== 'object') {
|
|
868
|
-
return undefined;
|
|
869
|
-
}
|
|
870
|
-
// Check array
|
|
871
|
-
if (!Array.isArray(data)) {
|
|
872
|
-
data = [data];
|
|
873
|
-
}
|
|
874
|
-
// Map
|
|
875
|
-
return data.map((item) => {
|
|
876
|
-
return targetClass.map(item);
|
|
877
|
-
});
|
|
671
|
+
static isEqual(a, b) {
|
|
672
|
+
return Helper.isSubset(a, b) && Helper.isSubset(b, a);
|
|
878
673
|
}
|
|
879
674
|
/**
|
|
880
|
-
*
|
|
675
|
+
* First level difference of two objects
|
|
676
|
+
* Hint: functions will be ignored and when an array or an object is different the hole array or object will used as property value
|
|
677
|
+
*
|
|
678
|
+
* @returns Record<string, any> Object with properties from first object
|
|
881
679
|
*/
|
|
882
|
-
static
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
680
|
+
static getDiff(a, b, clone = true) {
|
|
681
|
+
const result = {};
|
|
682
|
+
let firstObject = a;
|
|
683
|
+
if (clone) {
|
|
684
|
+
firstObject = JSON.parse(JSON.stringify(a));
|
|
886
685
|
}
|
|
887
|
-
|
|
686
|
+
for (const [key, value] of Object.entries(firstObject)) {
|
|
687
|
+
if (!Helper.isSubset(value, b[key])) {
|
|
688
|
+
result[key] = value;
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
return result;
|
|
888
692
|
}
|
|
889
693
|
/**
|
|
890
|
-
*
|
|
694
|
+
* Check if propertie is type of HTMLCollection or NodeList
|
|
695
|
+
* See https://stackoverflow.com/a/7238344
|
|
696
|
+
*
|
|
697
|
+
* @param nodes
|
|
891
698
|
*/
|
|
892
|
-
static
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
return
|
|
699
|
+
static isNodeList(nodes) {
|
|
700
|
+
try {
|
|
701
|
+
const stringRepr = Object.prototype.toString.call(nodes);
|
|
702
|
+
return (typeof nodes === 'object' &&
|
|
703
|
+
/^\[object (HTMLCollection|NodeList|Object)\]$/.test(stringRepr) &&
|
|
704
|
+
typeof nodes.length === 'number' &&
|
|
705
|
+
(nodes.length === 0 || (typeof nodes[0] === 'object' && nodes[0].nodeType > 0)));
|
|
706
|
+
}
|
|
707
|
+
catch (e) {
|
|
708
|
+
return false;
|
|
896
709
|
}
|
|
897
|
-
return (_a = Helper.getPlainParameter(parameter)) === null || _a === void 0 ? void 0 : _a.split('-').pop();
|
|
898
710
|
}
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
/**
|
|
714
|
+
* Image service
|
|
715
|
+
*/
|
|
716
|
+
class ImageService {
|
|
899
717
|
/**
|
|
900
|
-
*
|
|
718
|
+
* Preaload images (for lazy handling)
|
|
719
|
+
*
|
|
720
|
+
* @param options
|
|
721
|
+
* @protected
|
|
901
722
|
*/
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
723
|
+
preLoadImages(options) {
|
|
724
|
+
// Init configuration
|
|
725
|
+
const config = Object.assign({ doneFunnction: undefined, elements: document, regExp: undefined, timeout: undefined }, options);
|
|
726
|
+
return new Promise((resolve) => {
|
|
727
|
+
var _a;
|
|
728
|
+
// Init variables
|
|
729
|
+
let resolved = false;
|
|
730
|
+
let timeoutId;
|
|
731
|
+
// Convert element(s) into array
|
|
732
|
+
if (!Array.isArray(config.elements)) {
|
|
733
|
+
// NodeList or HTMLCollection
|
|
734
|
+
if (Helper.isNodeList(config.elements)) {
|
|
735
|
+
config.elements = Array.from(config.elements);
|
|
736
|
+
}
|
|
737
|
+
// Single element
|
|
738
|
+
else {
|
|
739
|
+
config.elements = [config.elements];
|
|
740
|
+
}
|
|
741
|
+
}
|
|
742
|
+
// Init loading
|
|
743
|
+
const promises = [];
|
|
744
|
+
// Get all images
|
|
745
|
+
let images = [];
|
|
746
|
+
config.elements.forEach((element) => {
|
|
747
|
+
images = images.concat(Array.from(element.getElementsByTagName('img')));
|
|
748
|
+
});
|
|
749
|
+
// Prepare images
|
|
750
|
+
for (const image of images) {
|
|
751
|
+
const src = image.getAttribute('src');
|
|
752
|
+
// Check if changes are necessary and possible
|
|
753
|
+
if ((image.complete && image.naturalHeight !== 0) || // already laoded
|
|
754
|
+
image.getAttribute('loading') !== 'lazy' || // loading attribute !== lazy
|
|
755
|
+
!src || // Image has no src
|
|
756
|
+
((_a = config.regExp) === null || _a === void 0 ? void 0 : _a.test(src)) // Test if src matches regular expression
|
|
757
|
+
) {
|
|
758
|
+
continue;
|
|
759
|
+
}
|
|
760
|
+
// Replace lazy loading image with immediately loading image
|
|
761
|
+
const newImage = document.createElement('img');
|
|
762
|
+
Array.from(image.attributes).forEach((attr) => {
|
|
763
|
+
if (attr.name !== 'loading' && attr.name !== 'src') {
|
|
764
|
+
newImage.setAttribute(attr.name, attr.value);
|
|
765
|
+
}
|
|
766
|
+
});
|
|
767
|
+
image.replaceWith(newImage);
|
|
768
|
+
// Wait for laoding
|
|
769
|
+
promises.push(this.loadImage(newImage, src));
|
|
770
|
+
}
|
|
771
|
+
if (config.timeout) {
|
|
772
|
+
timeoutId = setTimeout(() => __awaiter(this, void 0, void 0, function* () {
|
|
773
|
+
resolved = true;
|
|
774
|
+
if (config.doneFunnction) {
|
|
775
|
+
yield config.doneFunction();
|
|
776
|
+
}
|
|
777
|
+
resolve(undefined);
|
|
778
|
+
}));
|
|
779
|
+
}
|
|
780
|
+
// Wait until all images loaded
|
|
781
|
+
Promise.all(promises)
|
|
782
|
+
.catch((e) => console.error('Error during image loading', e))
|
|
783
|
+
.finally(() => __awaiter(this, void 0, void 0, function* () {
|
|
784
|
+
// Check if already resolved
|
|
785
|
+
if (resolved) {
|
|
786
|
+
return;
|
|
787
|
+
}
|
|
788
|
+
// Stop timeout
|
|
789
|
+
if (timeoutId) {
|
|
790
|
+
clearTimeout(timeoutId);
|
|
791
|
+
}
|
|
792
|
+
// Return result
|
|
793
|
+
let result;
|
|
794
|
+
if (config.doneFunnction) {
|
|
795
|
+
result = yield config.doneFunction();
|
|
796
|
+
}
|
|
797
|
+
resolve(result);
|
|
798
|
+
}));
|
|
799
|
+
});
|
|
905
800
|
}
|
|
906
801
|
/**
|
|
907
|
-
*
|
|
908
|
-
*
|
|
802
|
+
* Load image for image element
|
|
803
|
+
*
|
|
804
|
+
* @param imageElement
|
|
805
|
+
* @param src
|
|
806
|
+
* @protected
|
|
909
807
|
*/
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
return
|
|
808
|
+
loadImage(imageElement, src) {
|
|
809
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
810
|
+
src = src || imageElement.src;
|
|
811
|
+
return new Promise((resolve, reject) => {
|
|
812
|
+
imageElement.onload = () => resolve(imageElement);
|
|
813
|
+
imageElement.onerror = reject;
|
|
814
|
+
imageElement.src = src;
|
|
815
|
+
});
|
|
816
|
+
});
|
|
817
|
+
}
|
|
818
|
+
}
|
|
819
|
+
ImageService.ɵprov = i0.ɵɵdefineInjectable({ factory: function ImageService_Factory() { return new ImageService(); }, token: ImageService, providedIn: "root" });
|
|
820
|
+
ImageService.decorators = [
|
|
821
|
+
{ type: Injectable, args: [{
|
|
822
|
+
providedIn: 'root',
|
|
823
|
+
},] }
|
|
824
|
+
];
|
|
825
|
+
|
|
826
|
+
/**
|
|
827
|
+
* Set same height (maximum) to different elements
|
|
828
|
+
*/
|
|
829
|
+
class MatchHeightDirective {
|
|
830
|
+
constructor(el, imageService, platformId) {
|
|
831
|
+
this.el = el;
|
|
832
|
+
this.imageService = imageService;
|
|
833
|
+
// Replace lazy loading images with immediate loading images
|
|
834
|
+
this.loadLazyImages = true;
|
|
835
|
+
this.isBrowser = isPlatformBrowser(platformId);
|
|
836
|
+
}
|
|
837
|
+
onResize() {
|
|
838
|
+
this.matchHeight(this.el.nativeElement, this.ltMatchHeight);
|
|
839
|
+
}
|
|
840
|
+
ngAfterViewChecked() {
|
|
841
|
+
this.matchHeight(this.el.nativeElement, this.ltMatchHeight);
|
|
842
|
+
}
|
|
843
|
+
matchHeight(parent, target) {
|
|
844
|
+
if (this.isBrowser) {
|
|
845
|
+
// Timeout is set to force Angular to wait for all actions and only continue once the process has run through.
|
|
846
|
+
// Otherwise, an infinite loop will occur.
|
|
847
|
+
setTimeout(() => {
|
|
848
|
+
this.matchHeightHelper(parent, target);
|
|
849
|
+
}, 1);
|
|
914
850
|
}
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
const propNames = Object.getOwnPropertyNames(object);
|
|
918
|
-
// Freeze properties before freezing self
|
|
919
|
-
for (const name of propNames) {
|
|
920
|
-
const value = object[name];
|
|
921
|
-
if (value && typeof value === 'object') {
|
|
922
|
-
Helper.deepFreeze(value, preparedObjects);
|
|
923
|
-
}
|
|
851
|
+
else {
|
|
852
|
+
this.matchHeightHelper(parent, target);
|
|
924
853
|
}
|
|
925
|
-
return Object.freeze(object);
|
|
926
854
|
}
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
855
|
+
matchHeightHelper(parent, target) {
|
|
856
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
857
|
+
if (!parent) {
|
|
858
|
+
return;
|
|
859
|
+
}
|
|
860
|
+
let classNames;
|
|
861
|
+
if (!Array.isArray(target)) {
|
|
862
|
+
classNames = [target];
|
|
863
|
+
}
|
|
864
|
+
else {
|
|
865
|
+
classNames = target;
|
|
866
|
+
}
|
|
867
|
+
for (const className of classNames) {
|
|
868
|
+
// find all child structureElements with the selected class name
|
|
869
|
+
const children = parent.getElementsByClassName(className);
|
|
870
|
+
if (!children || children.length < 2) {
|
|
871
|
+
continue;
|
|
872
|
+
}
|
|
873
|
+
// Load images of children
|
|
874
|
+
if (this.loadLazyImages) {
|
|
875
|
+
yield this.imageService.preLoadImages({ elements: children });
|
|
876
|
+
}
|
|
877
|
+
// reset all children height
|
|
878
|
+
Array.from(children).forEach((element) => {
|
|
879
|
+
element.style.height = 'initial';
|
|
880
|
+
});
|
|
881
|
+
// get all the child structureElements heights
|
|
882
|
+
const itemHeights = Array.from(children).map((element) => {
|
|
883
|
+
if (element.getBoundingClientRect) {
|
|
884
|
+
return element.getBoundingClientRect().height;
|
|
885
|
+
}
|
|
886
|
+
return 0;
|
|
887
|
+
});
|
|
888
|
+
// find out the tallest one
|
|
889
|
+
const maxHeight = itemHeights.reduce((prev, curr) => (curr > prev ? curr : prev), 0);
|
|
890
|
+
// update the child structureElements height to the tallest one
|
|
891
|
+
Array.from(children).forEach((element) => (element.style.height = `${maxHeight}px`));
|
|
892
|
+
}
|
|
893
|
+
});
|
|
894
|
+
}
|
|
895
|
+
}
|
|
896
|
+
MatchHeightDirective.decorators = [
|
|
897
|
+
{ type: Directive, args: [{
|
|
898
|
+
selector: '[ltMatchHeight]',
|
|
899
|
+
},] }
|
|
900
|
+
];
|
|
901
|
+
MatchHeightDirective.ctorParameters = () => [
|
|
902
|
+
{ type: ElementRef },
|
|
903
|
+
{ type: ImageService },
|
|
904
|
+
{ type: String, decorators: [{ type: Inject, args: [PLATFORM_ID,] }] }
|
|
905
|
+
];
|
|
906
|
+
MatchHeightDirective.propDecorators = {
|
|
907
|
+
ltMatchHeight: [{ type: Input }],
|
|
908
|
+
loadLazyImages: [{ type: Input }],
|
|
909
|
+
onResize: [{ type: HostListener, args: ['window:resize',] }]
|
|
910
|
+
};
|
|
911
|
+
|
|
912
|
+
/**
|
|
913
|
+
* Reszise detection
|
|
914
|
+
* (inpsired by: https://stackblitz.com/edit/angular-resizable)
|
|
915
|
+
*/
|
|
916
|
+
class ResizableDirective {
|
|
917
|
+
constructor(el) {
|
|
918
|
+
this.el = el;
|
|
919
|
+
this.resizableGrabWidth = 8;
|
|
920
|
+
this.resizableMinWidth = 10;
|
|
921
|
+
this.dragging = false;
|
|
922
|
+
}
|
|
923
|
+
ngOnInit() {
|
|
924
|
+
this.addListenerToDocument();
|
|
925
|
+
this.addListenerToElement();
|
|
940
926
|
}
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
static parseDate(dateString) {
|
|
945
|
-
const reISO = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*))(?:Z|(\+|-)([\d|:]*))?$/;
|
|
946
|
-
const reMsAjax = /^\/Date\((d|-|.*)\)[\/|\\]$/;
|
|
947
|
-
if (typeof dateString === 'string') {
|
|
948
|
-
const isoExec = reISO.exec(dateString);
|
|
949
|
-
if (isoExec) {
|
|
950
|
-
return new Date(dateString);
|
|
951
|
-
}
|
|
952
|
-
const msAjaxExec = reMsAjax.exec(dateString);
|
|
953
|
-
if (msAjaxExec) {
|
|
954
|
-
const cleaned = msAjaxExec[1].split(/[-+,.]/);
|
|
955
|
-
return new Date(cleaned[0] ? +cleaned[0] : 0 - +cleaned[1]);
|
|
956
|
-
}
|
|
927
|
+
mouseMoveG(evt) {
|
|
928
|
+
if (!this.dragging) {
|
|
929
|
+
return;
|
|
957
930
|
}
|
|
958
|
-
|
|
931
|
+
this.newWidth(evt.clientX - this.el.nativeElement.offsetLeft);
|
|
932
|
+
evt.stopPropagation();
|
|
959
933
|
}
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
return { name: 'IE', version: version[1] || '' };
|
|
970
|
-
}
|
|
971
|
-
if (data[1] === 'Chrome') {
|
|
972
|
-
version = userAgent.match(/\bOPR|Edge\/(\d+)/);
|
|
973
|
-
if (version != null) {
|
|
974
|
-
return { name: 'Opera', version: version[1] };
|
|
975
|
-
}
|
|
976
|
-
}
|
|
977
|
-
data = data[2] ? [data[1], data[2]] : [navigator.appName, navigator.appVersion, '-?'];
|
|
978
|
-
version = userAgent.match(/version\/(\d+)/i);
|
|
979
|
-
if (version !== null) {
|
|
980
|
-
data.splice(1, 1, version[1]);
|
|
934
|
+
newWidth(wid) {
|
|
935
|
+
const result = Math.max(this.resizableMinWidth, wid);
|
|
936
|
+
this.el.nativeElement.style.width = result + 'px';
|
|
937
|
+
}
|
|
938
|
+
mouseDown(evt) {
|
|
939
|
+
if (this.inDragRegion(evt)) {
|
|
940
|
+
this.dragging = true;
|
|
941
|
+
this.preventGlobalMouseEvents();
|
|
942
|
+
evt.stopPropagation();
|
|
981
943
|
}
|
|
982
|
-
return {
|
|
983
|
-
name: data[0],
|
|
984
|
-
version: data[1],
|
|
985
|
-
};
|
|
986
944
|
}
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
if (a === b) {
|
|
994
|
-
return true;
|
|
945
|
+
restoreGlobalMouseEvents() {
|
|
946
|
+
document.body.style['pointer-events'] = 'auto';
|
|
947
|
+
}
|
|
948
|
+
mouseUpG(evt) {
|
|
949
|
+
if (!this.dragging) {
|
|
950
|
+
return;
|
|
995
951
|
}
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
952
|
+
this.restoreGlobalMouseEvents();
|
|
953
|
+
this.dragging = false;
|
|
954
|
+
evt.stopPropagation();
|
|
955
|
+
}
|
|
956
|
+
mouseMove(evt) {
|
|
957
|
+
if (this.inDragRegion(evt) || this.dragging) {
|
|
958
|
+
this.el.nativeElement.style.cursor = 'col-resize';
|
|
999
959
|
}
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
for (const [key, value] of Object.entries(a)) {
|
|
1003
|
-
if (Helper.isSubset(value, b[key])) {
|
|
1004
|
-
return false;
|
|
1005
|
-
}
|
|
1006
|
-
}
|
|
1007
|
-
return true;
|
|
960
|
+
else {
|
|
961
|
+
this.el.nativeElement.style.cursor = 'default';
|
|
1008
962
|
}
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
963
|
+
}
|
|
964
|
+
preventGlobalMouseEvents() {
|
|
965
|
+
document.body.style['pointer-events'] = 'none';
|
|
966
|
+
}
|
|
967
|
+
inDragRegion(evt) {
|
|
968
|
+
return this.el.nativeElement.clientWidth - evt.clientX + this.el.nativeElement.offsetLeft < this.resizableGrabWidth;
|
|
969
|
+
}
|
|
970
|
+
addListenerToDocument() {
|
|
971
|
+
document.addEventListener('mousemove', (e) => {
|
|
972
|
+
this.mouseMoveG(e);
|
|
973
|
+
}, true);
|
|
974
|
+
document.addEventListener('mouseup', (e) => {
|
|
975
|
+
this.mouseUpG(e);
|
|
976
|
+
}, true);
|
|
977
|
+
}
|
|
978
|
+
addListenerToElement() {
|
|
979
|
+
this.el.nativeElement.addEventListener('mousedown', (e) => {
|
|
980
|
+
this.mouseDown(e);
|
|
981
|
+
}, true);
|
|
982
|
+
this.el.nativeElement.addEventListener('mousemove', (e) => {
|
|
983
|
+
this.mouseMove(e);
|
|
984
|
+
}, true);
|
|
985
|
+
}
|
|
986
|
+
}
|
|
987
|
+
ResizableDirective.decorators = [
|
|
988
|
+
{ type: Directive, args: [{
|
|
989
|
+
selector: '[ltResizable]',
|
|
990
|
+
},] }
|
|
991
|
+
];
|
|
992
|
+
ResizableDirective.ctorParameters = () => [
|
|
993
|
+
{ type: ElementRef }
|
|
994
|
+
];
|
|
995
|
+
ResizableDirective.propDecorators = {
|
|
996
|
+
resizableGrabWidth: [{ type: Input }],
|
|
997
|
+
resizableMinWidth: [{ type: Input }]
|
|
998
|
+
};
|
|
999
|
+
|
|
1000
|
+
/**
|
|
1001
|
+
* Truncate string with ellipses
|
|
1002
|
+
*/
|
|
1003
|
+
class EllipsesPipe {
|
|
1004
|
+
transform(value, limit) {
|
|
1005
|
+
if (!value) {
|
|
1006
|
+
return null;
|
|
1018
1007
|
}
|
|
1019
|
-
|
|
1020
|
-
return true;
|
|
1008
|
+
return value.length > limit ? value.substring(0, limit) + '...' : value;
|
|
1021
1009
|
}
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1010
|
+
}
|
|
1011
|
+
EllipsesPipe.decorators = [
|
|
1012
|
+
{ type: Pipe, args: [{
|
|
1013
|
+
name: 'ltEllipses',
|
|
1014
|
+
},] }
|
|
1015
|
+
];
|
|
1016
|
+
|
|
1017
|
+
/**
|
|
1018
|
+
* Declarate html as safe
|
|
1019
|
+
*/
|
|
1020
|
+
class SafeHtmlPipe {
|
|
1021
|
+
constructor(sanitized) {
|
|
1022
|
+
this.sanitized = sanitized;
|
|
1023
|
+
}
|
|
1024
|
+
transform(value) {
|
|
1025
|
+
return this.sanitized.bypassSecurityTrustHtml(value);
|
|
1028
1026
|
}
|
|
1027
|
+
}
|
|
1028
|
+
SafeHtmlPipe.decorators = [
|
|
1029
|
+
{ type: Pipe, args: [{ name: 'ltSafeHtml' },] }
|
|
1030
|
+
];
|
|
1031
|
+
SafeHtmlPipe.ctorParameters = () => [
|
|
1032
|
+
{ type: DomSanitizer }
|
|
1033
|
+
];
|
|
1034
|
+
|
|
1035
|
+
// Imported and exported elements
|
|
1036
|
+
const elements = [
|
|
1037
|
+
// Directives
|
|
1038
|
+
ContextMenuDirective,
|
|
1039
|
+
LazyLoadDirective,
|
|
1040
|
+
MatchHeightDirective,
|
|
1041
|
+
ResizableDirective,
|
|
1042
|
+
// Pipes
|
|
1043
|
+
EllipsesPipe,
|
|
1044
|
+
SafeHtmlPipe,
|
|
1045
|
+
];
|
|
1046
|
+
/**
|
|
1047
|
+
* Base module
|
|
1048
|
+
*/
|
|
1049
|
+
class BaseModule {
|
|
1029
1050
|
/**
|
|
1030
|
-
*
|
|
1031
|
-
* Hint: functions will be ignored and when an array or an object is different the hole array or object will used as property value
|
|
1032
|
-
*
|
|
1033
|
-
* @returns Record<string, any> Object with properties from first object
|
|
1051
|
+
* Set configuration of base module in root module of the app
|
|
1034
1052
|
*/
|
|
1035
|
-
static
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1053
|
+
static forRoot(baseModuleConfig = {}) {
|
|
1054
|
+
// Default config
|
|
1055
|
+
const config = Object.assign({ apiUrl: 'localhost:3000', authGuardRedirectUrl: '/auth', logging: false, version: null, prefix: null, scrollDetectionOffset: 200, scrollOffset: 100, storageType: 'local' }, baseModuleConfig);
|
|
1056
|
+
// Prepare providers
|
|
1057
|
+
const providers = [
|
|
1058
|
+
{
|
|
1059
|
+
provide: BASE_MODULE_CONFIG,
|
|
1060
|
+
useValue: baseModuleConfig,
|
|
1061
|
+
},
|
|
1062
|
+
];
|
|
1063
|
+
// Add apollo features if API URL is set
|
|
1064
|
+
if (baseModuleConfig.apiUrl) {
|
|
1065
|
+
providers.push({
|
|
1066
|
+
provide: APOLLO_OPTIONS,
|
|
1067
|
+
useFactory: apolloOptionsFactory,
|
|
1068
|
+
deps: [BASE_MODULE_CONFIG, HttpLink, AuthService],
|
|
1069
|
+
});
|
|
1040
1070
|
}
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
result[key] = value;
|
|
1044
|
-
}
|
|
1071
|
+
else if (config.logging) {
|
|
1072
|
+
console.log('apiUrl is missing, ApolloLink is not initialized');
|
|
1045
1073
|
}
|
|
1046
|
-
|
|
1074
|
+
// Return root module
|
|
1075
|
+
return {
|
|
1076
|
+
ngModule: BaseModule,
|
|
1077
|
+
providers,
|
|
1078
|
+
};
|
|
1047
1079
|
}
|
|
1048
1080
|
}
|
|
1081
|
+
BaseModule.decorators = [
|
|
1082
|
+
{ type: NgModule, args: [{
|
|
1083
|
+
declarations: elements,
|
|
1084
|
+
exports: elements,
|
|
1085
|
+
},] }
|
|
1086
|
+
];
|
|
1049
1087
|
|
|
1050
1088
|
/**
|
|
1051
1089
|
* Standard class
|