From a410c77ede81d7789ea851b1e5b744f45b605b33 Mon Sep 17 00:00:00 2001 From: Javier Centeno Vega Date: Thu, 30 Sep 2021 03:21:45 +0200 Subject: [PATCH 1/7] Add regexp service --- projects/lux/src/lib/input/input.component.ts | 3 +- projects/lux/src/lib/input/regexp.service.ts | 219 ++++++++++++++++++ 2 files changed, 221 insertions(+), 1 deletion(-) create mode 100644 projects/lux/src/lib/input/regexp.service.ts diff --git a/projects/lux/src/lib/input/input.component.ts b/projects/lux/src/lib/input/input.component.ts index 964a5933..f01524dd 100644 --- a/projects/lux/src/lib/input/input.component.ts +++ b/projects/lux/src/lib/input/input.component.ts @@ -24,6 +24,7 @@ import { normalizeDate } from '../helperFns'; import { languageDetector } from '../lang'; +import { RegexpService } from './regexp.service'; @Component({ selector: 'lux-input', templateUrl: './input.component.html', @@ -190,7 +191,7 @@ export class InputComponent implements OnInit, ControlValueAccessor, Validator { onChange = (value): void => {}; onTouched = (): void => {}; - constructor() {} + constructor(public regexpService: RegexpService) {} // ControlValueAccessor Interface implementation writeValue(value: any): void { diff --git a/projects/lux/src/lib/input/regexp.service.ts b/projects/lux/src/lib/input/regexp.service.ts new file mode 100644 index 00000000..6247db17 --- /dev/null +++ b/projects/lux/src/lib/input/regexp.service.ts @@ -0,0 +1,219 @@ +import { Injectable } from '@angular/core'; + +/** + * A service that holds the functionality for advanced handling of regular expressions + */ +@Injectable({ providedIn: 'root' }) +export class RegexpService { + constructor() {} + + private removeOuterRoundBrackets(regularExpressionString: string): string { + while ( + regularExpressionString[0] === '(' && + regularExpressionString[regularExpressionString.length - 1] === ')' + ) { + regularExpressionString = regularExpressionString.slice( + 1, + regularExpressionString.length - 1 + ); + } + return regularExpressionString; + } + + private isQuantifier(quantifier: string): boolean { + switch (quantifier) { + case '{': + case '?': + case '+': + case '*': + return true; + } + return false; + } + + private parseMinimalAmountOfQuantifier(quantifier: string): number { + switch (quantifier[0]) { + case '?': + case '*': + return 0; + case '+': + return 1; + case '{': + for (let index = 1; index < quantifier.length; ++index) { + if (quantifier[index] < '0' || quantifier[index] > '9') { + return Number(quantifier.slice(1, index)); + } + } + } + return 0; + } + + private sliceRegexByOr(regularExpressionString: string): string[] { + const result = []; + let slicedRegex = ''; + let lastSliceIndex = 0; + let roundBracketCount = 0; + let squareBracketCount = 0; + let curlyBracketCount = 0; + let index = 0; + for (; index < regularExpressionString.length; ++index) { + switch (regularExpressionString[index]) { + case '\\': + // escape sequence; skip the next character + ++index; + break; + case '(': + roundBracketCount += 1; + break; + case ')': + roundBracketCount -= 1; + break; + case '[': + squareBracketCount += 1; + break; + case ']': + squareBracketCount -= 1; + break; + case '{': + curlyBracketCount += 1; + break; + case '}': + curlyBracketCount -= 1; + break; + case '|': + if ( + roundBracketCount === 0 && + squareBracketCount === 0 && + curlyBracketCount === 0 + ) { + slicedRegex = this.removeOuterRoundBrackets( + regularExpressionString.slice(lastSliceIndex, index) + ); + result.push(slicedRegex); + lastSliceIndex = index + 1; + } + break; + } + } + slicedRegex = this.removeOuterRoundBrackets( + regularExpressionString.slice(lastSliceIndex, index) + ); + result.push(slicedRegex); + return result; + } + + private sliceRegexByThen(regularExpressionString: string): string[][] { + // the actual result + const resultStart = []; + // the remainder of the regex in each case + const resultRemainder = []; + let roundBracketCount = 0; + let squareBracketCount = 0; + let curlyBracketCount = 0; + for (let index = 0; index < regularExpressionString.length; ++index) { + switch (regularExpressionString[index]) { + case '\\': + // escape sequence; skip the next character + ++index; + break; + case '(': + roundBracketCount += 1; + break; + case ')': + roundBracketCount -= 1; + break; + case '[': + squareBracketCount += 1; + break; + case ']': + squareBracketCount -= 1; + break; + case '{': + curlyBracketCount += 1; + break; + case '}': + curlyBracketCount -= 1; + break; + } + if ( + roundBracketCount === 0 && + squareBracketCount === 0 && + curlyBracketCount === 0 + ) { + if (!this.isQuantifier(regularExpressionString[index + 1])) { + resultStart.push(regularExpressionString.slice(0, index + 1)); + resultRemainder.push(regularExpressionString.slice(index + 1)); + } else { + // let minimalAmountOfRepeats = parseMinimalAmountOfQuantifier(regularExpressionString.slice(index + 1)); + // TODO + } + } + } + return [resultStart, resultRemainder]; + } + + suggestion(beginning: string, regularExpressionString: string): string { + if (new RegExp(regularExpressionString).test(beginning)) { + // TODO: RETURN AN EMPTY STRING + return 'YA ES IGUAL, NO HAY MÁS QUE SUGERIR'; + } + const regexOptions = this.sliceRegexByOr(regularExpressionString); + if (regexOptions.length > 1) { + for ( + let regexOptionIndex = 0; + regexOptionIndex < regexOptions.length; + ++regexOptionIndex + ) { + const regexParts = this.sliceRegexByThen( + regexOptions[regexOptionIndex] + ); + const regexPartsStarts = regexParts[0]; + const regexPartsRemainders = regexParts[1]; + // for each option, test if the first part of the regex matches + // if it doesn't, continue + // if it does, keep checking until what part it matches + if (!new RegExp(regexPartsStarts[0]).test(beginning)) { + // if there are no more options + if (regexOptionIndex === regexOptions.length - 1) { + // we return the first option, but we could return any option + + // TODO: RETURN ANY TEXT THAT MATCHES regexOptions[0] + return regexOptions[0]; + } + } else { + for ( + let regexPartIndex = 1; + regexPartIndex < regexPartsStarts.length; + ++regexPartIndex + ) { + if (!new RegExp(regexPartsStarts[regexPartIndex]).test(beginning)) { + // TODO: RETURN ANY TEXT THAT MATCHES regexPartsRemainders[regexPartIndex - 1] + return regexPartsRemainders[regexPartIndex - 1]; + } + } + } + } + } else if (regexOptions.length === 1) { + const regexParts = this.sliceRegexByThen(regexOptions[0]); + const regexPartsStarts = regexParts[0]; + const regexPartsRemainders = regexParts[1]; + if (!new RegExp(regexPartsStarts[0]).test(beginning)) { + // TODO: RETURN ANY TEXT THAT MATCHES regularExpressionString + return regularExpressionString; + } else { + for ( + let regexPartIndex = 1; + regexPartIndex < regexPartsStarts.length; + ++regexPartIndex + ) { + if (!new RegExp(regexPartsStarts[regexPartIndex]).test(beginning)) { + // TODO: RETURN ANY TEXT THAT MATCHES regexPartsRemainders[regexPartIndex - 1] + return regexPartsRemainders[regexPartIndex - 1]; + } + } + } + } + // TODO: RETURN AN EMPTY STRING + return 'NO DEBERÍA SER POSIBLE'; + } +} From f21b8d89848209cc96072ccd194f8437f5e46553 Mon Sep 17 00:00:00 2001 From: Javier Centeno Vega Date: Thu, 7 Oct 2021 14:42:52 +0200 Subject: [PATCH 2/7] Enable full suggestions for regex --- projects/lux/src/lib/input/regexp.service.ts | 226 +++++++++++++------ 1 file changed, 161 insertions(+), 65 deletions(-) diff --git a/projects/lux/src/lib/input/regexp.service.ts b/projects/lux/src/lib/input/regexp.service.ts index 6247db17..6458245d 100644 --- a/projects/lux/src/lib/input/regexp.service.ts +++ b/projects/lux/src/lib/input/regexp.service.ts @@ -7,6 +7,22 @@ import { Injectable } from '@angular/core'; export class RegexpService { constructor() {} + private joinStrings( + stringArray: string[], + startIndex: number, + endIndex: number + ): string { + let result = ''; + for ( + let joinStringsIndex = startIndex; + joinStringsIndex < endIndex; + ++joinStringsIndex + ) { + result += stringArray[joinStringsIndex]; + } + return result; + } + private removeOuterRoundBrackets(regularExpressionString: string): string { while ( regularExpressionString[0] === '(' && @@ -39,9 +55,18 @@ export class RegexpService { case '+': return 1; case '{': - for (let index = 1; index < quantifier.length; ++index) { - if (quantifier[index] < '0' || quantifier[index] > '9') { - return Number(quantifier.slice(1, index)); + for ( + let parseMinimalAmountOfQuantifierIndex = 1; + parseMinimalAmountOfQuantifierIndex < quantifier.length; + ++parseMinimalAmountOfQuantifierIndex + ) { + if ( + quantifier[parseMinimalAmountOfQuantifierIndex] < '0' || + quantifier[parseMinimalAmountOfQuantifierIndex] > '9' + ) { + return Number( + quantifier.slice(1, parseMinimalAmountOfQuantifierIndex) + ); } } } @@ -55,12 +80,16 @@ export class RegexpService { let roundBracketCount = 0; let squareBracketCount = 0; let curlyBracketCount = 0; - let index = 0; - for (; index < regularExpressionString.length; ++index) { - switch (regularExpressionString[index]) { + let sliceRegexByOrIndex = 0; + for ( + ; + sliceRegexByOrIndex < regularExpressionString.length; + ++sliceRegexByOrIndex + ) { + switch (regularExpressionString[sliceRegexByOrIndex]) { case '\\': // escape sequence; skip the next character - ++index; + ++sliceRegexByOrIndex; break; case '(': roundBracketCount += 1; @@ -87,34 +116,37 @@ export class RegexpService { curlyBracketCount === 0 ) { slicedRegex = this.removeOuterRoundBrackets( - regularExpressionString.slice(lastSliceIndex, index) + regularExpressionString.slice(lastSliceIndex, sliceRegexByOrIndex) ); result.push(slicedRegex); - lastSliceIndex = index + 1; + lastSliceIndex = sliceRegexByOrIndex + 1; } break; } } slicedRegex = this.removeOuterRoundBrackets( - regularExpressionString.slice(lastSliceIndex, index) + regularExpressionString.slice(lastSliceIndex, sliceRegexByOrIndex) ); result.push(slicedRegex); return result; } - private sliceRegexByThen(regularExpressionString: string): string[][] { - // the actual result - const resultStart = []; - // the remainder of the regex in each case - const resultRemainder = []; + private sliceRegexByThen(regularExpressionString: string): string[] { + const result = []; + let slicedRegex = ''; + let lastSliceIndex = 0; let roundBracketCount = 0; let squareBracketCount = 0; let curlyBracketCount = 0; - for (let index = 0; index < regularExpressionString.length; ++index) { - switch (regularExpressionString[index]) { + for ( + let sliceRegexByThenIndex = 0; + sliceRegexByThenIndex < regularExpressionString.length; + ++sliceRegexByThenIndex + ) { + switch (regularExpressionString[sliceRegexByThenIndex]) { case '\\': // escape sequence; skip the next character - ++index; + ++sliceRegexByThenIndex; break; case '(': roundBracketCount += 1; @@ -140,80 +172,144 @@ export class RegexpService { squareBracketCount === 0 && curlyBracketCount === 0 ) { - if (!this.isQuantifier(regularExpressionString[index + 1])) { - resultStart.push(regularExpressionString.slice(0, index + 1)); - resultRemainder.push(regularExpressionString.slice(index + 1)); + if ( + !this.isQuantifier(regularExpressionString[sliceRegexByThenIndex + 1]) + ) { + slicedRegex = this.removeOuterRoundBrackets( + regularExpressionString.slice( + lastSliceIndex, + sliceRegexByThenIndex + 1 + ) + ); + result.push(slicedRegex); + lastSliceIndex = sliceRegexByThenIndex + 1; } else { - // let minimalAmountOfRepeats = parseMinimalAmountOfQuantifier(regularExpressionString.slice(index + 1)); - // TODO + if (regularExpressionString[sliceRegexByThenIndex + 1] === '{') { + // regex without the quantifier + slicedRegex = this.removeOuterRoundBrackets( + regularExpressionString.slice( + lastSliceIndex, + sliceRegexByThenIndex + 1 + ) + ); + // minimal amount of repeats that the regex allows + const minimalAmountOfRepeats = this.parseMinimalAmountOfQuantifier( + regularExpressionString.slice(sliceRegexByThenIndex + 1) + ); + // skip the quantifier if it's of the form {,} + while (regularExpressionString[sliceRegexByThenIndex] !== '}') { + sliceRegexByThenIndex = sliceRegexByThenIndex + 1; + } + // turn a regex of the form x{a,b} into xxxxxx... repeated a times + for (let repeats = 0; repeats < minimalAmountOfRepeats; ++repeats) { + result.push(slicedRegex); + } + lastSliceIndex = sliceRegexByThenIndex + 1; + } } } } - return [resultStart, resultRemainder]; + return result; + } + + suggestOneCharacter( + regularExpressionString: string, + invert: boolean = false + ): string { + if (regularExpressionString[0] === '\\') { + switch (regularExpressionString[1]) { + case 'd': + return invert ? 'a' : '0'; + case 'D': + return invert ? '0' : 'a'; + case 's': + return invert ? '_' : ' '; + case 'S': + return invert ? ' ' : '_'; + case 'w': + return invert ? ' ' : '_'; + case 'W': + return invert ? '_' : ' '; + default: + return regularExpressionString[1]; + } + } + if ( + regularExpressionString[0] === '[' || + regularExpressionString[0] === '(' + ) { + return this.suggestOneCharacter(regularExpressionString.slice(1), invert); + } + if (regularExpressionString[0] === '^') { + return this.suggestOneCharacter( + regularExpressionString.slice(1), + !invert + ); + } + return regularExpressionString[0]; + } + + suggestAllCharacters(regularExpressionString: string): string { + const regexOptions = this.sliceRegexByOr(regularExpressionString); + const regexParts = this.sliceRegexByThen(regexOptions[0]); + if (regexOptions.length > 1 || regexParts.length > 1) { + let suggestionResult = ''; + for (const regexPart of regexParts) { + suggestionResult += this.suggestAllCharacters(regexPart); + } + return suggestionResult; + } else { + return this.suggestOneCharacter(regexParts[0]); + } + return ''; } suggestion(beginning: string, regularExpressionString: string): string { if (new RegExp(regularExpressionString).test(beginning)) { - // TODO: RETURN AN EMPTY STRING - return 'YA ES IGUAL, NO HAY MÁS QUE SUGERIR'; + return ''; } const regexOptions = this.sliceRegexByOr(regularExpressionString); - if (regexOptions.length > 1) { - for ( - let regexOptionIndex = 0; - regexOptionIndex < regexOptions.length; - ++regexOptionIndex - ) { - const regexParts = this.sliceRegexByThen( - regexOptions[regexOptionIndex] - ); - const regexPartsStarts = regexParts[0]; - const regexPartsRemainders = regexParts[1]; + for ( + let regexOptionIndex = 0; + regexOptionIndex < regexOptions.length; + ++regexOptionIndex + ) { + const regexParts = this.sliceRegexByThen(regexOptions[regexOptionIndex]); + if (regexOptions.length > 1 || regexParts.length > 1) { // for each option, test if the first part of the regex matches // if it doesn't, continue // if it does, keep checking until what part it matches - if (!new RegExp(regexPartsStarts[0]).test(beginning)) { + if (!new RegExp(regexParts[0]).test(beginning)) { // if there are no more options if (regexOptionIndex === regexOptions.length - 1) { // we return the first option, but we could return any option - - // TODO: RETURN ANY TEXT THAT MATCHES regexOptions[0] - return regexOptions[0]; + return this.suggestAllCharacters(regexOptions[0]); } } else { for ( let regexPartIndex = 1; - regexPartIndex < regexPartsStarts.length; + regexPartIndex < regexParts.length; ++regexPartIndex ) { - if (!new RegExp(regexPartsStarts[regexPartIndex]).test(beginning)) { - // TODO: RETURN ANY TEXT THAT MATCHES regexPartsRemainders[regexPartIndex - 1] - return regexPartsRemainders[regexPartIndex - 1]; + if ( + !new RegExp( + this.joinStrings(regexParts, 0, regexPartIndex + 1) + ).test(beginning) + ) { + const remainingRegexToBeMatched = this.joinStrings( + regexParts, + regexPartIndex, + regexParts.length + ); + return this.suggestAllCharacters(remainingRegexToBeMatched); } } } - } - } else if (regexOptions.length === 1) { - const regexParts = this.sliceRegexByThen(regexOptions[0]); - const regexPartsStarts = regexParts[0]; - const regexPartsRemainders = regexParts[1]; - if (!new RegExp(regexPartsStarts[0]).test(beginning)) { - // TODO: RETURN ANY TEXT THAT MATCHES regularExpressionString - return regularExpressionString; } else { - for ( - let regexPartIndex = 1; - regexPartIndex < regexPartsStarts.length; - ++regexPartIndex - ) { - if (!new RegExp(regexPartsStarts[regexPartIndex]).test(beginning)) { - // TODO: RETURN ANY TEXT THAT MATCHES regexPartsRemainders[regexPartIndex - 1] - return regexPartsRemainders[regexPartIndex - 1]; - } - } + // there's only one part and one option, so a suggestion can be trivial + return this.suggestOneCharacter(regexParts[0]); } } - // TODO: RETURN AN EMPTY STRING - return 'NO DEBERÍA SER POSIBLE'; + return ''; } } From f87a1ca4076e0fccaeefde842f86747ef4c209a8 Mon Sep 17 00:00:00 2001 From: Javier Centeno Vega Date: Mon, 11 Oct 2021 09:30:54 +0200 Subject: [PATCH 3/7] Mask suggestion working --- .../lux/src/lib/input/input.component.html | 98 +++++++++++-------- .../lux/src/lib/input/input.component.scss | 20 ++++ projects/lux/src/lib/input/input.component.ts | 20 ++++ .../input-sample/input-sample.component.html | 10 ++ 4 files changed, 109 insertions(+), 39 deletions(-) diff --git a/projects/lux/src/lib/input/input.component.html b/projects/lux/src/lib/input/input.component.html index 9d7bfe82..d35ac912 100644 --- a/projects/lux/src/lib/input/input.component.html +++ b/projects/lux/src/lib/input/input.component.html @@ -1,47 +1,67 @@
$
- - +> + + +
diff --git a/projects/lux/src/lib/input/input.component.scss b/projects/lux/src/lib/input/input.component.scss index c0240a20..10ce826e 100644 --- a/projects/lux/src/lib/input/input.component.scss +++ b/projects/lux/src/lib/input/input.component.scss @@ -6,6 +6,26 @@ align-items: stretch; } +.patterned { + font-family: monospace; +} + +.masked { + top: 0px; + left: 0px; + background-color: transparent; + z-index: 0; +} + +.mask { + position: absolute; + top: 0px; + left: 0px; + border-color: transparent; + color: gray; + z-index: -1; +} + .readonly { border: none; diff --git a/projects/lux/src/lib/input/input.component.ts b/projects/lux/src/lib/input/input.component.ts index b59bf986..842cd23f 100644 --- a/projects/lux/src/lib/input/input.component.ts +++ b/projects/lux/src/lib/input/input.component.ts @@ -46,7 +46,9 @@ export class InputComponent implements OnInit, ControlValueAccessor, Validator { static idCounter = 0; @ViewChild('input', { static: false }) input: ElementRef; + @ViewChild('inputMask', { static: false }) inputMask: ElementRef; @ViewChild('textarea', { static: false }) textarea: ElementRef; + @ViewChild('textareaMask', { static: false }) textareaMask: ElementRef; touched = false; dirty = false; @@ -171,6 +173,15 @@ export class InputComponent implements OnInit, ControlValueAccessor, Validator { } this._value = v; + if (this._regexp) { + let suggestion; + if (hasValue(v)) { + suggestion = this.regexpService.suggestion(v, this._pattern); + } else { + suggestion = this.regexpService.suggestion('', this._pattern); + } + this.setValueInMaskControl(' '.repeat(v.length) + suggestion); + } this.onChange(v); if (!initialAndEmpty) { this.valueChange.emit(v); @@ -231,6 +242,15 @@ export class InputComponent implements OnInit, ControlValueAccessor, Validator { } } + private setValueInMaskControl(v: any): void { + if (this.inputMask) { + this.inputMask.nativeElement.value = v; + } + if (this.textareaMask) { + this.textareaMask.nativeElement.value = v; + } + } + // Validator interface registerOnValidatorChange(): void {} diff --git a/src/app/input-sample/input-sample.component.html b/src/app/input-sample/input-sample.component.html index aacf93b3..429dbb70 100644 --- a/src/app/input-sample/input-sample.component.html +++ b/src/app/input-sample/input-sample.component.html @@ -81,6 +81,16 @@

Required

+ +

Pattern

+
+    
+      <lux-input aria-label="Pattern example" pattern="\\w+@\\w+\\.[a-z]{2,3}"></lux-input>
+      
+
+ +
+

Types

From 551cafc2a220d0405e9896dfc0187e1bd61f0a7c Mon Sep 17 00:00:00 2001 From: Javier Centeno Vega Date: Mon, 11 Oct 2021 10:08:54 +0200 Subject: [PATCH 4/7] Fix mask style --- projects/lux/src/lib/input/input.component.scss | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/projects/lux/src/lib/input/input.component.scss b/projects/lux/src/lib/input/input.component.scss index 10ce826e..4b0c4e93 100644 --- a/projects/lux/src/lib/input/input.component.scss +++ b/projects/lux/src/lib/input/input.component.scss @@ -11,7 +11,10 @@ } .masked { - top: 0px; + position: relative; + padding-top: 0.2rem; + padding-bottom: 0.2rem; + bottom: 0px; left: 0px; background-color: transparent; z-index: 0; @@ -19,7 +22,9 @@ .mask { position: absolute; - top: 0px; + padding-top: 0.2rem; + padding-bottom: 0.2rem; + bottom: 0px; left: 0px; border-color: transparent; color: gray; From 2e4faaa349520e5324287c86c82d7750144e1d5e Mon Sep 17 00:00:00 2001 From: Javier Centeno Vega Date: Wed, 13 Oct 2021 08:37:52 +0200 Subject: [PATCH 5/7] Assume simplest option if no options match --- projects/lux/src/lib/input/regexp.service.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/projects/lux/src/lib/input/regexp.service.ts b/projects/lux/src/lib/input/regexp.service.ts index 6458245d..602dec18 100644 --- a/projects/lux/src/lib/input/regexp.service.ts +++ b/projects/lux/src/lib/input/regexp.service.ts @@ -282,8 +282,12 @@ export class RegexpService { if (!new RegExp(regexParts[0]).test(beginning)) { // if there are no more options if (regexOptionIndex === regexOptions.length - 1) { - // we return the first option, but we could return any option - return this.suggestAllCharacters(regexOptions[0]); + // we return the shortest option, assuming it's the simplest + return this.suggestAllCharacters( + regexOptions.reduce((a1, a2) => + a1.length <= a2.length ? a1 : a2 + ) + ); } } else { for ( From cbfa3ccd5e63541bc5d77cf5b33fcce60c752f28 Mon Sep 17 00:00:00 2001 From: Javier Centeno Vega Date: Fri, 15 Oct 2021 08:16:21 +0200 Subject: [PATCH 6/7] Remove useless divs --- .../lux/src/lib/input/input.component.html | 114 +++++++++--------- 1 file changed, 55 insertions(+), 59 deletions(-) diff --git a/projects/lux/src/lib/input/input.component.html b/projects/lux/src/lib/input/input.component.html index d35ac912..9f926ce1 100644 --- a/projects/lux/src/lib/input/input.component.html +++ b/projects/lux/src/lib/input/input.component.html @@ -1,67 +1,63 @@
$
-
- - -
-
+ + - -
+ #textarea + class="infix masked patterned" + placement="top" + [id]="inputId" + [attr.value]="value" + [attr.aria-label]="ariaLabel" + [attr.disabled]="disabled === true ? 'true' : undefined" + [attr.readonly]="readonly === true ? 'true' : undefined" + [attr.cols]="cols?.toString() || undefined" + [attr.rows]="rows?.toString() || undefined" + [placeholder]="placeholder" + [ngClass]="className" + (keyup)="onKeyUp(textarea.value)" + (change)="onChangeValue(textarea.value)" + (keypress)="onKeyPress($event)" + (blur)="onLostFocus()" +> +
From d355f930675ee26b149b98bd9db40c196d46e49a Mon Sep 17 00:00:00 2001 From: Javier Centeno Vega Date: Fri, 15 Oct 2021 08:24:50 +0200 Subject: [PATCH 7/7] Make regexp non-injectable --- projects/lux/src/lib/input/regexp.service.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/projects/lux/src/lib/input/regexp.service.ts b/projects/lux/src/lib/input/regexp.service.ts index 602dec18..499c20f1 100644 --- a/projects/lux/src/lib/input/regexp.service.ts +++ b/projects/lux/src/lib/input/regexp.service.ts @@ -1,9 +1,6 @@ -import { Injectable } from '@angular/core'; - /** * A service that holds the functionality for advanced handling of regular expressions */ -@Injectable({ providedIn: 'root' }) export class RegexpService { constructor() {}