neft
Version:
Universal Platform
128 lines (103 loc) • 3.65 kB
text/coffeescript
'use strict'
fs = require 'fs-extra'
pathUtils = require 'path'
coffee = require 'coffee-script'
moduleCache = require 'lib/module-cache'
cliUtils = require 'cli/utils'
utils = require 'src/utils'
log = require 'src/log'
Document = require 'src/document'
styles = require 'src/styles'
signal = require 'src/signal'
IN_DIR = 'components'
OUT_DIR = 'build'
SCRIPTS_DIR = './build/scripts'
STYLES_DIR = './build/styles'
Document.FILES_PATH = IN_DIR
Document.SCRIPTS_PATH = SCRIPTS_DIR
Document.STYLES_PATH = STYLES_DIR
loadedExtensions = {}
class DocumentParseError extends Error
constructor: (@message, @previousError) ->
if @previousError
@message += "\n\n#{@previousError.message}"
module.exports = (platform, app, callback) ->
unless fs.existsSync(IN_DIR)
return callback null
logtime = log.time 'Parse documents'
parsingError = null
# clear
fs.removeSync "./#{OUT_DIR}/#{IN_DIR}"
fs.removeSync SCRIPTS_DIR
# install document extensions
for ext in app.allExtensions
path = pathUtils.join ext.path, '/app.js'
if not loadedExtensions[ext.name] and fs.existsSync(path)
loadedExtensions[ext.name] = true
require(path)()
styles {windowStyle: null, styles: {}, queries: app.styleQueries}
utils.clear Document._files
mainPaths = Object.create null
Document.onError onErrorListener = (error) ->
if error instanceof Document.LoadError
mainPaths[error.path] = true
parseFile error.path
Document.onBeforeParse onBeforeParseListener = (file) ->
if mainPaths[file.path]
Document.Style.applyStyleQueriesInDocument file
return
Document.onParse onParseListener = (file) ->
Document.Style.createStylesInDocument file
return
Document.onStyle onStyleListener = (style) ->
app.styles.push
name: style.filename
path: style.path
return
parseFile = (path) ->
log.show "Parse document '#{path}'"
try
html = moduleCache.getFileSync path
catch
log.error "File `#{path}` doesn't exist"
return
file = Document.fromHTML path, html
try
Document.parse file
catch error
msg = "Cannot parse file '#{path}'\n#{error.stack}"
parsingError = new DocumentParseError msg, parsingError
return
file
saveComponent = (name, component, callback) ->
json = JSON.stringify component
json = "module.exports = #{json}"
path = "#{OUT_DIR}/#{name}.js"
app.components.push {name, path}
fs.outputFile path, json, 'utf-8', callback
return
onFilesParsed = ->
stack = new utils.async.Stack
for name, component of Document._files
stack.add saveComponent, null, [name, component]
stack.runAllSimultaneously onViewsSaved
onViewsSaved = (err) ->
if err
return callback err
# clear listeners
Document.onError.disconnect onErrorListener
Document.onBeforeParse.disconnect onBeforeParseListener
Document.onParse.disconnect onParseListener
Document.onStyle.disconnect onStyleListener
log.end logtime
callback parsingError
return
cliUtils.forEachFileDeep IN_DIR, (path, stat) ->
if /\..*ml$/.test(path) and not Document._files[path]
mainPaths[path] = true
parseFile path
, (err) ->
if err
log.end logtime
return callback err
onFilesParsed()