2014-11-28 17:49:41 -08:00
CocoClass = require ' core/CocoClass '
2014-11-28 16:38:50 -08:00
locale = require ' locale/locale '
2014-11-28 17:49:41 -08:00
LOG = false
2014-11-28 16:38:50 -08:00
module.exports = ModuleLoader = class ModuleLoader extends CocoClass
@WADS = [
2014-11-29 08:54:08 -08:00
' lib '
2014-11-28 16:38:50 -08:00
' views/play '
' views/editor '
]
constructor: ->
super ( )
@loaded = { }
@queue = new createjs . LoadQueue ( )
@ queue . on ( ' fileload ' , @ onFileLoad , @ )
2014-11-29 15:31:34 -08:00
wrapped = _ . wrap window . require , (func, name, loaderPath) ->
# vendor libraries aren't actually wrapped with common.js, so short circuit those requires
return { } if _ . string . startsWith ( name , ' vendor/ ' )
2014-12-08 14:21:40 -08:00
return { } if name is ' tests '
2016-01-07 09:40:35 -08:00
return { } if name is ' demo-app '
2014-12-01 10:35:45 -08:00
name = ' core/auth ' if name is ' lib/auth ' # proxy for iPad until it's been updated to use the new, refactored location. TODO: remove this
2014-11-29 15:31:34 -08:00
return func ( name , loaderPath )
_ . extend wrapped , window . require # for functions like 'list'
window . require = wrapped
2014-12-06 13:11:47 -08:00
@updateProgress = _ . throttle _ . bind ( @ updateProgress , @ ) , 700
@lastShownProgress = 0
2014-11-28 16:38:50 -08:00
load: (path, first=true) ->
2014-12-06 13:11:47 -08:00
$ ( ' # module-load-progress ' ) . css ( ' opacity ' , 1 )
2014-11-28 16:38:50 -08:00
if first
@recentPaths = [ ]
@recentLoadedBytes = 0
originalPath = path
wad = _ . find ModuleLoader . WADS , (wad) -> _ . string . startsWith ( path , wad )
path = wad if wad
return false if @ loaded [ path ]
@ loaded [ path ] = true
@ recentPaths . push ( path )
console . debug ' Loading js file: ' , " /javascripts/app/ #{ path } .js " if LOG
@ queue . loadFile ( {
id: path
src: " /javascripts/app/ #{ path } .js "
type: createjs . LoadQueue . JAVASCRIPT
} )
return true
2016-09-19 12:38:22 -07:00
loadLanguage: (langCode='en-US') ->
2014-11-28 16:38:50 -08:00
loading = @ load ( " locale/ #{ langCode } " )
firstBit = langCode [ . . . 2 ]
return loading if firstBit is langCode
return loading unless locale [ firstBit ] ?
return @ load ( " locale/ #{ firstBit } " , false ) or loading
onFileLoad: (e) =>
2016-09-19 12:38:22 -07:00
return # TODO: remove, just trying to get Webpack going
2014-11-29 16:46:36 -08:00
# load dependencies if it's not a vendor library
if not _ . string . startsWith ( e . item . id , ' vendor ' )
have = window . require . list ( )
2016-07-08 13:13:28 -07:00
haveWithIndexRemoved = _ ( have )
. filter (file) -> _ . string . endsWith ( file , ' index ' )
. map (file) -> file . slice ( 0 , - 6 )
. value ( )
have = have . concat ( haveWithIndexRemoved )
2014-11-29 16:46:36 -08:00
console . group ( ' Dependencies ' , e . item . id ) if LOG
@ recentLoadedBytes += e . rawResult . length
dependencies = @ parseDependencies ( e . rawResult )
console . groupEnd ( ) if LOG
missing = _ . difference dependencies , have
@ load ( module , false ) for module in missing
# update locale data
if _ . string . startsWith ( e . item . id , ' locale ' )
locale . update ( )
# just a bit of cleanup to get the script objects out of the body element
2014-11-28 16:38:50 -08:00
$ ( e . result ) . remove ( )
2014-12-01 13:16:00 -08:00
# get treema set up only when the library loads, if it loads
if e . item . id is ' vendor/treema '
treemaExt = require ' core/treema-ext '
treemaExt . setup ( )
2014-11-29 16:46:36 -08:00
# a module and its dependencies have loaded!
2014-11-28 16:38:50 -08:00
if @ queue . progress is 1
@ recentPaths . sort ( )
2016-05-26 17:36:21 -07:00
# console.debug @recentPaths.join('\n')
# console.debug 'loaded', @recentPaths.length, 'files,', parseInt(@recentLoadedBytes/1024), 'KB'
2014-11-28 16:38:50 -08:00
@ trigger ' load-complete '
2014-12-01 13:16:00 -08:00
@ trigger ' loaded ' , e . item
2014-12-06 13:11:47 -08:00
@ updateProgress ( )
updateProgress: ->
return if @ queue . progress < @ lastShownProgress
$ ( ' # module-load-progress .progress-bar ' ) . css ( ' width ' , ( 100 * @ queue . progress ) + ' % ' )
2016-09-19 12:38:22 -07:00
if @ queue . progress is 1
2014-12-06 13:11:47 -08:00
$ ( ' # module-load-progress ' ) . css ( ' opacity ' , 0 )
2014-11-29 17:51:32 -08:00
2014-11-28 16:38:50 -08:00
parseDependencies: (raw) ->
2014-11-29 00:29:32 -08:00
bits = raw . match ( /(require\(['"](.+?)['"])|(register\(['"].+?['"])/g ) or [ ]
2014-11-28 16:38:50 -08:00
rootFolder = null
dependencies = [ ]
for bit in bits
if _ . string . startsWith ( bit , ' register ' )
root = bit . slice ( 10 , bit . length - 1 ) # remove 'register("' and final double quote
console . groupEnd ( ) if rootFolder if LOG
rootFolder = ( root . match ( ' .+/ ' ) [ 0 ] or ' ' ) [ . . . - 1 ]
console . group ( ' register ' , rootFolder , " ( #{ bit } ) " ) if LOG
else
dep = bit . slice ( 9 , bit . length - 1 ) # remove "require('" and final single quote
dep = dep [ 1 . . . ] if dep [ 0 ] is ' / '
dep = @ expand ( rootFolder , dep )
continue if dep is ' memwatch '
continue if _ . string . startsWith ( dep , ' ace/ ' )
dependencies . push ( dep )
2014-11-29 08:54:08 -08:00
console . debug dep if LOG
2014-11-28 16:38:50 -08:00
console . groupEnd ( ) if LOG
return dependencies
2014-11-29 16:46:36 -08:00
# basically ripped out of commonjs definition
2014-11-28 16:38:50 -08:00
expand: (root, name) ->
results = [ ]
if /^\.\.?(\/|$)/ . test ( name )
parts = [ root , name ] . join ( ' / ' ) . split ( ' / ' )
else
parts = name . split ( ' / ' )
for part in parts
2016-09-19 12:38:22 -07:00
if part is ' .. '
2014-11-28 16:38:50 -08:00
results . pop ( )
else if ( part isnt ' . ' and part isnt ' ' )
results . push ( part )
return results . join ( ' / ' )