@leanix/components 0.2.248 → 0.2.251

Sign up to get free protection for your applications and to get access to all the features.
@@ -7,13 +7,13 @@ import { ComponentPortal, CdkPortal, PortalModule } from '@angular/cdk/portal';
7
7
  import * as i1 from '@angular/cdk/overlay';
8
8
  import { OverlayModule, CdkConnectedOverlay } from '@angular/cdk/overlay';
9
9
  import { __decorate } from 'tslib';
10
+ import { escape, trimEnd, sortBy, get, isEqual, toLower, some, padCharsStart, toString, isNaN as isNaN$1, toNumber, includes, last, findIndex, filter as filter$1, isObject, find, uniqueId } from 'lodash/fp';
10
11
  import * as i6 from 'rxjs';
11
12
  import { BehaviorSubject, timer, Subject, combineLatest, merge, concat, fromEvent, Observable, ReplaySubject, of } from 'rxjs';
12
13
  import { skipWhile, map, switchMap, startWith, pairwise, filter, take, debounceTime, skip, withLatestFrom, distinctUntilChanged, takeUntil, first, delay, mapTo, tap } from 'rxjs/operators';
13
14
  import * as i1$1 from '@ngx-translate/core';
14
15
  import { TranslatePipe, TranslateModule } from '@ngx-translate/core';
15
16
  import * as i1$2 from '@angular/platform-browser';
16
- import { trimEnd, sortBy, get, isEqual, toLower, some, padCharsStart, toString, isNaN as isNaN$1, toNumber, includes, last, findIndex, filter as filter$1, isObject, find, uniqueId } from 'lodash/fp';
17
17
  import Color from 'color';
18
18
  import { format, distanceInWords, startOfDay } from 'date-fns';
19
19
  import _, { curry } from 'lodash';
@@ -604,10 +604,21 @@ class EllipsisComponent {
604
604
  this.resizeObserverService = resizeObserverService;
605
605
  this.translateService = translateService;
606
606
  this.content = '';
607
+ /**
608
+ * Only set this to false if the content is not a user provided string
609
+ * or if you sanitize the provided content yourself.
610
+ */
611
+ this.escapeHtmlInContent = true;
607
612
  this.isShowingMore$ = new BehaviorSubject(false);
608
613
  this.destroyed$ = new Subject();
609
614
  }
