Skip to content
This repository was archived by the owner on Sep 8, 2020. It is now read-only.

Commit 3407dfa

Browse files
Merge pull request #139 from isaacplmann/master
Tests and documentation for escChar
2 parents dd9e206 + 0af57a1 commit 3407dfa

File tree

3 files changed

+106
-2
lines changed

3 files changed

+106
-2
lines changed

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,13 +66,16 @@ Inside of `ui-options`, you can customize these four properties:
6666
* `clearOnBlurPlaceholder` - default: `false`,
6767
* `eventsToHandle` - default: `['input', 'keyup', 'click', 'focus']`
6868
* `addDefaultPlaceholder` - default: `true`
69+
* `escChar` - default: `'\\'`
6970

7071
When customizing `eventsToHandle`, `clearOnBlur`, or `addDefaultPlaceholder`, the value you supply will replace the default. To customize `eventsToHandle`, be sure to replace the entire array.
7172

7273
Whereas, `maskDefinitions` is an object, so any custom object you supply will be merged together with the defaults using `angular.extend()`. This allows you to override the defaults selectively, if you wish.
7374

7475
When setting `clearOnBlurPlaceholder` to `true`, it will show the placeholder text instead of the empty mask. It requires the `ui-mask-placeholder` attribute to be set on the input to display properly.
7576

77+
If the `escChar` (\\ by default) is encountered in a mask, the next character will be treated as a literal and not a mask definition key. To disable the `escChar` feature completely, set `escChar` to `null`.
78+
7679
#### Global customization
7780
In addition to customizing behaviors for a specific element, you can also customize the behaviors globally. To do this, simply use the `uiMaskConfig` provider in your app configuration. Example:
7881

src/mask.js

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ angular.module('ui.mask', [])
1010
},
1111
clearOnBlur: true,
1212
clearOnBlurPlaceholder: false,
13+
escChar: '\\',
1314
eventsToHandle: ['input', 'keyup', 'click', 'focus'],
1415
addDefaultPlaceholder: true
1516
})
@@ -373,9 +374,17 @@ angular.module('ui.mask', [])
373374
numberOfOptionalCharacters = 0,
374375
splitMask = mask.split('');
375376

377+
var inEscape = false;
376378
angular.forEach(splitMask, function(chr, i) {
377-
if (linkOptions.maskDefinitions[chr]) {
378-
379+
if (inEscape) {
380+
inEscape = false;
381+
maskPlaceholder += chr;
382+
characterCount++;
383+
}
384+
else if (linkOptions.escChar === chr) {
385+
inEscape = true;
386+
}
387+
else if (linkOptions.maskDefinitions[chr]) {
379388
maskCaretMap.push(characterCount);
380389

381390
maskPlaceholder += getPlaceholderChar(i - numberOfOptionalCharacters);

test/maskSpec.js

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,98 @@ describe("uiMask", function () {
379379
});
380380
});
381381

382+
describe("escChar", function () {
383+
it("should escape default mask definitions", function() {
384+
var escapeHtml = "<input name='input' ng-model='x' ui-mask='{{mask}}'>",
385+
input = compileElement(escapeHtml);
386+
scope.$apply(function() {
387+
scope.x = '';
388+
scope.mask = '\\A\\9\\*\\?*';
389+
});
390+
expect(input.attr("placeholder")).toBe("A9*?_");
391+
input.val("a").triggerHandler("input");
392+
expect(input.val()).toBe("A9*?a");
393+
});
394+
it("should not confuse entered values with escaped values", function() {
395+
var escapeHtml = "<input name='input' ng-model='x' ui-mask='{{mask}}'>",
396+
input = compileElement(escapeHtml);
397+
scope.$apply(function() {
398+
scope.x = '';
399+
scope.mask = '\\A\\9\\*\\?****';
400+
});
401+
expect(input.attr("placeholder")).toBe("A9*?____");
402+
input.val("A9A9").triggerHandler("input");
403+
expect(input.val()).toBe("A9*?A9A9");
404+
});
405+
it("should escape custom mask definitions", function() {
406+
scope.options = {
407+
maskDefinitions: {
408+
"Q": /[Qq]/
409+
}
410+
};
411+
var input = compileElement(inputHtml);
412+
scope.$apply(function() {
413+
scope.x = '';
414+
scope.mask = '\\QQ';
415+
});
416+
expect(input.attr("placeholder")).toBe("Q_");
417+
input.val("q").triggerHandler("input");
418+
expect(input.val()).toBe("Qq");
419+
});
420+
it("should escape normal characters", function() {
421+
var input = compileElement(inputHtml);
422+
scope.$apply(function() {
423+
scope.x = '';
424+
scope.mask = '\\W*';
425+
});
426+
expect(input.attr("placeholder")).toBe("W_");
427+
input.val("q").triggerHandler("input");
428+
expect(input.val()).toBe("Wq");
429+
});
430+
it("should escape itself", function() {
431+
var escapeHtml = "<input name='input' ng-model='x' ui-mask='{{mask}}'>",
432+
input = compileElement(escapeHtml);
433+
scope.$apply(function() {
434+
scope.x = '';
435+
scope.mask = '\\\\*';
436+
});
437+
scope.$apply("x = ''");
438+
scope.$apply("mask = '\\\\\\\\*'");
439+
expect(input.attr("placeholder")).toBe("\\_");
440+
input.val("a").triggerHandler("input");
441+
expect(input.val()).toBe("\\a");
442+
});
443+
it("should change the escape character", function() {
444+
scope.options = {
445+
escChar: '!',
446+
maskDefinitions: {
447+
"Q": /[Qq]/
448+
}
449+
};
450+
var input = compileElement(inputHtml);
451+
scope.$apply(function() {
452+
scope.x = '';
453+
scope.mask = '\\!A!9!*!Q!!!W*';
454+
});
455+
expect(input.attr("placeholder")).toBe("\\A9*Q!W_");
456+
input.val("a").triggerHandler("input");
457+
expect(input.val()).toBe("\\A9*Q!Wa");
458+
});
459+
it("should use null to mean no escape character", function() {
460+
scope.options = {
461+
escChar: null,
462+
};
463+
var input = compileElement(inputHtml);
464+
scope.$apply(function() {
465+
scope.x = '';
466+
scope.mask = '\\!A!9!*!!*';
467+
});
468+
expect(input.attr("placeholder")).toBe("\\!_!_!_!!_");
469+
input.val("a").triggerHandler("input");
470+
expect(input.val()).toBe("\\!a!_!_!!_");
471+
});
472+
});
473+
382474
describe("placeholders", function () {
383475
it("should have default placeholder functionality", function() {
384476
var input = compileElement(inputHtml);

0 commit comments

Comments
 (0)