@@ -20,6 +20,107 @@ module.exports = function (grunt) {
20
20
21
21
grunt . loadNpmTasks ( 'grunt-contrib-jshint' ) ;
22
22
grunt . loadNpmTasks ( 'grunt-contrib-uglify' ) ;
23
- grunt . registerTask ( 'default' , [ 'jshint' , 'uglify' ] ) ;
24
23
24
+ grunt . registerTask ( 'compile-data' , 'Compile the data into the polyfill' , compileData ) ;
25
+ grunt . registerTask ( 'default' , function ( ) {
26
+ grunt . task . run ( 'jshint' ) ;
27
+ grunt . task . run ( 'uglify' ) ;
28
+
29
+ if ( grunt . option ( 'complete' ) )
30
+ grunt . task . run ( 'compile-data' ) ;
31
+ } ) ;
32
+
33
+ /**
34
+ * Compiles all JSON data into the polyfill and saves it as Intl.complete.js
35
+ */
36
+ function compileData ( ) {
37
+ var
38
+ locData = { } ,
39
+ objStrs = { } ,
40
+ objs = [ ] ,
41
+ prims = [ ] ,
42
+
43
+ valCount = 0 ,
44
+ objCount = 0 ,
45
+
46
+ fileData = '' ,
47
+ fs = require ( 'fs' ) ,
48
+ locales = fs . readdirSync ( 'locale-data/json/' ) ,
49
+ Intl = String ( fs . readFileSync ( 'Intl.js' ) ) ;
50
+
51
+ fileData += Intl . slice ( 0 , Intl . lastIndexOf ( 'return Intl;' ) ) + '(function () {' ;
52
+
53
+ locales . forEach ( function ( file ) {
54
+ locData [ file . slice ( 0 , file . indexOf ( '.' ) ) ] = JSON . parse ( fs . readFileSync ( 'locale-data/json/' + file ) , reviver ) ;
55
+ } ) ;
56
+
57
+ function reviver ( k , v ) {
58
+ var idx ;
59
+
60
+ if ( k === 'locale' )
61
+ return undefined ;
62
+
63
+ else if ( typeof v === 'string' ) {
64
+ idx = prims . indexOf ( v ) ;
65
+ valCount ++ ;
66
+
67
+ if ( idx === - 1 )
68
+ idx += prims . push ( v ) ;
69
+
70
+ return '###prims[' + idx + ']###' ;
71
+ }
72
+
73
+ else if ( typeof v === 'object' && v !== null ) {
74
+ var str = JSON . stringify ( v ) ;
75
+ objCount ++ ;
76
+
77
+ if ( objStrs . hasOwnProperty ( str ) )
78
+ return objStrs [ str ] ;
79
+
80
+ else {
81
+ // We need to make sure this object is not added to the same
82
+ // array as an object it references (and we need to check
83
+ // this recursively)
84
+ var
85
+ depth ,
86
+ objDepths = [ 0 ] ;
87
+
88
+ for ( var key in v ) {
89
+ if ( typeof v [ key ] === 'string' && ( depth = v [ key ] . match ( / ^ # # # o b j s \[ ( \d + ) / ) ) )
90
+ objDepths . push ( + depth [ 1 ] + 1 ) ;
91
+ }
92
+
93
+ depth = Math . max . apply ( Math , objDepths ) ;
94
+
95
+ if ( ! Array . isArray ( objs [ depth ] ) )
96
+ objs [ depth ] = [ ] ;
97
+
98
+ idx = objs [ depth ] . push ( v ) - 1 ;
99
+ objStrs [ str ] = '###objs[' + depth + '][' + idx + ']###' ;
100
+
101
+ return objStrs [ str ] ;
102
+ }
103
+ }
104
+ }
105
+
106
+ fileData += 'var a=' + JSON . stringify ( prims ) + ',b=[];' ;
107
+ objs . forEach ( function ( val , idx ) {
108
+ var ref = JSON . stringify ( val ) . replace ( / " # # # ( o b j s | p r i m s ) ( \[ [ ^ # ] + ) # # # " / g, replacer ) ;
109
+
110
+ fileData += 'b[' + idx + ']=' + ref + ';' ;
111
+ } ) ;
112
+
113
+ for ( var k in locData )
114
+ fileData += 'addLocaleData(' + locData [ k ] . replace ( / # # # ( o b j s | p r i m s ) ( \[ [ ^ # ] + ) # # # / , replacer ) + ', "' + k + '");' ;
115
+
116
+ fileData += '})();\n' + Intl . slice ( Intl . lastIndexOf ( 'return Intl;' ) ) ;
117
+ fs . writeFileSync ( 'Intl.complete.js' , fileData ) ;
118
+
119
+ grunt . log . writeln ( 'Total number of reused strings is ' + prims . length + ' (reduced from ' + valCount + ')' ) ;
120
+ grunt . log . writeln ( 'Total number of reused objects is ' + Object . keys ( objStrs ) . length + ' (reduced from ' + objCount + ')' ) ;
121
+ }
122
+
123
+ function replacer ( $0 , type , loc ) {
124
+ return ( type === 'prims' ? 'a' : 'b' ) + loc ;
125
+ }
25
126
} ;
0 commit comments