Skip to content

Commit

Permalink
Removing new Function for moment#377
Browse files Browse the repository at this point in the history
  • Loading branch information
timrwood committed Aug 20, 2012
1 parent b661e8d commit be6b2ca
Showing 1 changed file with 134 additions and 60 deletions.
194 changes: 134 additions & 60 deletions moment.js
Expand Up @@ -30,9 +30,8 @@
aspNetJsonRegex = /^\/?Date\((\-?\d+)/i,

// format tokens
formattingTokens = /(\[[^\[]*\])|(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|YYYY|YY|a|A|hh?|HH?|mm?|ss?|SS?S?|zz?|ZZ?)/g,
formattingTokens = /(\[[^\[]*\])|(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|YYYY|YY|a|A|hh?|HH?|mm?|ss?|SS?S?|zz?|ZZ?|.)/g,
localFormattingTokens = /(LT|LL?L?L?)/g,
formattingRemoveEscapes = /(^\[)|(\\)|\]$/g,

// parsing tokens
parseMultipleFormatChunker = /([0-9a-zA-Z\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+)/gi,
Expand Down Expand Up @@ -77,58 +76,138 @@
// format function strings
formatFunctions = {},

// tokens to ordinalize and pad
ordinalizeTokens = 'DDD w M D d'.split(' '),
paddedTokens = 'M D H h m s w'.split(' '),

/*
* moment.fn.format uses new Function() to create an inlined formatting function.
* Results are a 3x speed boost
* http://jsperf.com/momentjs-cached-format-functions
*
* These strings are appended into a function using replaceFormatTokens and makeFormatFunction
*/
formatFunctionStrings = {
formatTokenFunctions = {
// a = placeholder
// b = placeholder
// t = the current moment being formatted
// v = getValueAtKey function
// o = language.ordinal function
// p = leftZeroFill function
// m = language.meridiem value or function
M : '(a=t.month()+1)',
MMM : 'v("monthsShort",t.month())',
MMMM : 'v("months",t.month())',
D : '(a=t.date())',
DDD : '(a=new Date(t.year(),t.month(),t.date()),b=new Date(t.year(),0,1),a=~~(((a-b)/864e5)+1.5))',
d : '(a=t.day())',
dd : 'v("weekdaysMin",t.day())',
ddd : 'v("weekdaysShort",t.day())',
dddd : 'v("weekdays",t.day())',
w : '(a=new Date(t.year(),t.month(),t.date()-t.day()+5),b=new Date(a.getFullYear(),0,4),a=~~((a-b)/864e5/7+1.5))',
YY : 'p(t.year()%100,2)',
YYYY : 'p(t.year(),4)',
a : 'm(t.hours(),t.minutes(),!0)',
A : 'm(t.hours(),t.minutes(),!1)',
H : 't.hours()',
h : 't.hours()%12||12',
m : 't.minutes()',
s : 't.seconds()',
S : '~~(t.milliseconds()/100)',
SS : 'p(~~(t.milliseconds()/10),2)',
SSS : 'p(t.milliseconds(),3)',
Z : '((a=-t.zone())<0?((a=-a),"-"):"+")+p(~~(a/60),2)+":"+p(~~a%60,2)',
ZZ : '((a=-t.zone())<0?((a=-a),"-"):"+")+p(~~(10*a/6),4)'
},
M : function () {
return this.month() + 1;
},
MMM : function (format) {
return getValueFromArray("monthsShort", this.month(), this, format);
},
MMMM : function (format) {
return getValueFromArray("months", this.month(), this, format);
},
D : function () {
return this.date();
},
DDD : function () {
var a = new Date(this.year(), this.month(), this.date()),
b = new Date(this.year(), 0, 1);
return ~~(((a - b) / 864e5) + 1.5);
},
d : function () {
return this.day();
},
dd : function (format) {
return getValueFromArray("weekdaysMin", this.day(), this, format);
},
ddd : function (format) {
return getValueFromArray("weekdaysShort", this.day(), this, format);
},
dddd : function (format) {
return getValueFromArray("weekdays", this.day(), this, format);
},
w : function () {
var a = new Date(this.year(), this.month(), this.date() - this.day() + 5),
b = new Date(a.getFullYear(), 0, 4);
return ~~((a - b) / 864e5 / 7 + 1.5);
},
YY : function () {
return leftZeroFill(this.year() % 100, 2);
},
YYYY : function () {
return leftZeroFill(this.year(), 4);
},
a : function () {
return this.lang().meridiem(this.hours(), this.minutes(), true);
},
A : function () {
return this.lang().meridiem(this.hours(), this.minutes(), false);
},
H : function () {
return this.hours();
},
h : function () {
return this.hours() % 12 || 12;
},
m : function () {
return this.minutes();
},
s : function () {
return this.seconds();
},
S : function () {
return ~~(this.milliseconds() / 100);
},
SS : function () {
return leftZeroFill(~~(this.milliseconds() / 10), 2);
},
SSS : function () {
return leftZeroFill(this.milliseconds(), 3);
},
Z : function () {
var a = -this.zone(),
b = "+";
if (a < 0) {
a = -a;
b = "-";
}
return b + leftZeroFill(~~(a / 60), 2) + ":" + leftZeroFill(~~a % 60, 2);
},
ZZ : function () {
var a = -this.zone(),
b = "+";
if (a < 0) {
a = -a;
b = "-";
}
return b + leftZeroFill(~~(10 * a / 6), 4);
}
};

ordinalizeTokens = 'DDD w M D d'.split(' '),
paddedTokens = 'M D H h m s w'.split(' ');
function getValueFromArray(key, index, m, format) {
var lang = m.lang();
return lang[key].call ? lang[key](m, format) : lang[key][index];
}

function padToken(func, count) {
return function (a) {
return leftZeroFill(func.call(this, a), count);
};
}
function ordinalizeToken(func) {
return function (a) {
var b = func.call(this, a);
return b + this.lang().ordinal(b);
};
}

while (ordinalizeTokens.length) {
i = ordinalizeTokens.pop();
formatFunctionStrings[i + 'o'] = formatFunctionStrings[i] + '+o(a)';
formatTokenFunctions[i + 'o'] = ordinalizeToken(formatTokenFunctions[i]);
}
while (paddedTokens.length) {
i = paddedTokens.pop();
formatFunctionStrings[i + i] = 'p(' + formatFunctionStrings[i] + ',2)';
formatTokenFunctions[i + i] = padToken(formatTokenFunctions[i], 2);
}
formatFunctionStrings.DDDD = 'p(' + formatFunctionStrings.DDD + ',3)';
formatTokenFunctions.DDDD = padToken(formatTokenFunctions.DDD, 3);


/************************************
Expand Down Expand Up @@ -339,45 +418,40 @@
************************************/


// helper for building inline formatting functions
function replaceFormatTokens(token) {
return formatFunctionStrings[token] ?
("'+(" + formatFunctionStrings[token] + ")+'") :
token.replace(formattingRemoveEscapes, "").replace(/\\?'/g, "\\'");
}

// helper for recursing long date formatting tokens
function replaceLongDateFormatTokens(input) {
return getLangDefinition().longDateFormat[input] || input;
}

function makeFormatFunction(format) {
var output = "var a,b;return '" +
format.replace(formattingTokens, replaceFormatTokens) + "';",
Fn = Function; // get around jshint
// t = the current moment being formatted
// v = getValueAtKey function
// o = language.ordinal function
// p = leftZeroFill function
// m = language.meridiem value or function
return new Fn('t', 'v', 'o', 'p', 'm', output);
function removeFormattingTokens(input) {
if (input.match(/\[.*\]/)) {
return input.replace(/^\[|\]$/g, "");
}
return input.replace(/\\/g, "");
}

function makeOrGetFormatFunction(format) {
if (!formatFunctions[format]) {
formatFunctions[format] = makeFormatFunction(format);
function makeFormatFunction(format) {
var array = format.match(formattingTokens), i, length;

for (i = 0, length = array.length; i < length; i++) {
if (formatTokenFunctions[array[i]]) {
array[i] = formatTokenFunctions[array[i]];
} else {
array[i] = removeFormattingTokens(array[i]);
}
}
return formatFunctions[format];

return function (mom) {
var output = "";
for (i = 0; i < length; i++) {
output += typeof array[i].call === 'function' ? array[i].call(mom, format) : array[i];
}
return output;
};
}

// format date using native date object
function formatMoment(m, format) {
var lang = getLangDefinition(m);

function getValueFromArray(key, index) {
return lang[key].call ? lang[key](m, format) : lang[key][index];
}

while (localFormattingTokens.test(format)) {
format = format.replace(localFormattingTokens, replaceLongDateFormatTokens);
}
Expand All @@ -386,7 +460,7 @@
formatFunctions[format] = makeFormatFunction(format);
}

return formatFunctions[format](m, getValueFromArray, lang.ordinal, leftZeroFill, lang.meridiem);
return formatFunctions[format](m);
}


Expand Down

0 comments on commit be6b2ca

Please sign in to comment.