Skip to content

Commit f40b11e

Browse files
authored
Merge branch 'master' into mdragnev/fix-12316
2 parents 1f5c211 + 7498e03 commit f40b11e

File tree

6 files changed

+70
-26
lines changed

6 files changed

+70
-26
lines changed

gulpfile.js

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,10 @@ function typedocBuildDocsEN(cb) {
248248
}
249249

250250
const SASSDOC = {
251-
PROJECT_PATH: path.join(__dirname, 'projects', 'igniteui-angular', 'src', 'lib', 'core', 'styles'),
251+
PROJECT_PATHS: [
252+
`${path.join(__dirname, 'projects', 'igniteui-angular', 'src', 'lib', 'core', 'styles')}/**/*.scss`,
253+
`${path.join(__dirname, 'node_modules', 'igniteui-theming', 'sass')}/**/*.scss`
254+
],
252255
DEST: path.join(DOCS_OUTPUT_PATH, 'sass'),
253256
OPTIONS: path.join(__dirname, '.sassdocrc'),
254257
};
@@ -266,7 +269,7 @@ function sassdocBuildJson(cb) {
266269
options.convert = convert;
267270
options.exportDir = exportDir;
268271

269-
gulp.src(`${SASSDOC.PROJECT_PATH}/**/*.scss`)
272+
gulp.src(SASSDOC.PROJECT_PATHS)
270273
.pipe(sassdoc(options));
271274

272275
cb();
@@ -282,7 +285,7 @@ function sassdocImportJson(cb) {
282285
options.json_dir = importDir;
283286
options.shellStringsPath = path.join(__dirname, 'extras', 'template', 'strings', 'shell-strings.json');
284287

285-
gulp.src(`${SASSDOC.PROJECT_PATH}/**/*.scss`)
288+
gulp.src(SASSDOC.PROJECT_PATHS)
286289
.pipe(sassdoc(options));
287290

288291
cb();
@@ -297,7 +300,7 @@ function sassdocBuildJA(cb) {
297300
options.json_dir = pathTranslations;
298301
options.shellStringsPath = path.join(__dirname, 'extras', 'template', 'strings', 'shell-strings.json');
299302

300-
gulp.src(`${SASSDOC.PROJECT_PATH}/**/*.scss`)
303+
gulp.src(SASSDOC.PROJECT_PATHS)
301304
.pipe(sassdoc(options));
302305

303306
cb();
@@ -309,7 +312,7 @@ function sassdocBuildEN(cb) {
309312
options.lang = 'en';
310313
options.shellStringsPath = path.join(__dirname, 'extras', 'template', 'strings', 'shell-strings.json');
311314

312-
gulp.src(`${SASSDOC.PROJECT_PATH}/**/*.scss`)
315+
gulp.src(SASSDOC.PROJECT_PATHS)
313316
.pipe(sassdoc(options));
314317

315318
cb();

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@
114114
"hammer-simulator": "0.0.1",
115115
"ig-typedoc-theme": "^4.2.0",
116116
"igniteui-sassdoc-theme": "^1.1.4",
117-
"igniteui-theming": "^1.1.2",
117+
"igniteui-theming": "^1.1.4",
118118
"igniteui-webcomponents": "^4.0.0",
119119
"jasmine": "^4.5.0",
120120
"jasmine-core": "~4.5.0",
@@ -128,7 +128,7 @@
128128
"postcss-scss": "^4.0.3",
129129
"sass": "^1.56.0",
130130
"sass-true": "^6.0.1",
131-
"sassdoc": "^2.7.3",
131+
"sassdoc": "^2.7.4",
132132
"sassdoc-plugin-localization": "^1.4.3",
133133
"stylelint": "^14.15.0",
134134
"stylelint-scss": "^4.1.0",

projects/igniteui-angular/src/lib/directives/mask/mask-parsing.service.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ export interface Replaced {
2020
providedIn: 'root'
2121
})
2222
export class MaskParsingService {
23-
public applyMask(inputVal: string, maskOptions: MaskOptions): string {
23+
public applyMask(inputVal: string, maskOptions: MaskOptions, pos: number = 0): string {
2424
let outputVal = '';
2525
let value = '';
2626
const mask: string = maskOptions.format;
@@ -60,7 +60,6 @@ export class MaskParsingService {
6060
nonLiteralValues.splice(nonLiteralIndices.length);
6161
}
6262

63-
let pos = 0;
6463
for (const nonLiteralValue of nonLiteralValues) {
6564
const char = nonLiteralValue;
6665
outputVal = this.replaceCharAt(outputVal, nonLiteralIndices[pos++], char);
@@ -115,7 +114,13 @@ export class MaskParsingService {
115114
maskedValue = this.replaceCharAt(maskedValue, i, char);
116115
}
117116

118-
return { value: maskedValue, end: cursor };
117+
if (Math.abs(end - start) >= 1) {
118+
// set cursor to be max between last cursor pos and the calculated `end`
119+
// since on `delete` the cursor should move forward
120+
cursor = Math.max(cursor, end);
121+
}
122+
123+
return { value: maskedValue, end: cursor};
119124
}
120125

121126
public replaceCharAt(strValue: string, index: number, char: string): string {

projects/igniteui-angular/src/lib/directives/mask/mask.directive.spec.ts

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ describe('igxMask', () => {
2727
OneWayBindComponent,
2828
PipesMaskComponent,
2929
PlaceholderMaskComponent,
30-
EmptyMaskTestComponent,
30+
MaskTestComponent,
3131
ReadonlyMaskTestComponent
3232
],
3333
imports: [
@@ -378,7 +378,7 @@ describe('igxMask', () => {
378378
}));
379379

380380
it('Should display mask on dragenter and remove it on dragleave', fakeAsync(() => {
381-
const fixture = TestBed.createComponent(EmptyMaskTestComponent);
381+
const fixture = TestBed.createComponent(MaskTestComponent);
382382
fixture.detectChanges();
383383
const input = fixture.componentInstance.input;
384384

@@ -390,6 +390,17 @@ describe('igxMask', () => {
390390

391391
input.nativeElement.dispatchEvent(new DragEvent('dragleave'));
392392
expect(input.nativeElement.value).toEqual('');
393+
394+
// should preserve state on dragenter
395+
input.nativeElement.dispatchEvent(new Event('focus'));
396+
UIInteractions.simulatePaste('76', fixture.debugElement.query(By.css('.igx-input-group__input')), 3, 3);
397+
fixture.detectChanges();
398+
399+
input.nativeElement.dispatchEvent(new Event('blur'));
400+
expect(input.nativeElement.value).toEqual('___76_____');
401+
402+
input.nativeElement.dispatchEvent(new DragEvent('dragenter'));
403+
expect(input.nativeElement.value).toEqual('___76_____');
393404
}));
394405

395406
it('Apply display and input pipes on blur and focus.', fakeAsync(() => {
@@ -485,6 +496,29 @@ describe('igxMask', () => {
485496
expect(fixture.componentInstance.maskDirective.mask).toEqual('##.##');
486497
expect(input.nativeElement.placeholder).toEqual('##.##');
487498
}));
499+
500+
it('should update input properly on selection with DELETE', () => {
501+
const fixture = TestBed.createComponent(MaskComponent);
502+
fixture.detectChanges();
503+
const inputElement = fixture.debugElement.query(By.css('input'));
504+
inputElement.triggerEventHandler('focus');
505+
UIInteractions.simulatePaste('1234567890', inputElement, 1, 1);
506+
fixture.detectChanges();
507+
expect(inputElement.nativeElement.value).toEqual('(123) 4567-890');
508+
509+
const inputHTMLElement = inputElement.nativeElement as HTMLInputElement;
510+
inputHTMLElement.setSelectionRange(6, 8);
511+
fixture.detectChanges();
512+
expect(inputElement.nativeElement.selectionStart).toEqual(6);
513+
expect(inputElement.nativeElement.selectionEnd).toEqual(8);
514+
515+
UIInteractions.triggerEventHandlerKeyDown('Delete', inputElement);
516+
inputElement.triggerEventHandler('input', { inputType: 'test' });
517+
fixture.detectChanges();
518+
expect(inputElement.nativeElement.selectionStart).toEqual(8);
519+
expect(inputElement.nativeElement.selectionEnd).toEqual(8);
520+
expect(inputHTMLElement.value).toEqual('(123) __67-890');
521+
});
488522
});
489523

490524
describe('igxMaskDirective ControlValueAccessor Unit', () => {
@@ -728,7 +762,7 @@ class PipesMaskComponent {
728762
</igx-input-group>
729763
`
730764
})
731-
class EmptyMaskTestComponent {
765+
class MaskTestComponent {
732766
@ViewChild('input', { static: true })
733767
public input: ElementRef;
734768
}

projects/igniteui-angular/src/lib/directives/mask/mask.directive.ts

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -220,17 +220,19 @@ export class IgxMaskDirective implements OnInit, AfterViewChecked, ControlValueA
220220
numberOfMaskLiterals++;
221221
}
222222
}
223-
this.inputValue = isInputComplete?
223+
this.inputValue = isInputComplete ?
224224
this.inputValue.substring(0, this.selectionEnd - numberOfMaskLiterals) + this.inputValue.substring(this.selectionEnd)
225-
: this._compositionValue.substring(0, this._compositionStartIndex);
226-
227-
this._start = this.selectionStart;
228-
this._end = this.selectionEnd;
229-
this.nativeElement.selectionStart = isInputComplete ? this._start - numberOfMaskLiterals : this._compositionStartIndex;
230-
this.nativeElement.selectionEnd = this._end - numberOfMaskLiterals;
231-
this.nativeElement.selectionEnd = this._end;
232-
this._start = this.selectionStart;
233-
this._end = this.selectionEnd;
225+
: this._compositionValue?.substring(0, this._compositionStartIndex) || this.inputValue;
226+
227+
if (this._compositionValue) {
228+
this._start = this.selectionStart;
229+
this._end = this.selectionEnd;
230+
this.nativeElement.selectionStart = isInputComplete ? this._start - numberOfMaskLiterals : this._compositionStartIndex;
231+
this.nativeElement.selectionEnd = this._end - numberOfMaskLiterals;
232+
this.nativeElement.selectionEnd = this._end;
233+
this._start = this.selectionStart;
234+
this._end = this.selectionEnd;
235+
}
234236
}
235237

236238
if (this._hasDropAction) {
@@ -281,7 +283,7 @@ export class IgxMaskDirective implements OnInit, AfterViewChecked, ControlValueA
281283
/** @hidden */
282284
@HostListener('dragenter')
283285
public onDragEnter(): void {
284-
if (!this._focused) {
286+
if (!this._focused && !this._dataValue) {
285287
this.showMask(this._dataValue);
286288
}
287289
}

0 commit comments

Comments
 (0)