610
615
  ngOnInit() {
616
+ this.sanitizedContent$ = this.content$.pipe(map((content) => {
617
+ if (this.escapeHtmlInContent && typeof content === 'string') {
618
+ return escape(content);
619
+ }
620
+ return content;
621
+ }));
611
622
  this.showMoreButtonLabel$ = this.isShowingMore$.pipe(switchMap((isShowingMore) => {
612
623
  const translationKey = isShowingMore ? 'common.showLess' : 'common.showMore';
613
624
  return this.translateService.get(translationKey);
@@ -676,7 +687,7 @@ class EllipsisComponent {
676
687
  }
677
688
  EllipsisComponent.DEFAULT_RESIZE_DEBOUNCE_MS = 500;
678
689
  EllipsisComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: EllipsisComponent, deps: [{ token: LX_ELLIPSIS_DEBOUNCE_ON_RESIZE }, { token: i0.ChangeDetectorRef }, { token: i0.ElementRef }, { token: ResizeObserverService }, { token: i1$1.TranslateService }], target: i0.ɵɵFactoryTarget.Component });
679
- EllipsisComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.2", type: EllipsisComponent, selector: "lx-ellipsis", inputs: { content: "content" }, viewQueries: [{ propertyName: "contentSpanEl", first: true, predicate: ["contentEl"], descendants: true }, { propertyName: "showMoreButtonEl", first: true, predicate: ["showMoreButton"], descendants: true, read: ElementRef }], ngImport: i0, template: "<span #contentEl [class.showMore]=\"isShowingMore$ | async\" class=\"content truncate lx-margin-right\" [innerHtml]=\"content\"></span>\n<button *ngIf=\"showButton$ | async\" (click)=\"onShowMoreToggle()\" lx-button #showMoreButton size=\"auto\" mode=\"link\" color=\"primary\">\n {{ showMoreButtonLabel$ | async }}\n</button>\n", styles: [":host{display:block}.content{display:inline-block}.truncate:not(.showMore){width:calc(100% - 140px);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.content.showMore+button{margin-top:4px;display:block}button{white-space:nowrap;vertical-align:top}\n"], components: [{ type: ButtonComponent, selector: "button[lx-button]", inputs: ["size", "color", "mode", "pressed", "selected", "square", "circle", "disabled", "showSpinner"] }], directives: [{ type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], pipes: { "async": i2.AsyncPipe }, changeDetection: i0.ChangeDetectionStrategy.OnPush });
690
+ EllipsisComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.2", type: EllipsisComponent, selector: "lx-ellipsis", inputs: { content: "content", escapeHtmlInContent: "escapeHtmlInContent" }, viewQueries: [{ propertyName: "contentSpanEl", first: true, predicate: ["contentEl"], descendants: true }, { propertyName: "showMoreButtonEl", first: true, predicate: ["showMoreButton"], descendants: true, read: ElementRef }], ngImport: i0, template: "<span\n #contentEl\n [class.showMore]=\"isShowingMore$ | async\"\n class=\"content truncate lx-margin-right\"\n [innerHtml]=\"sanitizedContent$ | async\"\n></span>\n<button *ngIf=\"showButton$ | async\" (click)=\"onShowMoreToggle()\" lx-button #showMoreButton size=\"auto\" mode=\"link\" color=\"primary\">\n {{ showMoreButtonLabel$ | async }}\n</button>\n", styles: [":host{display:block}.content{display:inline-block}.truncate:not(.showMore){width:calc(100% - 140px);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.content.showMore+button{margin-top:4px;display:block}button{white-space:nowrap;vertical-align:top}\n"], components: [{ type: ButtonComponent, selector: "button[lx-button]", inputs: ["size", "color", "mode", "pressed", "selected", "square", "circle", "disabled", "showSpinner"] }], directives: [{ type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], pipes: { "async": i2.AsyncPipe }, changeDetection: i0.ChangeDetectionStrategy.OnPush });
680
691
  __decorate([
681
692
  Observe('contentSpanEl')
682
693
  ], EllipsisComponent.prototype, "contentSpanEl$", void 0);
@@ -688,12 +699,14 @@ __decorate([
688
699
  ], EllipsisComponent.prototype, "content$", void 0);
689
700
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: EllipsisComponent, decorators: [{
690
701
  type: Component,
691
- args: [{ selector: 'lx-ellipsis', changeDetection: ChangeDetectionStrategy.OnPush, template: "<span #contentEl [class.showMore]=\"isShowingMore$ | async\" class=\"content truncate lx-margin-right\" [innerHtml]=\"content\"></span>\n<button *ngIf=\"showButton$ | async\" (click)=\"onShowMoreToggle()\" lx-button #showMoreButton size=\"auto\" mode=\"link\" color=\"primary\">\n {{ showMoreButtonLabel$ | async }}\n</button>\n", styles: [":host{display:block}.content{display:inline-block}.truncate:not(.showMore){width:calc(100% - 140px);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.content.showMore+button{margin-top:4px;display:block}button{white-space:nowrap;vertical-align:top}\n"] }]
702
+ args: [{ selector: 'lx-ellipsis', changeDetection: ChangeDetectionStrategy.OnPush, template: "<span\n #contentEl\n [class.showMore]=\"isShowingMore$ | async\"\n class=\"content truncate lx-margin-right\"\n [innerHtml]=\"sanitizedContent$ | async\"\n></span>\n<button *ngIf=\"showButton$ | async\" (click)=\"onShowMoreToggle()\" lx-button #showMoreButton size=\"auto\" mode=\"link\" color=\"primary\">\n {{ showMoreButtonLabel$ | async }}\n</button>\n", styles: [":host{display:block}.content{display:inline-block}.truncate:not(.showMore){width:calc(100% - 140px);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.content.showMore+button{margin-top:4px;display:block}button{white-space:nowrap;vertical-align:top}\n"] }]
692
703
  }], ctorParameters: function () { return [{ type: undefined, decorators: [{
693
704
  type: Inject,
694
705
  args: [LX_ELLIPSIS_DEBOUNCE_ON_RESIZE]
695
706
  }] }, { type: i0.ChangeDetectorRef }, { type: i0.ElementRef }, { type: ResizeObserverService }, { type: i1$1.TranslateService }]; }, propDecorators: { content: [{
696
707
  type: Input
708
+ }], escapeHtmlInContent: [{
709
+ type: Input
697
710
  }], contentSpanEl$: [], contentSpanEl: [{
698
711
  type: ViewChild,
699
712
  args: ['contentEl']
@@ -1033,172 +1046,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImpor
1033
1046
  type: Input
1034
1047
  }] } });
1035
1048
 
