Skip to content

Commit ce18d9c

Browse files
Some fix when using isRevealingMask: true
- Create remove method and use it in backspace and input in a selection replace with placeholders on isRevealingMask: false and delete on true - Won't set placeholders when do backspace or input in a selection - Just move de selection to the next editable on input not after the input
1 parent 2e280bb commit ce18d9c

File tree

2 files changed

+83
-48
lines changed

2 files changed

+83
-48
lines changed

lib/index.js

Lines changed: 73 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,10 @@ Pattern.prototype.formatValue = function format(value) {
138138
var valueBuffer = new Array(this.length)
139139
var valueIndex = 0
140140

141+
if (this.isRevealingMask && value.length === 0) {
142+
return valueBuffer
143+
}
144+
141145
for (var i = 0, l = this.length; i < l; i++) {
142146
if (this.isEditableIndex(i)) {
143147
if (this.isRevealingMask &&
@@ -233,40 +237,44 @@ InputMask.prototype.input = function input(char) {
233237

234238
var inputIndex = this.selection.start
235239

236-
// If the cursor or selection is prior to the first editable character, make
237-
// sure any input given is applied to it.
238-
if (inputIndex < this.pattern.firstEditableIndex) {
239-
inputIndex = this.pattern.firstEditableIndex
240+
// Find next editable index
241+
var nextEditableIndex = inputIndex
242+
while (!this.pattern.isEditableIndex(nextEditableIndex)) {
243+
if (nextEditableIndex > this.pattern.lastEditableIndex) {
244+
return false
245+
}
246+
nextEditableIndex++
240247
}
241248

242-
// Bail out or add the character to input
243-
if (this.pattern.isEditableIndex(inputIndex)) {
244-
if (!this.pattern.isValidAtIndex(char, inputIndex)) {
245-
return false
249+
if (!this.pattern.isValidAtIndex(char, nextEditableIndex)) {
250+
return false
251+
}
252+
253+
// Add statics until next editable
254+
while (inputIndex < nextEditableIndex) {
255+
this.value[inputIndex] = this.pattern.pattern[inputIndex]
256+
inputIndex++
257+
}
258+
259+
this.value[inputIndex] = this.pattern.transform(char, inputIndex)
260+
261+
// If this is the last editable index fill with the rest
262+
if (inputIndex === this.pattern.lastEditableIndex) {
263+
while (inputIndex + 1 < this.pattern.length - 1) {
264+
inputIndex++
265+
this.value[inputIndex] = this.pattern.pattern[inputIndex]
246266
}
247-
this.value[inputIndex] = this.pattern.transform(char, inputIndex)
248267
}
249268

250269
// If multiple characters were selected, blank the remainder out based on the
251270
// pattern.
252-
var end = this.selection.end - 1
253-
while (end > inputIndex) {
254-
if (this.pattern.isEditableIndex(end)) {
255-
this.value[end] = this.placeholderChar
256-
}
257-
end--
271+
if (inputIndex + 1 < this.selection.end) {
272+
this.remove(inputIndex + 1, this.selection.end - 1)
258273
}
259274

260275
// Advance the cursor to the next character
261276
this.selection.start = this.selection.end = inputIndex + 1
262277

263-
// Skip over any subsequent static characters
264-
while (this.pattern.length > this.selection.start &&
265-
!this.pattern.isEditableIndex(this.selection.start)) {
266-
this.selection.start++
267-
this.selection.end++
268-
}
269-
270278
// History
271279
if (this._historyIndex != null) {
272280
// Took more input after undoing, so blow any subsequent history away
@@ -299,26 +307,26 @@ InputMask.prototype.backspace = function backspace() {
299307
var selectionBefore = copy(this.selection)
300308
var valueBefore = this.getValue()
301309

302-
// No range selected - work on the character preceding the cursor
310+
// No range selected
303311
if (this.selection.start === this.selection.end) {
304-
if (this.pattern.isEditableIndex(this.selection.start - 1)) {
305-
this.value[this.selection.start - 1] = this.placeholderChar
312+
var previousEditableIndex = this.selection.start - 1
313+
314+
while (!this.pattern.isEditableIndex(previousEditableIndex)) {
315+
if (previousEditableIndex === 0) {
316+
break
317+
}
318+
previousEditableIndex--
306319
}
307-
this.selection.start--
308-
this.selection.end--
320+
321+
this.remove(previousEditableIndex, this.selection.end)
322+
this.selection.start = previousEditableIndex
309323
}
310-
// Range selected - delete characters and leave the cursor at the start of the selection
311324
else {
312-
var end = this.selection.end - 1
313-
while (end >= this.selection.start) {
314-
if (this.pattern.isEditableIndex(end)) {
315-
this.value[end] = this.placeholderChar
316-
}
317-
end--
318-
}
319-
this.selection.end = this.selection.start
325+
this.remove(this.selection.start, this.selection.end - 1)
320326
}
321327

328+
this.selection.end = this.selection.start
329+
322330
// History
323331
if (this._historyIndex != null) {
324332
// Took more input after undoing, so blow any subsequent history away
@@ -381,7 +389,7 @@ InputMask.prototype.paste = function paste(input) {
381389
if (!valid) {
382390
if (this.selection.start > 0) {
383391
// XXX This only allows for one static character to be skipped
384-
var patternIndex = this.selection.start - 1
392+
var patternIndex = this.selection.start
385393
if (!this.pattern.isEditableIndex(patternIndex) &&
386394
input.charAt(i) === this.pattern.pattern[patternIndex]) {
387395
continue
@@ -395,6 +403,34 @@ InputMask.prototype.paste = function paste(input) {
395403
return true
396404
}
397405

406+
InputMask.prototype.remove = function remove(start, end) {
407+
if (this.pattern.isRevealingMask) {
408+
this.value.splice(start, end - start)
409+
410+
var index = start
411+
while (index < this.value.length) {
412+
if (!this.pattern.isEditableIndex(index)) {
413+
this.value.splice(index, 0, this.pattern.pattern[index])
414+
index++
415+
}
416+
else if (this.pattern.isValidAtIndex(this.value[index], index)) {
417+
index++
418+
}
419+
else {
420+
this.value.splice(index, 1)
421+
}
422+
}
423+
}
424+
else {
425+
while (end >= start) {
426+
if (this.pattern.isEditableIndex(end)) {
427+
this.value[end] = this.placeholderChar
428+
}
429+
end--
430+
}
431+
}
432+
}
433+
398434
// History
399435

400436
InputMask.prototype.undo = function undo() {

test/index.js

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ test('Escaping placeholder characters', function(t) {
143143
})
144144

145145
test('Basic input', function(t) {
146-
t.plan(23)
146+
t.plan(26)
147147

148148
var mask = new InputMask({
149149
pattern: '1111 1111 1111 1111'
@@ -156,18 +156,21 @@ test('Basic input', function(t) {
156156
t.true(mask.input('2'), 'Valid input accepted')
157157
t.true(mask.input('3'), 'Valid input accepted')
158158
t.true(mask.input('4'), 'Valid input accepted')
159-
t.deepEqual(mask.selection, {start: 5, end: 5}, 'Skipped over blank')
159+
t.deepEqual(mask.selection, {start: 4, end: 4}, 'Keep in position')
160160
t.true(mask.input('1'), 'Valid input accepted')
161+
t.deepEqual(mask.selection, {start: 6, end: 6}, 'Skipped over blank after input')
161162
t.true(mask.input('2'), 'Valid input accepted')
162163
t.true(mask.input('3'), 'Valid input accepted')
163164
t.true(mask.input('4'), 'Valid input accepted')
164-
t.deepEqual(mask.selection, {start: 10, end: 10}, 'Skipped over blank')
165+
t.deepEqual(mask.selection, {start: 9, end: 9}, 'Keep in position')
165166
t.true(mask.input('1'), 'Valid input accepted')
167+
t.deepEqual(mask.selection, {start: 11, end: 11}, 'Skipped over blank')
166168
t.true(mask.input('2'), 'Valid input accepted')
167169
t.true(mask.input('3'), 'Valid input accepted')
168170
t.true(mask.input('4'), 'Valid input accepted')
169-
t.deepEqual(mask.selection, {start: 15, end: 15}, 'Skipped over blank')
171+
t.deepEqual(mask.selection, {start: 14, end: 14}, 'Keep in position')
170172
t.true(mask.input('1'), 'Valid input accepted')
173+
t.deepEqual(mask.selection, {start: 16, end: 16}, 'Skipped over blank')
171174
t.true(mask.input('2'), 'Valid input accepted')
172175
t.true(mask.input('3'), 'Valid input accepted')
173176
t.true(mask.input('4'), 'Valid input accepted')
@@ -256,7 +259,7 @@ test('Skipping multiple static characters', function(t) {
256259
})
257260

258261
test('Basic backspacing', function(t) {
259-
t.plan(24)
262+
t.plan(21)
260263

261264
var mask = new InputMask({
262265
pattern: '1111 1111 1111 1111',
@@ -268,22 +271,18 @@ test('Basic backspacing', function(t) {
268271
t.true(mask.backspace(), 'Valid backspace accepted')
269272
t.true(mask.backspace(), 'Valid backspace accepted')
270273
t.true(mask.backspace(), 'Valid backspace accepted')
271-
// Backspacking doesn't automatically skip characters, as we can't tell when
272-
// the user intends to start making input again, so it just steps over static
273-
// parts of the mask when you backspace with the cursor ahead of them.
274-
t.true(mask.backspace(), 'Skipped over blank')
274+
// Backspacking automatically skip characters, and goes to the
275+
// previous valid editable character
275276
t.true(mask.backspace(), 'Valid backspace accepted')
276277
t.true(mask.backspace(), 'Valid backspace accepted')
277278
t.true(mask.backspace(), 'Valid backspace accepted')
278279
t.true(mask.backspace(), 'Valid backspace accepted')
279280
t.equal(mask.getValue(), '1234 1234 ____ ____', 'Intermediate value')
280281
t.deepEqual(mask.selection, {start: 10, end: 10}, 'Cursor remains in front of last deleted character')
281-
t.true(mask.backspace(), 'Skipped over blank')
282282
t.true(mask.backspace(), 'Valid backspace accepted')
283283
t.true(mask.backspace(), 'Valid backspace accepted')
284284
t.true(mask.backspace(), 'Valid backspace accepted')
285285
t.true(mask.backspace(), 'Valid backspace accepted')
286-
t.true(mask.backspace(), 'Skipped over blank')
287286
t.true(mask.backspace(), 'Valid backspace accepted')
288287
t.true(mask.backspace(), 'Valid backspace accepted')
289288
t.true(mask.backspace(), 'Valid backspace accepted')

0 commit comments

Comments
 (0)