Comparing version 0.10.17 to 0.10.18
@@ -19,2 +19,3 @@ /* | ||
var files = require('./files'); | ||
var parsing = require('../parsing'); | ||
@@ -218,6 +219,3 @@ var STYLE_EXTENSIONS = ['.css']; | ||
var data = files.loadViewsSync(this, filename, namespace); | ||
for (var i = 0, len = data.views.length; i < len; i++) { | ||
var item = data.views[i]; | ||
this.views.register(item.name, item.source, item.options); | ||
} | ||
parsing.registerParsedViews(this, data.views); | ||
if (!util.isProduction) this._watchViews(data.files, filename, namespace); | ||
@@ -224,0 +222,0 @@ // Make chainable |
105
lib/files.js
/* | ||
* files.js | ||
* loads templates, configurations and other files from disk | ||
* load templates and styles from disk | ||
* | ||
@@ -10,4 +10,4 @@ */ | ||
var util = require('racer/lib/util'); | ||
var htmlUtil = require('html-util'); | ||
var resolve = require('resolve'); | ||
var parsing = require('../parsing'); | ||
@@ -22,10 +22,13 @@ exports.loadViewsSync = loadViewsSync; | ||
var files = []; | ||
var resolved = resolve.sync(sourceFilename, {extensions: app.viewExtensions, packageFilter: deleteMain}); | ||
if (!resolved) { | ||
var filename = resolve.sync(sourceFilename, { | ||
extensions: app.viewExtensions, | ||
packageFilter: deleteMain} | ||
); | ||
if (!filename) { | ||
throw new Error('View template file not found: ' + sourceFilename); | ||
} | ||
var file = fs.readFileSync(resolved, 'utf8'); | ||
var file = fs.readFileSync(filename, 'utf8'); | ||
var extension = path.extname(resolved); | ||
var extension = path.extname(filename); | ||
var compiler = app.compilers[extension]; | ||
@@ -36,85 +39,33 @@ if (!compiler) { | ||
var htmlFile = compiler(file, resolved); | ||
var parsed = parseViews(namespace, htmlFile, resolved, app.viewExtensions); | ||
for (var i = 0, len = parsed.imports.length; i < len; i++) { | ||
var item = parsed.imports[i]; | ||
var imported = loadViewsSync(app, item.filename, item.namespace); | ||
function onImport(attrs) { | ||
var dir = path.dirname(filename); | ||
var importFilename = resolve.sync(attrs.src, { | ||
basedir: dir, | ||
extensions: app.viewExtensions, | ||
packageFilter: deleteMain | ||
}); | ||
var importNamespace = parsing.getImportNamespace(namespace, attrs, importFilename); | ||
var imported = loadViewsSync(app, importFilename, importNamespace); | ||
views = views.concat(imported.views); | ||
files = files.concat(imported.files); | ||
} | ||
var htmlFile = compiler(file, filename); | ||
var parsedViews = parsing.parseViews(htmlFile, namespace, filename, onImport); | ||
return { | ||
views: views.concat(parsed.views) | ||
, files: files.concat(resolved) | ||
views: views.concat(parsedViews), | ||
files: files.concat(filename) | ||
}; | ||
} | ||
function htmlCompiler(file, filename) { | ||
function htmlCompiler(file) { | ||
return file; | ||
} | ||
function parseViews(namespace, file, filename, extensions) { | ||
var imports = []; | ||
var views = []; | ||
var prefix = (namespace) ? namespace + ':' : ''; | ||
htmlUtil.parse(file + '\n', { | ||
// Force view tags to be treated as raw tags, | ||
// meaning their contents are not parsed as HTML | ||
rawTags: /^(?:[^\s=\/!>]+:|style|script)$/i | ||
, matchEnd: matchEnd | ||
, start: onStart | ||
, text: onText | ||
}); | ||
function matchEnd(tagName) { | ||
if (tagName.slice(-1) === ':') { | ||
return /<\/?[^\s=\/!>]+:[\s>]/i; | ||
} | ||
return new RegExp('</' + tagName, 'i'); | ||
} | ||
// These variables pass state from attributes in the start tag to the | ||
// following view template text | ||
var name, attrs; | ||
function onStart(tag, tagName, tagAttrs) { | ||
var lastChar = tagName.charAt(tagName.length - 1); | ||
if (lastChar !== ':') { | ||
throw new Error('Expected tag ending in colon (:) instead of ' + tag); | ||
} | ||
name = tagName.slice(0, -1); | ||
attrs = tagAttrs; | ||
if (name === 'import') { | ||
var dir = path.dirname(filename); | ||
var resolved = resolve.sync(attrs.src, {basedir: dir, extensions: extensions, packageFilter: deleteMain}); | ||
var extension = path.extname(resolved); | ||
var importNamespace = (attrs.ns == null) ? | ||
path.basename(attrs.src, extension) : attrs.ns; | ||
imports.push({ | ||
filename: resolved | ||
, namespace: (!importNamespace) ? namespace : prefix + importNamespace | ||
}); | ||
} | ||
} | ||
function onText(text, isRawText) { | ||
if (!name || name === 'import') return; | ||
views.push({ | ||
name: prefix + name | ||
, source: text | ||
, options: attrs | ||
, filename: filename | ||
}); | ||
} | ||
return { | ||
imports: imports | ||
, views: views | ||
}; | ||
} | ||
function loadStylesSync(app, sourceFilename, options) { | ||
options || (options = {compress: util.isProduction}); | ||
var resolved = resolve.sync(sourceFilename, {extensions: app.styleExtensions, packageFilter: deleteMain}); | ||
var resolved = resolve.sync(sourceFilename, { | ||
extensions: app.styleExtensions, | ||
packageFilter: deleteMain} | ||
); | ||
if (!resolved) { | ||
@@ -121,0 +72,0 @@ throw new Error('Style file not found: ' + sourceFilename); |
{ | ||
"name": "derby", | ||
"description": "MVC framework making it easy to write realtime, collaborative applications that run in both Node.js and browsers.", | ||
"version": "0.10.17", | ||
"version": "0.10.18", | ||
"homepage": "http://derbyjs.com/", | ||
@@ -6,0 +6,0 @@ "repository": { |
172365
37
4420