mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2025-02-17 00:40:56 -05:00
Set up the site to load its logic and templates piecemeal rather than in one giant app.js file.
This commit is contained in:
parent
12b3428aee
commit
b698745e05
15 changed files with 399 additions and 95 deletions
107
app/ModuleLoader.coffee
Normal file
107
app/ModuleLoader.coffee
Normal file
|
@ -0,0 +1,107 @@
|
|||
CocoClass = require 'lib/CocoClass'
|
||||
locale = require 'locale/locale'
|
||||
|
||||
LOG = true
|
||||
|
||||
|
||||
module.exports = ModuleLoader = class ModuleLoader extends CocoClass
|
||||
|
||||
@WADS = [
|
||||
'lib/world'
|
||||
'lib/surface'
|
||||
'views/play'
|
||||
'views/game-menu'
|
||||
'views/editor'
|
||||
]
|
||||
|
||||
constructor: ->
|
||||
super()
|
||||
@loaded = {}
|
||||
@queue = new createjs.LoadQueue()
|
||||
@queue.on('fileload', @onFileLoad, @)
|
||||
|
||||
load: (path, first=true) ->
|
||||
if first
|
||||
$('#module-loading-list ul').empty()
|
||||
@recentPaths = []
|
||||
@recentLoadedBytes = 0
|
||||
|
||||
originalPath = path
|
||||
wad = _.find ModuleLoader.WADS, (wad) -> _.string.startsWith(path, wad)
|
||||
path = wad if wad
|
||||
return false if @loaded[path]
|
||||
$('#module-loading-list').modal('show') if first
|
||||
@loaded[path] = true
|
||||
@recentPaths.push(path)
|
||||
li = $("<li class='list-group-item loading' data-path='#{path}'>#{path}</li>")
|
||||
.prepend($("<span class='glyphicon glyphicon-minus'></span>"))
|
||||
.prepend($("<span class='glyphicon glyphicon-ok'></span>"))
|
||||
ul = $('#module-loading-list ul')
|
||||
ul.append(li).scrollTop(ul[0].scrollHeight)
|
||||
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
|
||||
|
||||
loadLanguage: (langCode) ->
|
||||
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) =>
|
||||
$("#module-loading-list li[data-path='#{e.item.id}']").removeClass('loading').addClass('success')
|
||||
have = window.require.list()
|
||||
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
|
||||
locale.update() if _.string.startsWith(e.item.id, 'locale')
|
||||
$(e.result).remove()
|
||||
if @queue.progress is 1
|
||||
$('#module-loading-list').modal('hide')
|
||||
@recentPaths.sort()
|
||||
console.log @recentPaths.join('\n')
|
||||
console.log 'loaded', @recentPaths.length, 'files,', parseInt(@recentLoadedBytes/1024), 'KB'
|
||||
@trigger 'load-complete'
|
||||
|
||||
parseDependencies: (raw) ->
|
||||
bits = raw.match(/(require\(\'([^)]+)\')|(register\(\".+\")/g) or []
|
||||
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)
|
||||
console.log dep if LOG
|
||||
console.groupEnd() if LOG
|
||||
return dependencies
|
||||
|
||||
expand: (root, name) ->
|
||||
results = []
|
||||
if /^\.\.?(\/|$)/.test(name)
|
||||
parts = [root, name].join('/').split('/')
|
||||
else
|
||||
parts = name.split('/')
|
||||
for part in parts
|
||||
if part is '..'
|
||||
results.pop()
|
||||
else if (part isnt '.' and part isnt '')
|
||||
results.push(part)
|
||||
return results.join('/')
|
||||
|
|
@ -105,8 +105,12 @@ module.exports = class CocoRouter extends Backbone.Router
|
|||
window.location.href = window.location.href
|
||||
|
||||
routeDirectly: (path, args) ->
|
||||
path = "views/#{path}"
|
||||
path = "views/#{path}" if not _.str.startsWith(path, 'views/')
|
||||
ViewClass = @tryToLoadModule path
|
||||
if not ViewClass and application.moduleLoader.load(path)
|
||||
@listenToOnce application.moduleLoader, 'load-complete', ->
|
||||
@routeDirectly(path, args)
|
||||
return
|
||||
return @openView @notFoundView() if not ViewClass
|
||||
view = new ViewClass({}, args...) # options, then any path fragment args
|
||||
view.render()
|
||||
|
@ -148,11 +152,9 @@ module.exports = class CocoRouter extends Backbone.Router
|
|||
|
||||
initializeSocialMediaServices: ->
|
||||
return if application.testing or application.demoing
|
||||
services = [
|
||||
'./lib/services/facebook'
|
||||
'./lib/services/google'
|
||||
'./lib/services/twitter'
|
||||
]
|
||||
require('./lib/services/facebook')()
|
||||
require('./lib/services/google')()
|
||||
require('./lib/services/twitter')()
|
||||
|
||||
for service in services
|
||||
service = require service
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
FacebookHandler = require 'lib/FacebookHandler'
|
||||
GPlusHandler = require 'lib/GPlusHandler'
|
||||
GitHubHandler = require 'lib/GitHubHandler'
|
||||
locale = require 'locale/locale' # TODO: don't require all of these? Might be slow. (Haven't checked.)
|
||||
ModuleLoader = require 'ModuleLoader'
|
||||
locale = require 'locale/locale'
|
||||
{me} = require 'lib/auth'
|
||||
Tracker = require 'lib/Tracker'
|
||||
CocoView = require 'views/kinds/CocoView'
|
||||
|
||||
marked.setOptions {gfm: true, sanitize: true, smartLists: true, breaks: false}
|
||||
|
||||
|
@ -43,6 +43,8 @@ Application = initialize: ->
|
|||
@facebookHandler = new FacebookHandler()
|
||||
@gplusHandler = new GPlusHandler()
|
||||
@githubHandler = new GitHubHandler()
|
||||
@moduleLoader = new ModuleLoader()
|
||||
@moduleLoader.loadLanguage(me.get('preferredLanguage', true))
|
||||
$(document).bind 'keydown', preventBackspace
|
||||
preload(COMMON_FILES)
|
||||
$.i18n.init {
|
||||
|
|
|
@ -28,23 +28,46 @@
|
|||
<link rel="shortcut icon" href="/images/favicon.ico">
|
||||
<link rel="stylesheet" href="/stylesheets/app.css">
|
||||
|
||||
<script src="/lib/ace/ace.js"></script>
|
||||
<script src="/lib/ace/ace.js" defer></script>
|
||||
<!--[if IE 9]><script src="/javascripts/box2d.js"></script><![endif]-->
|
||||
<script src="/javascripts/vendor.js"></script>
|
||||
<script src="/javascripts/aether.js"></script>
|
||||
<script src="/javascripts/app.js"></script> <!-- it's all Backbone! -->
|
||||
<script>$(function() { FastClick.attach(document.body); });</script>
|
||||
<script src="/javascripts/vendor.js" defer></script>
|
||||
<script src="/javascripts/aether.js" defer></script>
|
||||
<script src="/javascripts/app.js" defer></script> <!-- it's all Backbone! -->
|
||||
<script>
|
||||
window.userObject = "userObjectTag";
|
||||
onLoad = function() {
|
||||
FastClick.attach(document.body);
|
||||
window.userObject = "userObjectTag";
|
||||
require('initialize');
|
||||
}
|
||||
</script>
|
||||
<script>require('initialize');</script>
|
||||
|
||||
</head>
|
||||
<body class="nano clearfix">
|
||||
<body class="nano clearfix" onload="onLoad();">
|
||||
<div id="fb-root"></div>
|
||||
|
||||
<div id="page-container" class="nano-content"></div>
|
||||
<div id="page-container" class="nano-content">
|
||||
</div>
|
||||
|
||||
<div id="modal-wrapper" class="modal-content"></div>
|
||||
|
||||
<div class="modal fade" id="module-loading-list">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h4 class="modal-title">LOADING</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<ul class="list-group"></ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--<div class="panel panel-primary" id="module-loading-list">-->
|
||||
<!--<div class="panel-heading">-->
|
||||
<!--<div class="panel-title">LOADING</div>-->
|
||||
<!--</div>-->
|
||||
<!--<ul class="list-group"></ul>-->
|
||||
<!--</div>-->
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -4,54 +4,62 @@
|
|||
# http://en.wikipedia.org/wiki/Languages_used_on_the_Internet
|
||||
|
||||
module.exports =
|
||||
en: require './en' # English - English
|
||||
'en-US': require './en-US' # English (US), English (US)
|
||||
'en-GB': require './en-GB' # English (UK), English (UK)
|
||||
'en-AU': require './en-AU' # English (AU), English (AU)
|
||||
ru: require './ru' # русский язык, Russian
|
||||
'de-DE': require './de-DE' # Deutsch (Deutschland), German (Germany)
|
||||
'de-AT': require './de-AT' # Deutsch (Österreich), German (Austria)
|
||||
'de-CH': require './de-CH' # Deutsch (Schweiz), German (Switzerland)
|
||||
'es-419': require './es-419' # español (América Latina), Spanish (Latin America)
|
||||
'es-ES': require './es-ES' # español (ES), Spanish (Spain)
|
||||
'zh-HANS': require './zh-HANS' # 简体中文, Chinese (Simplified)
|
||||
'zh-HANT': require './zh-HANT' # 繁体中文, Chinese (Traditional)
|
||||
'zh-WUU-HANS': require './zh-WUU-HANS' # 吴语, Wuu (Simplified)
|
||||
'zh-WUU-HANT': require './zh-WUU-HANT' # 吳語, Wuu (Traditional)
|
||||
fr: require './fr' # français, French
|
||||
ja: require './ja' # 日本語, Japanese
|
||||
ar: require './ar' # العربية, Arabic
|
||||
'pt-BR': require './pt-BR' # português do Brasil, Portuguese (Brazil)
|
||||
'pt-PT': require './pt-PT' # Português (Portugal), Portuguese (Portugal)
|
||||
pl: require './pl' # język polski, Polish
|
||||
it: require './it' # italiano, Italian
|
||||
tr: require './tr' # Türkçe, Turkish
|
||||
'nl-BE': require './nl-BE' # Nederlands (België), Dutch (Belgium)
|
||||
'nl-NL': require './nl-NL' # Nederlands (Nederland), Dutch (Netherlands)
|
||||
fa: require './fa' # فارسی, Persian
|
||||
cs: require './cs' # čeština, Czech
|
||||
sv: require './sv' # Svenska, Swedish
|
||||
id: require './id' # Bahasa Indonesia, Indonesian
|
||||
el: require './el' # ελληνικά, Greek
|
||||
ro: require './ro' # limba română, Romanian
|
||||
vi: require './vi' # Tiếng Việt, Vietnamese
|
||||
hu: require './hu' # magyar, Hungarian
|
||||
th: require './th' # ไทย, Thai
|
||||
da: require './da' # dansk, Danish
|
||||
ko: require './ko' # 한국어, Korean
|
||||
sk: require './sk' # slovenčina, Slovak
|
||||
sl: require './sl' # slovenščina, Slovene
|
||||
fi: require './fi' # suomi, Finnish
|
||||
bg: require './bg' # български език, Bulgarian
|
||||
no: require './no' # Norsk, Norwegian
|
||||
nn: require './nn' # Norwegian (Nynorsk), Norwegian Nynorsk
|
||||
nb: require './nb' # Norsk Bokmål, Norwegian (Bokmål)
|
||||
he: require './he' # עברית, Hebrew
|
||||
lt: require './lt' # lietuvių kalba, Lithuanian
|
||||
sr: require './sr' # српски, Serbian
|
||||
uk: require './uk' # українська мова, Ukrainian
|
||||
hi: require './hi' # मानक हिन्दी, Hindi
|
||||
ur: require './ur' # اُردُو, Urdu
|
||||
ms: require './ms' # Bahasa Melayu, Bahasa Malaysia
|
||||
ca: require './ca' # Català, Catalan
|
||||
gl: require './gl' # Galego, Galician
|
||||
update: ->
|
||||
localesLoaded = (s for s in window.require.list() when _.string.startsWith(s, 'locale/'))
|
||||
for path in localesLoaded
|
||||
continue if path is 'locale/locale'
|
||||
code = path.replace('locale/', '')
|
||||
@[code] = require(path)
|
||||
|
||||
|
||||
'en': { nativeDescription: 'English', englishDescription: 'English' }
|
||||
'en-US': { nativeDescription: 'English (US)', englishDescription: 'English (US)' }
|
||||
'en-GB': { nativeDescription: 'English (UK)', englishDescription: 'English (UK)' }
|
||||
'en-AU': { nativeDescription: 'English (AU)', englishDescription: 'English (AU)' }
|
||||
'ru': { nativeDescription: 'русский', englishDescription: 'Russian' }
|
||||
'de-DE': { nativeDescription: 'Deutsch (Deutschland)', englishDescription: 'German (Germany)' }
|
||||
'de-AT': { nativeDescription: 'Deutsch (Österreich)', englishDescription: 'German (Austria)' }
|
||||
'de-CH': { nativeDescription: 'Deutsch (Schweiz)', englishDescription: 'German (Switzerland)' }
|
||||
'es-419': { nativeDescription: 'español (América Latina)', englishDescription: 'Spanish (Latin America)' }
|
||||
'es-ES': { nativeDescription: 'español (ES)', englishDescription: 'Spanish (Spain)' }
|
||||
'zh-HANS': { nativeDescription: '简体中文', englishDescription: 'Chinese (Simplified)' }
|
||||
'zh-HANT': { nativeDescription: '繁体中文', englishDescription: 'Chinese (Traditional)' }
|
||||
'zh-WUU-HANS': { nativeDescription: '吴语', englishDescription: 'Wuu (Simplified)' }
|
||||
'zh-WUU-HANT': { nativeDescription: '吳語', englishDescription: 'Wuu (Traditional)' }
|
||||
'fr': { nativeDescription: 'français', englishDescription: 'French' }
|
||||
'ja': { nativeDescription: '日本語', englishDescription: 'Japanese' }
|
||||
'ar': { nativeDescription: 'العربية', englishDescription: 'Arabic' }
|
||||
'pt-BR': { nativeDescription: 'português do Brasil', englishDescription: 'Portuguese (Brazil)' }
|
||||
'pt-PT': { nativeDescription: 'Português (Portugal)', englishDescription: 'Portuguese (Portugal)' }
|
||||
'pl': { nativeDescription: 'język polski', englishDescription: 'Polish' }
|
||||
'it': { nativeDescription: 'Italiano', englishDescription: 'Italian' }
|
||||
'tr': { nativeDescription: 'Türkçe', englishDescription: 'Turkish' }
|
||||
'nl-BE': { nativeDescription: 'Nederlands (België)', englishDescription: 'Dutch (Belgium)' }
|
||||
'nl-NL': { nativeDescription: 'Nederlands (Nederland)', englishDescription: 'Dutch (Netherlands)' }
|
||||
'fa': { nativeDescription: 'فارسی', englishDescription: 'Persian' }
|
||||
'cs': { nativeDescription: 'čeština', englishDescription: 'Czech' }
|
||||
'sv': { nativeDescription: 'Svenska', englishDescription: 'Swedish' }
|
||||
'id': { nativeDescription: 'Bahasa Indonesia', englishDescription: 'Indonesian' }
|
||||
'el': { nativeDescription: 'Ελληνικά', englishDescription: 'Greek' }
|
||||
'ro': { nativeDescription: 'limba română', englishDescription: 'Romanian' }
|
||||
'vi': { nativeDescription: 'Tiếng Việt', englishDescription: 'Vietnamese' }
|
||||
'hu': { nativeDescription: 'magyar', englishDescription: 'Hungarian' }
|
||||
'th': { nativeDescription: 'ไทย', englishDescription: 'Thai' }
|
||||
'da': { nativeDescription: 'dansk', englishDescription: 'Danish' }
|
||||
'ko': { nativeDescription: '한국어', englishDescription: 'Korean' }
|
||||
'sk': { nativeDescription: 'slovenčina', englishDescription: 'Slovak' }
|
||||
'sl': { nativeDescription: 'slovenščina', englishDescription: 'Slovene' }
|
||||
'fi': { nativeDescription: 'suomi', englishDescription: 'Finnish' }
|
||||
'bg': { nativeDescription: 'български език', englishDescription: 'Bulgarian' }
|
||||
'no': { nativeDescription: 'Norsk', englishDescription: 'Norwegian' }
|
||||
'nn': { nativeDescription: 'Norwegian Nynorsk', englishDescription: 'Norwegian' }
|
||||
'nb': { nativeDescription: 'Norsk Bokmål', englishDescription: 'Norwegian (Bokmål)' }
|
||||
'he': { nativeDescription: 'עברית', englishDescription: 'Hebrew' }
|
||||
'lt': { nativeDescription: 'lietuvių kalba', englishDescription: 'Lithuanian' }
|
||||
'sr': { nativeDescription: 'српски', englishDescription: 'Serbian' }
|
||||
'uk': { nativeDescription: 'українська мова', englishDescription: 'Ukrainian' }
|
||||
'hi': { nativeDescription: 'मानक हिन्दी', englishDescription: 'Hindi' }
|
||||
'ur': { nativeDescription: 'اُردُو', englishDescription: 'Urdu' }
|
||||
'ms': { nativeDescription: 'Bahasa Melayu', englishDescription: 'Bahasa Malaysia' }
|
||||
'ca': { nativeDescription: 'Català', englishDescription: 'Catalan' }
|
||||
'gl': { nativeDescription: 'Galego', englishDescription: 'Galician' }
|
|
@ -292,3 +292,27 @@ html.no-borderimage
|
|||
|
||||
body > iframe[src^="https://apis.google.com"]
|
||||
display: none
|
||||
|
||||
#module-loading-list
|
||||
.modal-content
|
||||
background: white
|
||||
border-shadow: 2px 2px 10px black
|
||||
|
||||
ul
|
||||
max-height: 500px
|
||||
overflow: scroll
|
||||
|
||||
li
|
||||
padding: 2px 15px
|
||||
font-size: 10px
|
||||
.glyphicon
|
||||
margin-right: 10px
|
||||
|
||||
&.loading
|
||||
.glyphicon-ok
|
||||
display: none
|
||||
|
||||
&.success
|
||||
font-weight: bold
|
||||
.glyphicon-minus
|
||||
display: none
|
|
@ -1,10 +1,5 @@
|
|||
RootView = require 'views/kinds/RootView'
|
||||
template = require 'templates/home'
|
||||
WizardLank = require 'lib/surface/WizardLank'
|
||||
ThangType = require 'models/ThangType'
|
||||
Simulator = require 'lib/simulator/Simulator'
|
||||
|
||||
{me} = require '/lib/auth'
|
||||
|
||||
module.exports = class HomeView extends RootView
|
||||
id: 'home-view'
|
||||
|
@ -47,10 +42,6 @@ module.exports = class HomeView extends RootView
|
|||
afterInsert: ->
|
||||
super(arguments...)
|
||||
@$el.addClass 'hour-of-code' if @explainsHourOfCode
|
||||
if me.isAdmin() and me.get('slug') is 'nick'
|
||||
LevelSetupManager = require 'lib/LevelSetupManager'
|
||||
setupManager = new LevelSetupManager levelID: 'dungeons-of-kithgard', hadEverChosenHero: true, parent: @
|
||||
setupManager.open()
|
||||
|
||||
setUpHourOfCode: ->
|
||||
elapsed = (new Date() - new Date(me.get('dateCreated')))
|
||||
|
|
|
@ -6,6 +6,10 @@ World = require 'lib/world/world'
|
|||
DocumentFiles = require 'collections/DocumentFiles'
|
||||
LevelLoader = require 'lib/LevelLoader'
|
||||
|
||||
# in the template, but need to require them to load them
|
||||
require 'views/modal/RevertModal'
|
||||
require 'views/editor/level/modals/GenerateTerrainModal'
|
||||
|
||||
ThangsTabView = require './thangs/ThangsTabView'
|
||||
SettingsTabView = require './settings/SettingsTabView'
|
||||
ScriptsTabView = require './scripts/ScriptsTabView'
|
||||
|
|
|
@ -6,6 +6,9 @@ LayerAdapter = require 'lib/surface/LayerAdapter'
|
|||
Camera = require 'lib/surface/Camera'
|
||||
DocumentFiles = require 'collections/DocumentFiles'
|
||||
|
||||
# in the template, but need to require to load them
|
||||
require 'views/modal/RevertModal'
|
||||
|
||||
RootView = require 'views/kinds/RootView'
|
||||
ThangComponentsEditView = require 'views/editor/component/ThangComponentsEditView'
|
||||
ThangTypeVersionsModal = require './ThangTypeVersionsModal'
|
||||
|
|
|
@ -4,6 +4,9 @@ Patch = require 'models/Patch'
|
|||
template = require 'templates/i18n/i18n-edit-model-view'
|
||||
deltasLib = require 'lib/deltas'
|
||||
|
||||
# in the template, but need to require to load them
|
||||
require 'modal/RevertModal'
|
||||
|
||||
module.exports = class I18NEditModelView extends RootView
|
||||
className: 'editor i18n-edit-model-view'
|
||||
template: template
|
||||
|
|
|
@ -139,8 +139,16 @@ module.exports = class RootView extends CocoView
|
|||
newLang = $('.language-dropdown').val()
|
||||
$.i18n.setLng(newLang, {})
|
||||
@saveLanguage(newLang)
|
||||
|
||||
loading = application.moduleLoader.loadLanguage(me.get('preferredLanguage', true))
|
||||
if loading
|
||||
@listenToOnce application.moduleLoader, 'load-complete', @onLanguageLoaded
|
||||
else
|
||||
@onLanguageLoaded()
|
||||
|
||||
onLanguageLoaded: ->
|
||||
@render()
|
||||
unless newLang.split('-')[0] is 'en'
|
||||
unless me.get('preferredLanguage').split('-')[0] is 'en'
|
||||
DiplomatModal = require 'views/modal/DiplomatSuggestionModal'
|
||||
@openModalView(new DiplomatModal())
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
RootView = require 'views/kinds/RootView'
|
||||
template = require 'templates/play'
|
||||
template = require 'templates/main-play-view'
|
||||
LevelSession = require 'models/LevelSession'
|
||||
CocoCollection = require 'collections/CocoCollection'
|
||||
|
||||
|
|
154
config.coffee
154
config.coffee
|
@ -1,21 +1,109 @@
|
|||
#- Imports, helpers
|
||||
_ = require 'lodash'
|
||||
_.str = require 'underscore.string'
|
||||
sysPath = require 'path'
|
||||
startsWith = (string, substring) ->
|
||||
string.lastIndexOf(substring, 0) is 0
|
||||
fs = require('fs')
|
||||
commonjsHeader = fs.readFileSync('node_modules/brunch/node_modules/commonjs-require-definition/require.js', {encoding: 'utf8'})
|
||||
regJoin = (s) -> new RegExp(s.replace(/\//, '[\\\/\\\\]'))
|
||||
|
||||
|
||||
#- Find all .coffee and .jade files in /app
|
||||
|
||||
dirStack = ['./app']
|
||||
coffeeFiles = []
|
||||
jadeFiles = []
|
||||
|
||||
while dirStack.length
|
||||
dir = dirStack.pop()
|
||||
contents = fs.readdirSync(dir)
|
||||
for file in contents
|
||||
fullPath = "#{dir}/#{file}"
|
||||
stat = fs.statSync(fullPath)
|
||||
if stat.isDirectory()
|
||||
dirStack.push(fullPath)
|
||||
else
|
||||
if _.str.endsWith(file, '.coffee')
|
||||
coffeeFiles.push(fullPath)
|
||||
else if _.str.endsWith(file, '.jade')
|
||||
jadeFiles.push(fullPath)
|
||||
|
||||
console.log "Got #{coffeeFiles.length} coffee files and #{jadeFiles.length} jade files."
|
||||
|
||||
|
||||
#- Build the config
|
||||
|
||||
exports.config =
|
||||
|
||||
paths:
|
||||
public: 'public'
|
||||
watched: ['app', 'vendor', 'test/app', 'test/demo']
|
||||
|
||||
conventions:
|
||||
ignored: (path) -> startsWith(sysPath.basename(path), '_')
|
||||
sourceMaps: true
|
||||
ignored: (path) -> _.str.startsWith(sysPath.basename(path), '_')
|
||||
|
||||
sourceMaps: 'absoluteUrl'
|
||||
|
||||
overrides:
|
||||
production:
|
||||
sourceMaps: true
|
||||
sourceMaps: 'absoluteUrl'
|
||||
|
||||
files:
|
||||
javascripts:
|
||||
defaultExtension: 'coffee'
|
||||
joinTo:
|
||||
|
||||
#- app.js, the first file that is loaded. These modules are required to initialize the client.
|
||||
'javascripts/app.js': [
|
||||
|
||||
# IMPORTANT: if you add to this, make sure you also add any other dependencies
|
||||
regJoin('^app/schemas')
|
||||
regJoin('^app/models')
|
||||
regJoin('^app/collections')
|
||||
|
||||
'app/locale/locale.coffee'
|
||||
|
||||
'app/application.coffee'
|
||||
'app/initialize.coffee'
|
||||
'app/Router.coffee'
|
||||
'app/ModuleLoader.coffee'
|
||||
'app/treema-ext.coffee'
|
||||
|
||||
'app/collections/NewAchievementCollection.coffee'
|
||||
'app/collections/CocoCollection.coffee'
|
||||
|
||||
'app/lib/FacebookHandler.coffee'
|
||||
'app/lib/GPlusHandler.coffee'
|
||||
'app/lib/GitHubHandler.coffee'
|
||||
'app/lib/auth.coffee'
|
||||
'app/lib/Tracker.coffee'
|
||||
'app/lib/CocoClass.coffee'
|
||||
'app/lib/errors.coffee'
|
||||
'app/lib/storage.coffee'
|
||||
'app/lib/utils.coffee'
|
||||
'app/lib/forms.coffee'
|
||||
'app/lib/deltas.coffee'
|
||||
'app/lib/contact.coffee'
|
||||
'app/lib/sprites/SpriteBuilder.coffee'
|
||||
'app/lib/SystemNameLoader.coffee'
|
||||
regJoin('^app/lib/services')
|
||||
|
||||
regJoin('^app/views/kinds')
|
||||
'app/views/NotFoundView.coffee'
|
||||
'app/views/achievements/AchievementPopup.coffee'
|
||||
'app/views/modal/ContactModal.coffee'
|
||||
'app/views/modal/NewModelModal.coffee'
|
||||
'app/views/modal/RevertModal.coffee'
|
||||
'app/views/modal/DiplomatSuggestionModal.coffee'
|
||||
]
|
||||
|
||||
#- Wads. Groups of modules by folder which are loaded as a group when needed.
|
||||
'javascripts/app/lib/surface.js': regJoin('^app/lib/surface')
|
||||
'javascripts/app/lib/world.js': regJoin('^app/lib/world')
|
||||
'javascripts/app/views/play.js': regJoin('^app/views/play')
|
||||
'javascripts/app/views/game-menu.js': regJoin('^app/views/game-menu')
|
||||
'javascripts/app/views/editor.js': regJoin('^app/views/editor')
|
||||
|
||||
#- world.js, used by the worker to generate the world in game
|
||||
'javascripts/world.js': ///^(
|
||||
(app[\/\\]lib[\/\\]world(?![\/\\]test))
|
||||
|(app[\/\\]lib[\/\\]CocoClass.coffee)
|
||||
|
@ -24,11 +112,14 @@ exports.config =
|
|||
|(vendor[\/\\]scripts[\/\\]string_score.js)
|
||||
|(bower_components[\/\\]underscore.string)
|
||||
)///
|
||||
'javascripts/app.js': /^app/
|
||||
|
||||
#- vendor.js, all the vendor libraries
|
||||
'javascripts/vendor.js': ///^(
|
||||
vendor[\/\\](?!scripts[\/\\]Box2d)
|
||||
|bower_components[\/\\](?!aether)
|
||||
)///
|
||||
|
||||
#- Other vendor libraries in separate bunches
|
||||
'javascripts/box2d.js': ///^(
|
||||
# Include box2dweb for profiling and IE9
|
||||
# Vector renamed to Box2DVector to avoid name collisions
|
||||
|
@ -41,6 +132,8 @@ exports.config =
|
|||
'javascripts/aether.js': ///^(
|
||||
(bower_components[\/\\]aether[\/\\]build[\/\\]aether.js)
|
||||
)///
|
||||
|
||||
#- test, demo libraries
|
||||
'javascripts/test-app.js': /^test[\/\\]app/
|
||||
'javascripts/demo-app.js': /^test[\/\\]demo/
|
||||
|
||||
|
@ -66,6 +159,7 @@ exports.config =
|
|||
'vendor/scripts/async.js'
|
||||
'vendor/scripts/jquery-ui-1.11.1.js.custom.js'
|
||||
]
|
||||
|
||||
stylesheets:
|
||||
defaultExtension: 'sass'
|
||||
joinTo:
|
||||
|
@ -75,9 +169,28 @@ exports.config =
|
|||
'app/styles/bootstrap/*'
|
||||
'vendor/styles/nanoscroller.scss'
|
||||
]
|
||||
|
||||
templates:
|
||||
defaultExtension: 'jade'
|
||||
joinTo: 'javascripts/app.js'
|
||||
joinTo:
|
||||
'javascripts/app.js': [
|
||||
'app/templates/modal/error.jade'
|
||||
'app/templates/not_found.jade'
|
||||
'app/templates/achievements/achievement-popup.jade'
|
||||
'app/templates/loading.jade'
|
||||
'app/templates/loading_error.jade'
|
||||
'app/templates/modal/contact.jade'
|
||||
'app/templates/modal/modal_base.jade'
|
||||
'app/templates/kinds/search.jade'
|
||||
'app/templates/modal/new_model.jade'
|
||||
'app/templates/modal/revert.jade'
|
||||
'app/templates/kinds/user.jade'
|
||||
'app/templates/modal/diplomat_suggestion.jade'
|
||||
]
|
||||
'javascripts/app/views/play.js': regJoin('^app/templates/play')
|
||||
'javascripts/app/views/game-menu.js': regJoin('^app/templates/game-menu')
|
||||
'javascripts/app/views/editor.js': regJoin('^app/templates/editor')
|
||||
|
||||
framework: 'backbone'
|
||||
|
||||
plugins:
|
||||
|
@ -85,6 +198,7 @@ exports.config =
|
|||
delay: 300
|
||||
coffeelint:
|
||||
pattern: /^app\/.*\.coffee$/
|
||||
# pattern: /^dne/ # use this pattern instead if you want to speed compilation
|
||||
options:
|
||||
line_endings:
|
||||
value: 'unix'
|
||||
|
@ -102,11 +216,21 @@ exports.config =
|
|||
mode: 'ruby'
|
||||
allowCache: true
|
||||
|
||||
onCompile: (files) ->
|
||||
exec = require('child_process').exec
|
||||
regexFrom = '\\/\\/# sourceMappingURL=([^\\/].*)\\.map'
|
||||
regexTo = '\\/\\/# sourceMappingURL=\\/javascripts\\/$1\\.map'
|
||||
regex = "s/#{regexFrom}/#{regexTo}/g"
|
||||
for file in files
|
||||
c = "perl -pi -e '#{regex}' #{file.path}"
|
||||
exec c
|
||||
modules:
|
||||
definition: (path, data) ->
|
||||
needHeaders = [
|
||||
'public/javascripts/app.js'
|
||||
'public/javascripts/world.js'
|
||||
]
|
||||
defn = if path in needHeaders then commonjsHeader else ''
|
||||
return defn
|
||||
|
||||
for file in coffeeFiles
|
||||
inputFile = file.replace('./app', 'app')
|
||||
outputFile = file.replace('.coffee', '.js').replace('./app', 'javascripts/app')
|
||||
exports.config.files.javascripts.joinTo[outputFile] = inputFile
|
||||
|
||||
for file in jadeFiles
|
||||
inputFile = file.replace('./app', 'app')
|
||||
outputFile = file.replace('.jade', '.js').replace('./app', 'javascripts/app')
|
||||
exports.config.files.templates.joinTo[outputFile] = inputFile
|
||||
|
|
|
@ -112,9 +112,14 @@ exports.setupMiddleware = (app) ->
|
|||
setupTrailingSlashRemovingMiddleware app
|
||||
setupRedirectMiddleware app
|
||||
setupErrorMiddleware app
|
||||
|
||||
setupJavascript404s app
|
||||
|
||||
###Routing function implementations###
|
||||
|
||||
setupJavascript404s = (app) ->
|
||||
app.get '/javascripts/*', (req, res) ->
|
||||
res.status(404).send('Not found')
|
||||
|
||||
setupFallbackRouteToIndex = (app) ->
|
||||
app.all '*', (req, res) ->
|
||||
if req.user
|
||||
|
|
Loading…
Reference in a new issue