1036
- class BrPipe {
1037
- transform(input, options = {}) {
1038
- if (input) {
1039
- if (options.isTrimEnd) {
1040
- input = trimEnd(input);
1041
- }
1042
- return input.replace(/[\n\r]/g, '<br/>');
1043
- }
1044
- return input;
1045
- }
1046
- }
1047
- BrPipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: BrPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
1048
- BrPipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: BrPipe, name: "lxBr" });
1049
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: BrPipe, decorators: [{
1050
- type: Pipe,
1051
- args: [{
1052
- name: 'lxBr'
1053
- }]
1054
- }] });
1055
-
1056
- /**
1057
- * Compute the most eligible text color for a given background color (black or white), depending on the luminance of the
1058
- * background color. In case the provided color is undefined or invalid, white (#FFFFFF) is returned.
1059
- *
1060
- * @param colorHex Color string in hexadecimal encoding.
1061
- * @returns Equivalent contrast color in hexadecimal encoding.
1062
- */
1063
- function getContrastColor(colorHex) {
1064
- try {
1065
- const color = Color(colorHex || '#000');
1066
- // Check http://codepen.io/WebSeed/pen/pvgqEq
1067
- const a = 1 - (0.299 * color.red() + 0.587 * color.green() + 0.114 * color.blue()) / 255;
1068
- const d = a < 0.4 ? 0 : 255;
1069
- return Color({ r: d, g: d, b: d }).hex();
1070
- }
1071
- catch {
1072
- return '#FFFFFF';
1073
- }
1074
- }
1075
- function shorthandHexHandle(hex) {
1076
- const shorthandRegex = /^(#)([a-f\d])([a-f\d])([a-f\d])$/i;
1077
- const shorthand = hex.match(shorthandRegex);
1078
- if (shorthand) {
1079
- const convertedHex = shorthand[1] + shorthand[2] + shorthand[2] + shorthand[3] + shorthand[3] + shorthand[4] + shorthand[4];
1080
- return convertedHex;
1081
- }
1082
- else {
1083
- return hex;
1084
- }
1085
- }
1086
- function isValidHexColor(color) {
1087
- return /^#[0-9A-F]{6}$/i.test(color);
1088
- }
1089
-
1090
- class ContrastColorPipe {
1091
- transform(color) {
1092
- if (color) {
1093
- return isValidHexColor(shorthandHexHandle(color)) ? getContrastColor(color) : '';
1094
- }
1095
- return '';
1096
- }
1097
- }
1098
- ContrastColorPipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: ContrastColorPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
1099
- ContrastColorPipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: ContrastColorPipe, name: "lxContrastColor" });
1100
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: ContrastColorPipe, decorators: [{
1101
- type: Pipe,
1102
- args: [{
1103
- name: 'lxContrastColor'
1104
- }]
1105
- }] });
1106
-
1107
- const DATE_FORMATS = new InjectionToken('DATE_FORMATS', {
1108
- providedIn: 'root',
1109
- factory: () => ({
1110
- getDateFormat: () => 'YYYY-MM-DD',
1111
- getDateTimeFormat: () => 'YYYY-MM-DD HH:mm',
1112
- getDateTimeFormatWithSeconds: () => 'YYYY-MM-DD HH:mm:ss'
1113
- })
1114
- });
1115
- const DATE_FN_LOCALE = new InjectionToken('DATE_FN_LOCALE');
1116
- const LOCALE_FN = new InjectionToken('LOCALE_FN');
1117
- const GLOBAL_TRANSLATION_OPTIONS = new InjectionToken('GLOBAL_TRANSLATION_OPTIONS');
1118
-
1119
- class CustomDatePipe {
1120
- constructor(getDateFnLocale) {
1121
- this.getDateFnLocale = getDateFnLocale;
1122
- }
1123
- transform(value, f) {
1124
- const locale = this.getDateFnLocale ? this.getDateFnLocale() : null;
1125
- return value ? format(value, f, { locale }) : '';
1126
- }
1127
- }
1128
- CustomDatePipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: CustomDatePipe, deps: [{ token: DATE_FN_LOCALE, optional: true }], target: i0.ɵɵFactoryTarget.Pipe });
1129
- CustomDatePipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: CustomDatePipe, name: "lxDate" });
1130
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: CustomDatePipe, decorators: [{
1131
- type: Pipe,
1132
- args: [{
1133
- name: 'lxDate'
1134
- }]
1135
- }], ctorParameters: function () { return [{ type: Function, decorators: [{
1136
- type: Optional
1137
- }, {
1138
- type: Inject,
1139
- args: [DATE_FN_LOCALE]
1140
- }] }]; } });
1141
-
1142
- class HighlightRangePipe {
1143
- transform(text, offset = 0, length = 0) {
1144
- if (!text || offset < 0 || length < 0 || offset >= text?.length || offset + length > text?.length) {
1145
- return '';
1146
- }
1147
- const highlightedPart = text.slice(offset, offset + length);
1148
- return text.slice(0, offset) + (highlightedPart.length !== 0 ? this.highlight(highlightedPart) : '') + text.slice(offset + length);
1149
- }
1150
- highlight(text) {
1151
- return `<span class="termHighlight">${text}</span>`;
1152
- }
1153
- }
1154
- HighlightRangePipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: HighlightRangePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
1155
- HighlightRangePipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: HighlightRangePipe, name: "lxHighlightRange" });
1156
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: HighlightRangePipe, decorators: [{
1157
- type: Pipe,
1158
- args: [{ name: 'lxHighlightRange' }]
1159
- }] });
1160
-
1161
- /**
1162
- * These characters are treated as seperators by
1163
- * elasticsearch and split the input into search tokens
1164
- * which are used to find matches.
1165
- */
1166
- const STANDARD_TOKENIZER_SEPERATORS = /[^a-zA-Z\d\s]/g;
1167
- class HighlightTermPipe {
1168
- transform(text, search) {
1169
- if (search && text) {
1170
- let pattern = search
1171
- .replace(STANDARD_TOKENIZER_SEPERATORS, ' ')
1172
- // replace special chars for a backslash for RegExp
1173
- .replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&');
1174
- pattern = pattern
1175
- .split(' ')
1176
- .filter((t) => {
1177
- return t.length > 0;
1178
- })
1179
- .join('|');
1180
- const regex = new RegExp(pattern, 'gi');
1181
- text = _.escape(text);
1182
- return text.replace(regex, (match) => `<span class="termHighlight">${match}</span>`); // add highlighting to matched regex pattern
1183
- }
1184
- else {
1185
- return text;
1186
- }
1187
- }
1188
- }
1189
- HighlightTermPipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: HighlightTermPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
1190
- HighlightTermPipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: HighlightTermPipe, name: "lxHighlightTerm" });
1191
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: HighlightTermPipe, decorators: [{
1192
- type: Pipe,
1193
- args: [{ name: 'lxHighlightTerm' }]
1194
- }] });
1195
-
1196
1049
  /**
1197
1050
  * This pipe transforms...
1198
1051
  * - "raw" http(s) links
1199
1052
  * - markdown link syntax
1200
1053
  * ... into clickable anchor elements.
1201
1054
  *
1055
+ * The characters "<" and ">" are escaped with their HTML entities &lt; and &gt;.
1056
+ *
1202
1057
  * You have an user interface where you don't want clickable links but also
1203
1058
  * don't want users to see the "ugly" markdown link syntax?
1204
1059
  * -> Use the 'lxUnlikify' pipe to replace markdown link syntax with just the link name
@@ -1206,7 +1061,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImpor
1206
1061
  class LxLinkifyPipe {
1207
1062
  transform(text) {
1208
1063
  if (text && typeof text === 'string') {
1209
- const textWithRawLinks = this.wrapRawHttpLinksWithAnchorTags(text);
1064
+ const escapedText = this.escapeHtmlInUserProvidedString(text);
1065
+ const textWithRawLinks = this.wrapRawHttpLinksWithAnchorTags(escapedText);
1210
1066
  const textWithRawAndNamedLinks = this.turnMarkdownStyleLinksIntoAnchorTags(textWithRawLinks);
1211
1067
  return textWithRawAndNamedLinks;
1212
1068
  }
@@ -1285,6 +1141,17 @@ class LxLinkifyPipe {
1285
1141
  }
1286
1142
  return matches;
1287
1143
  }
1144
+ /**
1145
+ * We assume that lxLinkify is exclusively used on user provided strings.
1146
+ * This is why we want to escape any other HTML tags that are already present in the string.
1147
+ * The logic implemented here has been used with no issues for three years in our Fact Sheet comments. See https://github.com/gregjacobs/Autolinker.js/pull/313
1148
+ *
1149
+ * When using lxLinkify in conjunction with other pipes that add HTML, make sure to use lxLinkify first,
1150
+ * so that it doesn't escape the HTML of any previous pipes.
1151
+ */
1152
+ escapeHtmlInUserProvidedString(input) {
1153
+ return input.replace(/<|>/gi, (match) => '&' + (match === '>' ? 'g' : 'l') + 't;');
1154
+ }
1288
1155
  }
