Skip to content

Commit 7fe0075

Browse files
committed
Breaking out mask implementation into separate file.
1 parent 9099e81 commit 7fe0075

File tree

3 files changed

+157
-154
lines changed

3 files changed

+157
-154
lines changed

gruntfile.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ module.exports = function(grunt) {
1515
stripBanners: false
1616
},
1717
dist: {
18-
src: ['src/jquery.maskedinput.js'],
18+
src: ['src/jquery.maskedinput.js','src/masks/*.js'],
1919
dest: 'dist/<%= pkg.name %>.js'
2020
}
2121
},

src/jquery.maskedinput.js

Lines changed: 4 additions & 153 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,9 @@
2727
return { begin: begin, end: end };
2828
}
2929

30+
//TODO: alias as maskedinput?
3031
$.mask = {
31-
masks:[],
32+
masks:{},
3233
//Predefined character definitions
3334
//TODO: Move these to the mask def itself.
3435
definitions: {
@@ -41,156 +42,6 @@
4142
placeholder: '_'
4243
};
4344

44-
function FixedWidthMask (mask, settings){
45-
var self=this;
46-
//Build up structures necessary to quickly apply masking
47-
this.settings = settings;
48-
49-
this.tests = [];
50-
this.partialPosition = mask.length;
51-
this.length = mask.length;
52-
53-
var firstNonMaskPos = null;
54-
55-
$.each(mask.split(""), function(i, c) {
56-
if (c == '?') {
57-
self.length--;
58-
self.partialPosition = i;
59-
} else if (settings.definitions[c]) {
60-
self.tests.push(new RegExp(settings.definitions[c]));
61-
if (firstNonMaskPos === null) {
62-
firstNonMaskPos = self.tests.length - 1;
63-
}
64-
} else {
65-
self.tests.push(c);
66-
}
67-
});
68-
}
69-
70-
FixedWidthMask.prototype.applyBackspace = function(input, pos){
71-
var i, buffer = input.split('');
72-
for(i = pos - 1; i >= 0; i--){
73-
if(this.tests[i].test)
74-
break;
75-
}
76-
buffer.splice(i, 1);
77-
var result= this.apply(buffer.join(''), i, true);
78-
result.pos=i;
79-
return result;
80-
};
81-
82-
FixedWidthMask.prototype.applyDelete = function(input, pos){
83-
var i, buffer = input.split('');
84-
for(i = pos; i < buffer.length; i++){
85-
if(this.tests[i].test)
86-
break;
87-
}
88-
buffer.splice(i, 1);
89-
var result=this.apply(buffer.join(''), i, true);
90-
result.pos=i;
91-
return result;
92-
};
93-
94-
FixedWidthMask.prototype.apply = function(inputString, caretPosition, doShift){
95-
if(caretPosition == null)
96-
caretPosition = this.length;
97-
98-
var input=inputString.split(''),
99-
buffer=[],
100-
raw=[],
101-
lastMatch = -1,
102-
i,
103-
action,
104-
pos;
105-
106-
for (i = 0, pos = 0; i < this.length; i++) {
107-
action=this.tests[i];
108-
109-
if (action.test) {
110-
buffer.push(this.settings.placeholder);
111-
112-
while (pos++ < input.length) {
113-
var c = input[pos - 1];
114-
if (action.test(c)) {
115-
buffer[i] = c;
116-
raw.push(c);
117-
lastMatch = i;
118-
break;
119-
}else if(doShift){
120-
//TODO: The following is awful and needs to be refactored.
121-
var tests;
122-
/* jshint ignore:start */
123-
tests=$.map(this.tests.slice(i + 1), function(test, offset){
124-
var index = pos - 1 + offset;
125-
if(test.test && input[index] != null){
126-
return {regex:test,char:input[index]};
127-
}
128-
});
129-
/* jshint ignore:end */
130-
131-
var newInput = [];
132-
var canShift = tests.length > 0;
133-
134-
if(tests.length){
135-
tests.unshift({regex: action});
136-
for(var j = 1; j < tests.length; j++){
137-
if(!tests[j-1].regex.test(tests[j].char)){
138-
canShift = false;
139-
break;
140-
}
141-
newInput.push(tests[j].char);
142-
}
143-
}
144-
145-
if(canShift){
146-
//Everything to the right can shift left and still match.
147-
input = newInput;
148-
buffer[i] = input[0];
149-
pos = 1;
150-
}else{
151-
//Retry current char at next position leaving a blank.
152-
pos--;
153-
}
154-
//Only allow shift attempt to happen once.
155-
doShift = false;
156-
break;
157-
}
158-
}
159-
} else {
160-
buffer.push(action);
161-
if(action === input[pos] && i !== this.partialPosition) {
162-
pos++;
163-
}
164-
}
165-
}
166-
167-
//Find the next spot waiting for input
168-
var maxCaret=Math.min(caretPosition,this.length);
169-
for(i=Math.min(lastMatch+1,maxCaret);i<this.length;i++){
170-
if(this.tests[i].test)
171-
break;
172-
}
173-
174-
var trimmed=buffer;
175-
if(this.partialPosition < this.length){
176-
trimmed = buffer.slice(0, Math.max(this.partialPosition,lastMatch+1));
177-
}
178-
179-
if(!this.settings.autoclear){
180-
trimmed = buffer.slice(0,i);
181-
}
182-
183-
//TODO: better names for these props
184-
var result={
185-
value: buffer.join(''), //Prompt Value
186-
trimmed: trimmed.join(''), //Display Value
187-
raw: raw.join(''), //Raw Value, TODO: separate unmask call?
188-
pos: i , //(partialPosition ? i : firstNonMaskPos)
189-
isComplete: (lastMatch + 1) >= this.partialPosition
190-
};
191-
return result;
192-
};
193-
19445
function getPasteEvent() {
19546
var el = document.createElement('input'),
19647
name = 'onpaste';
@@ -222,8 +73,8 @@
22273
completed: null
22374
}, settings);
22475

