1+ /*** SET UP AIRBORN OS ***/
2+
3+ var fs = require ( 'fs' ) ;
4+
5+ var window = global . window = global ;
6+ global . parent = global ;
7+
8+ window . sjcl = require ( 'sjcl' ) ;
9+
10+ function randomWords ( n ) {
11+ return Array . apply ( null , new Array ( n ) ) . map ( function ( ) { return Math . floor ( Math . random ( ) * 0xFFFFFFFF ) ; } ) ;
12+ }
13+ var hmac_bits = randomWords ( 4 ) ;
14+ var files_hmac = window . files_hmac = new sjcl . misc . hmac ( hmac_bits ) ;
15+
16+ window . XMLHttpRequest = function ( ) {
17+ this . listeners = { } ;
18+ } ;
19+ window . XMLHttpRequest . prototype . addEventListener = function ( name , listener ) {
20+ if ( ! this . listeners [ name ] ) {
21+ this . listeners [ name ] = [ ] ;
22+ }
23+ this . listeners [ name ] . push ( listener ) ;
24+ } ;
25+ window . XMLHttpRequest . prototype . emit = function ( name ) {
26+ if ( this . listeners [ name ] ) {
27+ var _this = this ;
28+ this . listeners [ name ] . forEach ( function ( listener ) {
29+ listener . call ( _this ) ;
30+ } ) ;
31+ }
32+ } ;
33+ window . XMLHttpRequest . prototype . open = function ( method , url ) {
34+ if ( url . substr ( 0 , 8 ) === '/object/' && method === 'GET' ) {
35+ var hash = url . split ( '#' ) [ 1 ]
36+ url = '../' + hash . substr ( hash . indexOf ( '.' ) + 1 ) . replace ( '/Core/' , 'builder/airbornos/' ) ;
37+ Object . defineProperty ( this , 'send' , { value : function ( ) {
38+ var _this = this ;
39+ fs . readFile ( url , 'base64' , function ( err , contents ) {
40+ Object . defineProperty ( _this , 'readyState' , { get : function ( ) { return 4 ; } } ) ;
41+ if ( err ) {
42+ Object . defineProperty ( _this , 'status' , { get : function ( ) {
43+ return 404 ;
44+ } } ) ;
45+ } else {
46+ Object . defineProperty ( _this , 'status' , { get : function ( ) {
47+ return 200 ;
48+ } , configurable : true } ) ;
49+ Object . defineProperty ( _this , 'response' , { get : function ( ) {
50+ return codec . base64 . toAB ( contents ) ;
51+ } } ) ;
52+ }
53+ _this . emit ( 'readystatechange' ) ;
54+ _this . emit ( 'load' ) ;
55+ } ) ;
56+ } } ) ;
57+ return ;
58+ } else if ( url . substr ( 0 , 8 ) === '/object/' || url . substr ( 0 , 13 ) === '/transaction/' ) {
59+ Object . defineProperty ( this , 'setRequestHeader' , { value : function ( ) { } } ) ;
60+ Object . defineProperty ( this , 'send' , { value : function ( ) {
61+ Object . defineProperty ( this , 'readyState' , { get : function ( ) { return 4 ; } } ) ;
62+ Object . defineProperty ( this , 'status' , { get : function ( ) {
63+ return 200 ;
64+ } } ) ;
65+ this . emit ( 'readystatechange' ) ;
66+ this . emit ( 'load' ) ;
67+ } } ) ;
68+ return ;
69+ }
70+ throw new Error ( 'Unknown XMLHttpRequest url: ' + url ) ;
71+ } ;
72+
73+ window . document = { } ;
74+ document . createElement = function ( ) {
75+ return { } ;
76+ } ;
77+ document . head = { } ;
78+ document . head . appendChild = function ( ) { } ;
79+
80+ window . crypto = { } ;
81+ window . crypto . getRandomValues = function ( array ) {
82+ var words = randomWords ( array . length ) ;
83+ words . forEach ( function ( word , i ) {
84+ array [ i ] = word ;
85+ } ) ;
86+ } ;
87+
88+ window . atob = function ( str ) { return new Buffer ( str , 'base64' ) . toString ( 'binary' ) ; } ;
89+ window . btoa = function ( str ) { return new Buffer ( str , 'binary' ) . toString ( 'base64' ) ; } ;
90+
91+ window . TextDecoder = function ( ) { } ;
92+ TextDecoder . prototype . decode = function ( dataview ) { return new Buffer ( codec . base64 . fromAB ( dataview . buffer ) , 'base64' ) . toString ( 'utf8' ) ; } ;
93+ window . TextEncoder = function ( ) { } ;
94+ TextEncoder . prototype . encode = function ( str ) { return { buffer : codec . base64 . toAB ( new Buffer ( str , 'utf8' ) . toString ( 'base64' ) ) } ; } ;
95+
96+ window . navigator = { } ;
97+ window . navigator . userAgent = {
98+ match : function ( ) { return String . prototype . match . apply ( 'Safari' , arguments ) ; } , // Use the full set of variable rewrites
99+ indexOf : function ( ) { return String . prototype . match . apply ( 'Chrome' , arguments ) ; } , // Use Data URLs
100+ } ;
101+ window . location = { } ;
102+ window . location . protocol = 'https:' ;
103+
104+ window . eval ( fs . readFileSync ( 'airbornos/core.js' , 'utf8' ) ) ;
105+
106+ window . encrypt = window . decrypt = function ( key , content , callback ) {
107+ callback ( content ) ;
108+ } ;
109+
110+ /*** END SET UP AIRBORN OS ***/
111+
112+
113+ var argv = require ( 'yargs' ) . argv ;
114+
115+ // Compile everything into a single html file
116+ prepareFile ( argv . _ [ 0 ] . replace ( '../' , '' ) , { compat : false , _compat : false , bootstrap : false , rootParent : '' } , function ( contents ) {
117+
118+ // Extract scripts
119+ var scripts = [ ] ;
120+ contents = contents . replace ( / < s c r i p t ( [ ^ > ] * ) s r c = " ( [ ^ " ] * ) " ( [ ^ > ] * ) > < \/ s c r i p t > / g, function ( match , preAttrs , url , postAttrs ) {
121+ scripts . push ( '../' + decodeURIComponent ( url . split ( ',' ) [ 0 ] . match ( / f i l e n a m e = ( [ ^ ; ] * ) ; / ) [ 1 ] ) ) ;
122+ return '' ;
123+ } ) ;
124+
125+
126+ // Minify scripts
127+ var scriptsFileName = argv . _ [ 0 ] . replace ( '../' , '../build/' ) . replace ( / [ ^ \/ ] * \. h t m l / , 'scripts.js' ) ;
128+ var cc = require ( 'child_process' ) . spawn ( 'java' , [
129+ '-jar' , 'node_modules/google-closure-compiler/compiler.jar' ,
130+ '--language_in' , 'ECMASCRIPT5' ,
131+ '--js_output_file' , scriptsFileName ,
132+ ] . concat ( argv . sourceMap === false ? [ ] : [
133+ '--create_source_map' , '%outname%.map'
134+ ] ) . concat ( scripts ) ) ;
135+ cc . stderr . on ( 'data' , function ( data ) {
136+ console . error ( '' + data ) ;
137+ } ) ;
138+ cc . on ( 'close' , function ( ) {
139+ contents = contents . replace ( / (? = < \/ h e a d ) / i, '<script src="scripts.js"></script>' ) ;
140+
141+
142+ // Extract styles
143+ var styles = [ ] ;
144+ contents = contents . replace ( / < l i n k ( [ ^ > ] * ) h r e f = " ( [ ^ " ] * ) " ( [ ^ > ] * ) > / g, function ( match , preAttrs , url , postAttrs ) {
145+ var attrs = preAttrs + postAttrs ;
146+ if ( attrs . indexOf ( ' rel="stylesheet"' ) !== - 1 ) {
147+ var style = decodeURIComponent ( url . split ( ',' ) [ 1 ] ) ;
148+ var media = attrs . match ( / m e d i a = " ( [ ^ " ] * ) " / ) ;
149+ if ( media ) style = '@media ' + media [ 1 ] + '{' + style + '}' ;
150+ styles . push ( style ) ;
151+ return '' ;
152+ }
153+ return match ;
154+ } ) ;
155+
156+
157+ // Remove unused css
158+ require ( 'uncss' ) ( contents , {
159+ raw : styles . join ( '\n' ) ,
160+ ignoreModifiers : [
161+ '[disabled]' ,
162+ '.current' ,
163+ '.parent' ,
164+ '.active' ,
165+ '.selected-tab-button' ,
166+ '.selected-tab' ,
167+ '.shown' ,
168+ '.hidden-item' ,
169+ '[dir="rtl"]' ,
170+ '.fullscreen' ,
171+ '.night' ,
172+ '.previews' ,
173+ '[data-state="drawer"]' ,
174+ '.titlePopup' ,
175+ ] ,
176+ ignore : [
177+ / s e c t i o n \[ r o l e = " s t a t u s " \] / ,
178+ '.mainButtons button b' ,
179+ / \. f i l e L i s t I t e m / ,
180+ '[data-type="list"] li > a' ,
181+ '[data-type="list"] aside[class*=" icon-"]' ,
182+ 'label.pack-checkbox' ,
183+ 'label.pack-checkbox input' ,
184+ 'label.pack-checkbox input ~ span' ,
185+ 'label.pack-checkbox.danger input ~ span' ,
186+ / \. C o d e M i r r o r / ,
187+ / \. c m - / ,
188+ / \. i c o n - f u l l s c r e e n - e x i t / ,
189+ / \. i c o n - f i l e / ,
190+ / \. i c o n - f o r m a t - a l i g n - l e f t / ,
191+ / \. i c o n - f o r m a t - f l o a t - l e f t / ,
192+ ]
193+ } , function ( err , css ) {
194+ // Remove unused glyphs from icon font
195+ var rIconFontUrl = / ( u r l \( " .* ?m a t e r i a l d e s i g n i c o n s - w e b f o n t .w o f f .* ?b a s e 6 4 , ) ( .* ?) ( " \) ) / ;
196+ var rIconRuleMatch = / \. i c o n - .* ?: b e f o r e { \n c o n t e n t : " \\ ( [ \d a - f ] + ) " ; \n } / g;
197+ var rIconRuleExtract = / \. i c o n - .* ?: b e f o r e { \n c o n t e n t : " \\ ( [ \d a - f ] + ) " ; \n } / ; // not global
198+
199+ window . language = 'en-US' ; // Since there is a window, fontmin expects window.language
200+
201+ var Fontmin = require ( 'fontmin' ) ;
202+ var fontmin = new Fontmin ( )
203+ . src ( argv . _ [ 0 ] . replace ( / [ ^ \/ ] * \. h t m l / , 'style/fonts/materialdesignicons-webfont.ttf' ) )
204+ . use ( Fontmin . glyph ( {
205+ text : css . match ( rIconRuleMatch ) . map ( function ( iconRule ) {
206+ return String . fromCharCode ( parseInt ( iconRule . match ( rIconRuleExtract ) [ 1 ] , 16 ) ) ;
207+ } ) . join ( '' ) ,
208+ } ) )
209+ . use ( Fontmin . ttf2woff ( {
210+ deflate : true // Does nothing but shouldn't hurt
211+ } ) ) ;
212+ fontmin . run ( function ( err , files ) {
213+ if ( err ) {
214+ throw err ;
215+ }
216+
217+ css = css . replace ( rIconFontUrl ,
218+ '$1' +
219+ files [ 0 ] . contents . toString ( 'base64' ) +
220+ '$3'
221+ ) ;
222+
223+
224+ // Minify css
225+ css = require ( 'more-css' ) . compress ( css ) ;
226+ fs . writeFileSync ( argv . _ [ 0 ] . replace ( '../' , '../build/' ) . replace ( / [ ^ \/ ] * \. h t m l / , 'styles.css' ) , css ) ;
227+ contents = contents . replace ( / < h e a d > / i, '$&<link rel="stylesheet" href="styles.css">' ) ;
228+
229+
230+ // Minify html
231+ contents = require ( 'html-minifier' ) . minify ( contents , {
232+ removeComments : true ,
233+ removeCommentsFromCDATA : true ,
234+ collapseWhitespace : true ,
235+ collapseBooleanAttributes : true ,
236+ removeAttributeQuotes : true ,
237+ removeScriptTypeAttributes : true ,
238+ removeStyleLinkTypeAttributes : true ,
239+ minifyJS : true ,
240+ minifyCSS : true ,
241+ } ) ;
242+
243+
244+ // Pre-prepare script
245+ // We do this now instead of immediately in order to have a working script for uncss (phantomjs).
246+ if ( argv . airborn ) {
247+ prepareFile ( scriptsFileName . replace ( '../' , '' ) , { } , function ( prepared ) {
248+ contents = contents . split ( '<script src=scripts.js></script>' ) . join ( '<script>' + prepared . replace ( / < \/ ( s c r i p t ) / ig, '<\\\/$1' ) + '</script>' ) ; // split and join instead of replace to not interpret replacement string ($1 etc)
249+ fs . unlinkSync ( scriptsFileName ) ;
250+
251+ // Write to build folder
252+ fs . writeFileSync ( argv . _ [ 0 ] . replace ( '../' , '../build/' ) , contents ) ;
253+ } ) ;
254+ } else {
255+ // Write to build folder
256+ fs . writeFileSync ( argv . _ [ 0 ] . replace ( '../' , '../build/' ) , contents ) ;
257+ }
258+ } ) ;
259+ } ) ;
260+ } ) ;
261+
262+ } ) ;
0 commit comments