1289
1156
  /**
1290
1157
  * This is not the "one URL regex to rule them all", but a more realistic one which should work
@@ -1366,6 +1233,166 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImpor
1366
1233
  args: [{ name: 'lxUnlinkify' }]
1367
1234
  }] });
1368
1235
 
1236
+ class BrPipe {
1237
+ transform(input, options = {}) {
1238
+ if (input) {
1239
+ if (options.isTrimEnd) {
1240
+ input = trimEnd(input);
1241
+ }
1242
+ return input.replace(/[\n\r]/g, '<br/>');
1243
+ }
1244
+ return input;
1245
+ }
1246
+ }
1247
+ BrPipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: BrPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
1248
+ BrPipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: BrPipe, name: "lxBr" });
1249
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: BrPipe, decorators: [{
1250
+ type: Pipe,
1251
+ args: [{
1252
+ name: 'lxBr'
1253
+ }]
1254
+ }] });
1255
+
1256
+ /**
1257
+ * Compute the most eligible text color for a given background color (black or white), depending on the luminance of the
1258
+ * background color. In case the provided color is undefined or invalid, white (#FFFFFF) is returned.
1259
+ *
1260
+ * @param colorHex Color string in hexadecimal encoding.
1261
+ * @returns Equivalent contrast color in hexadecimal encoding.
1262
+ */
1263
+ function getContrastColor(colorHex) {
1264
+ try {
1265
+ const color = Color(colorHex || '#000');
1266
+ // Check http://codepen.io/WebSeed/pen/pvgqEq
1267
+ const a = 1 - (0.299 * color.red() + 0.587 * color.green() + 0.114 * color.blue()) / 255;
1268
+ const d = a < 0.4 ? 0 : 255;
1269
+ return Color({ r: d, g: d, b: d }).hex();
1270
+ }
1271
+ catch {
1272
+ return '#FFFFFF';
1273
+ }
1274
+ }
1275
+ function shorthandHexHandle(hex) {
1276
+ const shorthandRegex = /^(#)([a-f\d])([a-f\d])([a-f\d])$/i;
1277
+ const shorthand = hex.match(shorthandRegex);
1278
+ if (shorthand) {
1279
+ const convertedHex = shorthand[1] + shorthand[2] + shorthand[2] + shorthand[3] + shorthand[3] + shorthand[4] + shorthand[4];
1280
+ return convertedHex;
1281
+ }
1282
+ else {
1283
+ return hex;
1284
+ }
1285
+ }
1286
+ function isValidHexColor(color) {
1287
+ return /^#[0-9A-F]{6}$/i.test(color);
1288
+ }
1289
+
1290
+ class ContrastColorPipe {
1291
+ transform(color) {
1292
+ if (color) {
1293
+ return isValidHexColor(shorthandHexHandle(color)) ? getContrastColor(color) : '';
1294
+ }
1295
+ return '';
1296
+ }
1297
+ }
1298
+ ContrastColorPipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: ContrastColorPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
1299
+ ContrastColorPipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: ContrastColorPipe, name: "lxContrastColor" });
1300
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: ContrastColorPipe, decorators: [{
1301
+ type: Pipe,
1302
+ args: [{
1303
+ name: 'lxContrastColor'
1304
+ }]
1305
+ }] });
1306
+
1307
+ const DATE_FORMATS = new InjectionToken('DATE_FORMATS', {
1308
+ providedIn: 'root',
1309
+ factory: () => ({
1310
+ getDateFormat: () => 'YYYY-MM-DD',
1311
+ getDateTimeFormat: () => 'YYYY-MM-DD HH:mm',
1312
+ getDateTimeFormatWithSeconds: () => 'YYYY-MM-DD HH:mm:ss'
1313
+ })
1314
+ });
1315
+ const DATE_FN_LOCALE = new InjectionToken('DATE_FN_LOCALE');
1316
+ const LOCALE_FN = new InjectionToken('LOCALE_FN');
1317
+ const GLOBAL_TRANSLATION_OPTIONS = new InjectionToken('GLOBAL_TRANSLATION_OPTIONS');
1318
+
1319
+ class CustomDatePipe {
1320
+ constructor(getDateFnLocale) {
1321
+ this.getDateFnLocale = getDateFnLocale;
1322
+ }
1323
+ transform(value, f) {
1324
+ const locale = this.getDateFnLocale ? this.getDateFnLocale() : null;
1325
+ return value ? format(value, f, { locale }) : '';
1326
+ }
1327
+ }
1328
+ CustomDatePipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: CustomDatePipe, deps: [{ token: DATE_FN_LOCALE, optional: true }], target: i0.ɵɵFactoryTarget.Pipe });
1329
+ CustomDatePipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: CustomDatePipe, name: "lxDate" });
1330
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: CustomDatePipe, decorators: [{
1331
+ type: Pipe,
1332
+ args: [{
1333
+ name: 'lxDate'
1334
+ }]
1335
+ }], ctorParameters: function () { return [{ type: Function, decorators: [{
1336
+ type: Optional
1337
+ }, {
1338
+ type: Inject,
1339
+ args: [DATE_FN_LOCALE]
1340
+ }] }]; } });
1341
+
1342
+ class HighlightRangePipe {
1343
+ transform(text, offset = 0, length = 0) {
1344
+ if (!text || offset < 0 || length < 0 || offset >= text?.length || offset + length > text?.length) {
1345
+ return '';
1346
+ }
1347
+ const highlightedPart = text.slice(offset, offset + length);
1348
+ return text.slice(0, offset) + (highlightedPart.length !== 0 ? this.highlight(highlightedPart) : '') + text.slice(offset + length);
1349
+ }
1350
+ highlight(text) {
1351
+ return `<span class="termHighlight">${text}</span>`;
1352
+ }
1353
+ }
1354
+ HighlightRangePipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: HighlightRangePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
1355
+ HighlightRangePipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: HighlightRangePipe, name: "lxHighlightRange" });
1356
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: HighlightRangePipe, decorators: [{
1357
+ type: Pipe,
1358
+ args: [{ name: 'lxHighlightRange' }]
1359
+ }] });
1360
+
1361
+ /**
1362
+ * These characters are treated as seperators by
1363
+ * elasticsearch and split the input into search tokens
1364
+ * which are used to find matches.
1365
+ */
1366
+ const STANDARD_TOKENIZER_SEPERATORS = /[^a-zA-Z\d\s]/g;
1367
+ class HighlightTermPipe {
1368
+ transform(text, search) {
1369
+ if (search && text) {
1370
+ let pattern = search
1371
+ .replace(STANDARD_TOKENIZER_SEPERATORS, ' ')
1372
+ // replace special chars for a backslash for RegExp
1373
+ .replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&');
1374
+ pattern = pattern
1375
+ .split(' ')
1376
+ .filter((t) => {
1377
+ return t.length > 0;
1378
+ })
1379
+ .join('|');
1380
+ const regex = new RegExp(pattern, 'gi');
1381
+ text = _.escape(text);
1382
+ return text.replace(regex, (match) => `<span class="termHighlight">${match}</span>`); // add highlighting to matched regex pattern
1383
+ }
1384
+ else {
1385
+ return text;
1386
+ }
1387
+ }
1388
+ }
1389
+ HighlightTermPipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: HighlightTermPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
1390
+ HighlightTermPipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: HighlightTermPipe, name: "lxHighlightTerm" });
1391
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: HighlightTermPipe, decorators: [{
1392
+ type: Pipe,
1393
+ args: [{ name: 'lxHighlightTerm' }]
1394
+ }] });
1395
+
1369
1396
  function isUuid(s) {
1370
1397
  const uuidRegEx = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
1371
1398
  return uuidRegEx.test(s);
@@ -6099,6 +6126,7 @@ class PopoverComponent {
6099
6126
  constructor() {
6100
6127
  this.noMargin = false;
6101
6128
  this.allowOverflow = false;
6129
+ this.autoFocus = false;
6102
6130
  /**
6103
6131
  * If you have a popover, that should usually be displayed above or below its anchor,
6104
6132
  * and this anchor is in a scrollable container, you should set this to true.
@@ -6207,10 +6235,10 @@ class PopoverComponent {
6207
6235
  }
6208
6236
  }
6209
6237
  PopoverComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: PopoverComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
6210
- PopoverComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.2", type: PopoverComponent, selector: "lx-popover", inputs: { trigger: "trigger", horizontalAlign: "horizontalAlign", verticalAlign: "verticalAlign", noMargin: "noMargin", allowOverflow: "allowOverflow", adaptMarginsForViewportAlignChange: "adaptMarginsForViewportAlignChange" }, outputs: { opened: "opened", closed: "closed" }, queries: [{ propertyName: "explicitContent", first: true, predicate: PopoverContentDirective, descendants: true, read: TemplateRef, static: true }], viewQueries: [{ propertyName: "satPopover", first: true, predicate: SatPopover, descendants: true, static: true }, { propertyName: "implicitContent", first: true, predicate: ["implicitContent"], descendants: true, static: true }], usesOnChanges: true, ngImport: i0, template: "<sat-popover\n [anchor]=\"trigger.anchor\"\n [horizontalAlign]=\"horizontalAlign\"\n [verticalAlign]=\"verticalAlign\"\n [restoreFocus]=\"false\"\n [lockAlignment]=\"true\"\n [autoFocus]=\"false\"\n openTransition=\"0ms\"\n closeTransition=\"0ms\"\n (opened)=\"onOpen()\"\n (afterOpen)=\"onAfterOpen()\"\n (closed)=\"onClose()\"\n>\n <div\n class=\"popoverContainer\"\n [ngClass]=\"marginClasses\"\n [class.overflowHidden]=\"!allowOverflow\"\n (mouseenter)=\"trigger.showPopover(true)\"\n (mouseleave)=\"trigger.closePopover(true)\"\n >\n <ng-container *ngIf=\"isOpen\">\n <ng-container *ngTemplateOutlet=\"content\"></ng-container>\n </ng-container>\n </div>\n</sat-popover>\n<ng-template #implicitContent>\n <ng-content></ng-content>\n</ng-template>\n", styles: ["@keyframes subtleScaleUpKeyFrames{0%{transform:scale(.95);opacity:0}}.popoverContainer{position:relative;box-shadow:0 8px 12px 2px #00000026;max-width:600px;max-height:80vh;border-radius:3px;background-color:#fff;-webkit-hyphens:auto;hyphens:auto;animation:subtleScaleUpKeyFrames .2s ease}.popoverContainer.overflowHidden{overflow:hidden}.right{margin-left:18px}.left{margin-right:18px}.bottom{margin-top:18px}.top{margin-bottom:18px}\n"], components: [{ type: i1$6.SatPopover, selector: "sat-popover", inputs: ["anchor", "horizontalAlign", "xAlign", "verticalAlign", "yAlign", "forceAlignment", "lockAlignment", "autoFocus", "restoreFocus", "scrollStrategy", "hasBackdrop", "interactiveClose", "openTransition", "closeTransition", "openAnimationStartAtScale", "closeAnimationEndAtScale", "backdropClass", "panelClass"], outputs: ["opened", "closed", "afterOpen", "afterClose", "backdropClicked", "overlayKeydown"] }], directives: [{ type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }] });
6238
+ PopoverComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.2", type: PopoverComponent, selector: "lx-popover", inputs: { trigger: "trigger", horizontalAlign: "horizontalAlign", verticalAlign: "verticalAlign", noMargin: "noMargin", allowOverflow: "allowOverflow", autoFocus: "autoFocus", adaptMarginsForViewportAlignChange: "adaptMarginsForViewportAlignChange" }, outputs: { opened: "opened", closed: "closed" }, queries: [{ propertyName: "explicitContent", first: true, predicate: PopoverContentDirective, descendants: true, read: TemplateRef, static: true }], viewQueries: [{ propertyName: "satPopover", first: true, predicate: SatPopover, descendants: true, static: true }, { propertyName: "implicitContent", first: true, predicate: ["implicitContent"], descendants: true, static: true }], usesOnChanges: true, ngImport: i0, template: "<sat-popover\n [anchor]=\"trigger.anchor\"\n [horizontalAlign]=\"horizontalAlign\"\n [verticalAlign]=\"verticalAlign\"\n [restoreFocus]=\"false\"\n [lockAlignment]=\"true\"\n [autoFocus]=\"autoFocus\"\n openTransition=\"0ms\"\n closeTransition=\"0ms\"\n (opened)=\"onOpen()\"\n (afterOpen)=\"onAfterOpen()\"\n (closed)=\"onClose()\"\n>\n <div\n class=\"popoverContainer\"\n [ngClass]=\"marginClasses\"\n [class.overflowHidden]=\"!allowOverflow\"\n (mouseenter)=\"trigger.showPopover(true)\"\n (mouseleave)=\"trigger.closePopover(true)\"\n (keydown.escape)=\"$event.stopPropagation(); trigger.closePopover(true)\"\n >\n <ng-container *ngIf=\"isOpen\">\n <ng-container *ngTemplateOutlet=\"content\"></ng-container>\n </ng-container>\n </div>\n</sat-popover>\n<ng-template #implicitContent>\n <ng-content></ng-content>\n</ng-template>\n", styles: ["@keyframes subtleScaleUpKeyFrames{0%{transform:scale(.95);opacity:0}}.popoverContainer{position:relative;box-shadow:0 8px 12px 2px #00000026;max-width:600px;max-height:80vh;border-radius:3px;background-color:#fff;-webkit-hyphens:auto;hyphens:auto;animation:subtleScaleUpKeyFrames .2s ease}.popoverContainer.overflowHidden{overflow:hidden}.right{margin-left:18px}.left{margin-right:18px}.bottom{margin-top:18px}.top{margin-bottom:18px}\n"], components: [{ type: i1$6.SatPopover, selector: "sat-popover", inputs: ["anchor", "horizontalAlign", "xAlign", "verticalAlign", "yAlign", "forceAlignment", "lockAlignment", "autoFocus", "restoreFocus", "scrollStrategy", "hasBackdrop", "interactiveClose", "openTransition", "closeTransition", "openAnimationStartAtScale", "closeAnimationEndAtScale", "backdropClass", "panelClass"], outputs: ["opened", "closed", "afterOpen", "afterClose", "backdropClicked", "overlayKeydown"] }], directives: [{ type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }] });
6211
6239
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: PopoverComponent, decorators: [{
6212
6240
  type: Component,
6213
- args: [{ selector: 'lx-popover', template: "<sat-popover\n [anchor]=\"trigger.anchor\"\n [horizontalAlign]=\"horizontalAlign\"\n [verticalAlign]=\"verticalAlign\"\n [restoreFocus]=\"false\"\n [lockAlignment]=\"true\"\n [autoFocus]=\"false\"\n openTransition=\"0ms\"\n closeTransition=\"0ms\"\n (opened)=\"onOpen()\"\n (afterOpen)=\"onAfterOpen()\"\n (closed)=\"onClose()\"\n>\n <div\n class=\"popoverContainer\"\n [ngClass]=\"marginClasses\"\n [class.overflowHidden]=\"!allowOverflow\"\n (mouseenter)=\"trigger.showPopover(true)\"\n (mouseleave)=\"trigger.closePopover(true)\"\n >\n <ng-container *ngIf=\"isOpen\">\n <ng-container *ngTemplateOutlet=\"content\"></ng-container>\n </ng-container>\n </div>\n</sat-popover>\n<ng-template #implicitContent>\n <ng-content></ng-content>\n</ng-template>\n", styles: ["@keyframes subtleScaleUpKeyFrames{0%{transform:scale(.95);opacity:0}}.popoverContainer{position:relative;box-shadow:0 8px 12px 2px #00000026;max-width:600px;max-height:80vh;border-radius:3px;background-color:#fff;-webkit-hyphens:auto;hyphens:auto;animation:subtleScaleUpKeyFrames .2s ease}.popoverContainer.overflowHidden{overflow:hidden}.right{margin-left:18px}.left{margin-right:18px}.bottom{margin-top:18px}.top{margin-bottom:18px}\n"] }]
6241
+ args: [{ selector: 'lx-popover', template: "<sat-popover\n [anchor]=\"trigger.anchor\"\n [horizontalAlign]=\"horizontalAlign\"\n [verticalAlign]=\"verticalAlign\"\n [restoreFocus]=\"false\"\n [lockAlignment]=\"true\"\n [autoFocus]=\"autoFocus\"\n openTransition=\"0ms\"\n closeTransition=\"0ms\"\n (opened)=\"onOpen()\"\n (afterOpen)=\"onAfterOpen()\"\n (closed)=\"onClose()\"\n>\n <div\n class=\"popoverContainer\"\n [ngClass]=\"marginClasses\"\n [class.overflowHidden]=\"!allowOverflow\"\n (mouseenter)=\"trigger.showPopover(true)\"\n (mouseleave)=\"trigger.closePopover(true)\"\n (keydown.escape)=\"$event.stopPropagation(); trigger.closePopover(true)\"\n >\n <ng-container *ngIf=\"isOpen\">\n <ng-container *ngTemplateOutlet=\"content\"></ng-container>\n </ng-container>\n </div>\n</sat-popover>\n<ng-template #implicitContent>\n <ng-content></ng-content>\n</ng-template>\n", styles: ["@keyframes subtleScaleUpKeyFrames{0%{transform:scale(.95);opacity:0}}.popoverContainer{position:relative;box-shadow:0 8px 12px 2px #00000026;max-width:600px;max-height:80vh;border-radius:3px;background-color:#fff;-webkit-hyphens:auto;hyphens:auto;animation:subtleScaleUpKeyFrames .2s ease}.popoverContainer.overflowHidden{overflow:hidden}.right{margin-left:18px}.left{margin-right:18px}.bottom{margin-top:18px}.top{margin-bottom:18px}\n"] }]
6214
6242
  }], propDecorators: { trigger: [{
6215
6243
  type: Input
6216
6244
  }], horizontalAlign: [{
@@ -6221,6 +6249,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImpor
6221
6249
  type: Input
6222
6250
  }], allowOverflow: [{
6223
6251
  type: Input
6252
+ }], autoFocus: [{
6253
+ type: Input
6224
6254
  }], adaptMarginsForViewportAlignChange: [{
6225
6255
  type: Input
6226
6256
  }], opened: [{