225-
var mask=new FixedWidthMask(format,settings);
226-
76+
//Hardcoded as fixed for now.
77+
var mask=new $.mask.masks.fixed(format, settings);
22778

22879
return this.trigger("unmask").each(function() {
22980
var elm = this,

src/masks/FixedWidthMask.js

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
(function(){
2+
function FixedWidthMask (mask, settings){
3+
var self=this;
4+
//Build up structures necessary to quickly apply masking
5+
this.settings = settings;
6+
7+
this.tests = [];
8+
this.partialPosition = mask.length;
9+
this.length = mask.length;
10+
11+
var firstNonMaskPos = null;
12+
13+
$.each(mask.split(""), function(i, c) {
14+
if (c == '?') {
15+
self.length--;
16+
self.partialPosition = i;
17+
} else if (settings.definitions[c]) {
18+
self.tests.push(new RegExp(settings.definitions[c]));
19+
if (firstNonMaskPos === null) {
20+
firstNonMaskPos = self.tests.length - 1;
21+
}
22+
} else {
23+
self.tests.push(c);
24+
}
25+
});
26+
}
27+
28+
FixedWidthMask.prototype.applyBackspace = function(input, pos){
29+
var i, buffer = input.split('');
30+
for(i = pos - 1; i >= 0; i--){
31+
if(this.tests[i].test)
32+
break;
33+
}
34+
buffer.splice(i, 1);
35+
var result= this.apply(buffer.join(''), i, true);
36+
result.pos=i;
37+
return result;
38+
};
39+
40+
FixedWidthMask.prototype.applyDelete = function(input, pos){
41+
var i, buffer = input.split('');
42+
for(i = pos; i < buffer.length; i++){
43+
if(this.tests[i].test)
44+
break;
45+
}
46+
buffer.splice(i, 1);
47+
var result=this.apply(buffer.join(''), i, true);
48+
result.pos=i;
49+
return result;
50+
};
51+
52+
FixedWidthMask.prototype.apply = function(inputString, caretPosition, doShift){
53+
if(caretPosition == null)
54+
caretPosition = this.length;
55+
56+
var input=inputString.split(''),
57+
buffer=[],
58+
raw=[],
59+
lastMatch = -1,
60+
i,
61+
action,
62+
pos;
63+
64+
for (i = 0, pos = 0; i < this.length; i++) {
65+
action=this.tests[i];
66+
67+
if (action.test) {
68+
buffer.push(this.settings.placeholder);
69+
70+
while (pos++ < input.length) {
71+
var c = input[pos - 1];
72+
if (action.test(c)) {
73+
buffer[i] = c;
74+
raw.push(c);
75+
lastMatch = i;
76+
break;
77+
}else if(doShift){
78+
//TODO: The following is awful and needs to be refactored.
79+
var tests;
80+
/* jshint ignore:start */
81+
tests=$.map(this.tests.slice(i + 1), function(test, offset){
82+
var index = pos - 1 + offset;
83+
if(test.test && input[index] != null){
84+
return {regex:test,char:input[index]};
85+
}
86+
});
87+
/* jshint ignore:end */
88+
89+
var newInput = [];
90+
var canShift = tests.length > 0;
91+
92+
if(tests.length){
93+
tests.unshift({regex: action});
94+
for(var j = 1; j < tests.length; j++){
95+
if(!tests[j-1].regex.test(tests[j].char)){
96+
canShift = false;
97+
break;
98+
}
99+
newInput.push(tests[j].char);
100+
}
101+
}
102+
103+
if(canShift){
104+
//Everything to the right can shift left and still match.
105+
input = newInput;
106+
buffer[i] = input[0];
107+
pos = 1;
108+
}else{
109+
//Retry current char at next position leaving a blank.
110+
pos--;
111+
}
112+
//Only allow shift attempt to happen once.
113+
doShift = false;
114+
break;
115+
}
116+
}
117+
} else {
118+
buffer.push(action);
119+
if(action === input[pos] && i !== this.partialPosition) {
120+
pos++;
121+
}
122+
}
123+
}
124+
125+
//Find the next spot waiting for input
126+
var maxCaret=Math.min(caretPosition,this.length);
127+
for(i=Math.min(lastMatch+1,maxCaret);i<this.length;i++){
128+
if(this.tests[i].test)
129+
break;
130+
}
131+
132+
var trimmed=buffer;
133+
if(this.partialPosition < this.length){
134+
trimmed = buffer.slice(0, Math.max(this.partialPosition,lastMatch+1));
135+
}
136+
137+
if(!this.settings.autoclear){
138+
trimmed = buffer.slice(0,i);
139+
}
140+
141+
//TODO: better names for these props
142+
var result={
143+
value: buffer.join(''), //Prompt Value
144+
trimmed: trimmed.join(''), //Display Value
145+
raw: raw.join(''), //Raw Value, TODO: separate unmask call?
146+
pos: i , //(partialPosition ? i : firstNonMaskPos)
147+
isComplete: (lastMatch + 1) >= this.partialPosition
148+
};
149+
return result;
150+
};
151+
$.mask.masks.fixed = FixedWidthMask;
152+
})(jQuery);

0 commit comments

Comments
 (0)