Permalink
Browse files

Mostly working, still an odd line bug

  • Loading branch information...
1 parent 9094d4a commit 906ee4cad6e66da362f5e7b0460293a9ce90f1b6 @download13 committed May 13, 2012
Showing with 114 additions and 59 deletions.
  1. +24 −7 lib/source-build.js
  2. +40 −18 lib/source-package.js
  3. +25 −3 lib/sourcemap.js
  4. +23 −29 lib/write.js
  5. +2 −2 resources/source-package.mustache
View
@@ -46,9 +46,10 @@ var async = require('async')
init: function (options) {
this.options = options
this.packages = []
-
- this.sourcesMap = {};
-
+
+ this.asString = this.asString.bind(this) // Are these needed?
+ this.sources = this.sources.bind(this)
+
return this
}
@@ -68,10 +69,6 @@ var async = require('async')
}).join(' ')
}
- this.packages.forEach(function(v, i) {
- this.sourcesMap[v.filename] = v.fileContents;
- }, this);
-
template.generateSource(templateFile, data, function (err, source) {
if (err) return callback(err) // wrapped in template.js
if (options.type === 'minified') minify.minify(source, callback)
@@ -91,6 +88,26 @@ var async = require('async')
}
)
}
+
+ , sources: function (callback) {
+ async.map(
+ this.packages
+ , function (srcPackage, callback) {
+ srcPackage.sources(callback)
+ }
+ , function (err, sources) {
+ if (err) return callback(err)
+
+ var glom = {}
+ sources.forEach(function (v) {
+ for(var file in v) {
+ glom[file] = v[file]
+ }
+ })
+ callback(null, glom)
+ }
+ )
+ }
}
// a utility static method to partially read an ender build file and parse the head comment
View
@@ -48,6 +48,7 @@ var fs = require('fs')
template.generateSource(templateFiles[root ? 'root' : 'standard'], data, callback)
}
+ , INDENT_STR = ' '
, indent = function (str) {
// was this: return str.replace(/^(?!\s*$)/gm, ' ')
// but in some odd cases ^ was matching other things and inserting ' ' in unhelpful places
@@ -57,7 +58,7 @@ var fs = require('fs')
// which starts with: // If the space parameter...
// and gets converted to: / / If the space parameter
return str.split('\n').map(function (line) {
- return (/^\s*$/).test(line) ? line : (' ' + line)
+ return (/^\s*$/).test(line) ? line : (INDENT_STR + line)
}).join('\n')
}
@@ -68,10 +69,12 @@ var fs = require('fs')
this.isRoot = isRoot
this.packageName = packageName
this.packageJSON = packageJSON
+ this.rootPath = packageUtil.getPackageRoot(this.parents, this.packageName)
// custom hasher function for async.memoize so we have a single key, default will use
// first arg (callback) as hash key which won't work
this.asString = async.memoize(this.asString.bind(this), function () { return '_' })
+ this.sources = this.sources.bind(this)
return this
}
@@ -80,7 +83,8 @@ var fs = require('fs')
}
// utility to read multiple files in order and append them
- , loadFilesAsString: function (root, files, callback) {
+ // might want to memoize this so we don't have to read the files twice
+ , loadFiles: function (files, callback) {
if (!Array.isArray(files)) files = [ files ]
if (!files.length || (files.length == 1 && files[0] == 'noop')) return callback()
@@ -89,15 +93,13 @@ var fs = require('fs')
async.map(
files
, function (file, callback) {
- file = path.join(root, file).replace(/(\.js)?$/, '.js')
- fs.readFile(file, 'utf-8', function (err, contents) {
+ file = path.join(this.rootPath, file).replace(/(\.js)?$/, '.js')
+ fs.readFile(file, 'utf-8', function (err, content) {
if (err) return callback(new FilesystemError(err))
- callback.apply(null, arguments)
+ callback(err, {file: file, content: content})
})
- }
- , function (err, sources) {
- callback(err, sources && sources.join('\n\n'))
- }
+ }.bind(this)
+ , callback
)
}
@@ -131,17 +133,17 @@ var fs = require('fs')
// note that "main" and "ender" are processed in the same way so they can both be just
// a string pointing to a source file or an array of source files that are concatenated
// or be left unspecified
- var root = packageUtil.getPackageRoot(this.parents, this.packageName)
- , packageName = this.packageJSON.name
+ var packageName = this.packageJSON.name
, mainSources = this.packageJSON.main || []
, enderBridgeSources = this.packageJSON.ender || []
, handleSourceData = function (err, sources) {
if (err) return callback(err)
-
- this.filename = path.join(root, mainSources).replace(/(\.js)?$/, '.js')
- this.fileContents = sources.main;
-
+ for(var name in sources) {
+ if (sources[name]) {
+ sources[name] = sources[name].map(function (v) { return v.content }).join('\n\n')
+ }
+ }
generateSource(
this.isRoot
, this.makeTemplateData(sources)
@@ -150,14 +152,34 @@ var fs = require('fs')
}.bind(this)
, sourceLoaders = {
- main: this.loadFilesAsString.bind(this, root, mainSources)
- , ender: this.loadFilesAsString.bind(this, root, enderBridgeSources)
+ main: this.loadFiles.bind(this, mainSources)
+ , ender: this.loadFiles.bind(this, enderBridgeSources)
}
async.parallel(sourceLoaders, handleSourceData)
}
+
+ , sources: function (callback) {
+ async.parallel({
+ main: this.loadFiles.bind(this, this.packageJSON.main || [])
+ , ender: this.loadFiles.bind(this, this.packageJSON.ender || [])
+ }, function (err, sources) {
+ if (err) return callback(err)
+
+ var map = {}
+ if (sources.main) {
+ map[path.relative('.', sources.main[0].file)] = sources.main[0].content // HACK: Why would there be more than one? If there's a good reason I'll add an iterator
+ }
+ if (sources.ender) {
+ map[path.relative('.', sources.ender[0].file)] = sources.ender[0].content
+ }
+ callback(err, map)
+ }.bind(this))
+ }
}
module.exports.create = function (packageName, parents, isRoot, packageJSON, options) {
return Object.create(SourcePackage).init(packageName, parents, isRoot, packageJSON, options)
-}
+}
+exports.indent = indent;
+exports.INDENT_STR = INDENT_STR;
View
@@ -1,3 +1,5 @@
+var SourcePackage = require('./source-package');
+
function SourceMap(data) {
data = JSON.parse(data);
this.sources = data.sources;
@@ -28,6 +30,24 @@ function SourceMap(data) {
});
});
}
+SourceMap.buildSourceMap = function(options, plainSource, sources, orgMap) {
+ var map = {}
+ for(var filepath in sources) {
+ var source = sources[filepath], cols = 0
+ if (!options.noop) { // This may not work if the template changes. Solutions?
+ source = SourcePackage.indent(source)
+ cols = SourcePackage.INDENT_STR.length
+ }
+
+ var start = plainSource.indexOf(source)
+ var offset = plainSource.substr(0, start).split('\n').length - 1
+ map[filepath] = {offsetTop: offset, offsetLeft: cols, lines: source.split('\n').length}
+ }
+
+ var sm = new SourceMap(orgMap)
+ sm.translate(map)
+ return sm.serialize()
+}
SourceMap.prototype = {
translate: function(offsetMap) {
var sources = this.sources = Object.keys(offsetMap);
@@ -36,19 +56,21 @@ SourceMap.prototype = {
sources.forEach(function(sourceName, sourceIndex) {
var source = offsetMap[sourceName];
- var offset = source.offset;
+ var offsetTop = source.offsetTop;
+ var offsetLeft = source.offsetLeft;
var lines = source.lines;
groups.forEach(function(segments, minline) {
segments.forEach(function(segment) {
if(segment.field3 == null) {
return;
}
- var tmp = segment.field3 - offset;
+ var tmp = segment.field3 - offsetTop;
if(tmp >= 0 && tmp < lines) {
- //console.log(sourceName, offset, lines, tmp + ' <- ' + segment.field3, (self.names[segment.field5] || segment.field5) + ' <- ' + segment.field4);
+ console.log(sourceName, offsetTop, lines, tmp + ' <- ' + segment.field3, segment.field4 - offsetLeft + ' <- ' + segment.field4, (self.names[segment.field5] || segment.field5));
segment.field3 = tmp;
segment.field2 = sourceIndex;
+ segment.field4 -= offsetLeft;
}
});
});
View
@@ -34,6 +34,7 @@ var fs = require('fs')
, async = require('async')
, util = require('./util')
, FilesystemError = require('./errors').FilesystemError
+ , SourceMap = require('./sourcemap')
, writeFile = function (file, data, callback) {
fs.writeFile(file, data, 'utf-8', function (err) {
@@ -43,35 +44,28 @@ var fs = require('fs')
}
, write = function (options, sourceBuild, out, callback) {
- sourceBuild.asString({ type: 'plain' }, function(err, source) {
- var filename = util.getOutputFilenameFromOptions(options)
- var nonMinSource = source;
-
- writeFile(filename, source, function() {
- var filename = util.getOutputFilenameFromOptions(options).replace(/(\.min)?\.js/, '.min.js')
- sourceBuild.asString({ type: 'minified' }, function(err, source, sourceMapSeg2) {
- var sourcesMap = sourceBuild.sourcesMap;
- var offsetMap = {};
-
- for(var sourcePath in sourcesMap) {
- var relpath = path.relative('.', sourcePath);
- var start = nonMinSource.indexOf(sourcesMap[sourcePath]);
- var offset = nonMinSource.substr(0, start).split('\n').length - 1;
- offsetMap[relpath] = {offset: offset, lines: sourcesMap[sourcePath].split('\n').length};
- }
-
- var SourceMap = require('./sourcemap');
- var sm = new SourceMap(sourceMapSeg2);
- sm.translate(offsetMap);
- var sourceMap = sm.serialize();
-
- source += '//@ sourceMappingURL=ender.map.js'; // For demo purposes
- writeFile(filename, source, function() {
- writeFile('ender.map.js', sourceMap, callback);
- });
- })
- })
- })
+ var plainFilename = util.getOutputFilenameFromOptions(options), sourceMap
+ var mapFilename = plainFilename.replace(/(\.min)?\.js/, '.map.js')
+ // These can't really be separate since now the write stages depend on one-another
+ async.parallel({
+ plainSource: sourceBuild.asString.bind(null, {type: 'plain'})
+ , miniSource: function (callback) {
+ sourceBuild.asString({type: 'minified'}, function (err, minified, map) { // Is there a better way to get the source map from the minifier?
+ sourceMap = map
+ callback(err, minified)
+ })
+ }
+ , sources: sourceBuild.sources
+ }, function (err, results) {
+ sourceMap = SourceMap.buildSourceMap(options, results.plainSource, results.sources, sourceMap)
+ var miniSource = results.miniSource + '//@ sourceMappingURL=' + mapFilename; // We might want an option for this too
+
+ async.parallel([
+ writeFile.bind(null, plainFilename, results.plainSource)
+ , writeFile.bind(null, plainFilename.replace(/(\.min)?\.js/, '.min.js'), miniSource)
+ , writeFile.bind(null, mapFilename, sourceMap)
+ ], callback)
+ })
}
module.exports.write = write
@@ -4,14 +4,14 @@
var module = { exports: {} }, exports = module.exports;
{{#mainSource}}
-{{{raw}}}{{/mainSource}}
+{{{indented}}}{{/mainSource}}
provide("{{packageName}}", module.exports);
{{#options.sandbox}}
window["{{packageName}}"] = module.exports;
{{/options.sandbox}}{{#enderSource}}
-{{{raw}}}
+{{{indented}}}
{{/enderSource}}
{{^enderSource}}
$.ender(module.exports);

0 comments on commit 906ee4c

Please sign in to comment.