Skip to content

Commit 443f5bc

Browse files
committed
Merge pull request #26 from angularity/0-1-0-RC
interim release 0.0.21
2 parents a18c902 + 3b344db commit 443f5bc

File tree

8 files changed

+235
-1165
lines changed

8 files changed

+235
-1165
lines changed

lib/build/browserify.js

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
var fs = require('fs');
22
var path = require('path');
33
var through = require('through2');
4+
var merge = require('lodash.merge');
45
var trackFilenames = require('gulp-track-filenames');
56
var transformTools = require('browserify-transform-tools');
67
var browserify = require('browserify');
@@ -230,10 +231,11 @@ function compile(bannerWidth, transforms) {
230231
// transforms
231232
transforms
232233
.concat(requireTransform(false))
233-
.filter(function (candidate) {
234-
return (typeof candidate === 'function');
235-
}).forEach(function (item) {
236-
bundler.transform(item, { global: true });
234+
.forEach(function (item, i, list) {
235+
if (typeof item === 'function') {
236+
var opts = (typeof list[i+1] === 'object') ? merge({ global: true }, list[i+1]) : { global: true };
237+
bundler.transform(item, opts);
238+
}
237239
});
238240

239241
// require statements

lib/build/node-sass.js

Lines changed: 87 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
var path = require('path');
22
var fs = require('fs');
33
var through = require('through2');
4-
var minimatch = require('minimatch');
54
var sass = require('node-sass');
65
var gutil = require('gulp-util');
76
var slash = require('gulp-slash');
@@ -12,52 +11,76 @@ var SourceMapConsumer = require('source-map').SourceMapConsumer;
1211
var mime = require('mime');
1312

1413
/**
15-
* Search for the relative file reference from the <code>startPath</code> up to, but not including, the process
16-
* working directory.
17-
* @param {string} startPath The path to which the <code>relative</code> path might be specified
18-
* @param {string} relative A possibly relative file path
19-
* @param {string} [callerPath] The full path of the invoking function instance where recursion has occured
14+
* Search for the relative file reference from the <code>startPath</code> up to the process
15+
* working directory, avoiding any other directories with a <code>package.json</code> or <code>bower.json</code>.
16+
* @param {string} startPath The location of the uri declaration and the place to start the search from
17+
* @param {string} uri The content of the url() statement, expected to be a relative file path
2018
* @returns {string} dataURI of the file where found or <code>undefined</code> otherwise
2119
*/
22-
function encodeRelativeURL(startPath, relative, callerPath) {
23-
24-
// ensure we are at a valid start path that is not process working directory
25-
var absStart = path.resolve(startPath);
26-
var parentDir = path.resolve(path.join(absStart, '..'));
27-
if (fs.existsSync(absStart)) {
28-
var fullPath = path.resolve(path.join(startPath, relative));
29-
if (fs.existsSync(fullPath)) {
30-
31-
// file exists so get the dataURI
32-
var type = mime.lookup(fullPath);
33-
var contents = fs.readFileSync(fullPath);
34-
var base64 = new Buffer(contents).toString('base64');
35-
return 'url(data:' + type + ';base64,' + base64 + ')';
36-
37-
} else if (parentDir !== process.cwd()) { // will not jump across bower or npm packages
38-
39-
// find parent and child directories
40-
var childDirs = fs.readdirSync(absStart)
41-
.map(function toAbsolute(filename) {
42-
return path.join(absStart, filename);
43-
}).filter(function directoriesOnly(absolute) {
44-
return fs.statSync(absolute).isDirectory();
45-
});
20+
function encodeRelativeURL(startPath, uri) {
21+
'use strict';
4622

47-
// recurse paths down and up except the caller path
48-
// return the first success
49-
var result;
50-
childDirs.concat(parentDir)
51-
.filter(function excludeCallerDir(absoluteDir) {
52-
return (absoluteDir !== callerPath);
53-
})
54-
.some(function encode(absoluteDir) {
55-
result = encodeRelativeURL(absoluteDir, relative, absStart);
56-
return result;
57-
});
23+
/**
24+
* Test whether the given directory is the root of its own package
25+
* @param {string} absolutePath An absolute path
26+
* @returns {boolean} True where a package.json or bower.json exists, else False
27+
*/
28+
function notPackage(absolutePath) {
29+
return ['package.json', 'bower.json'].every(function fileNotFound(file) {
30+
return !(fs.existsSync(path.resolve(absolutePath, file)));
31+
});
32+
}
33+
34+
// ignore data uris and ensure we are at a valid start path
35+
var absoluteStart = !(/^data\:/.test(uri)) && path.resolve(startPath);
36+
if (absoluteStart) {
37+
38+
// find path to the root, stopping at cwd, package.json or bower.json
39+
var pathToRoot = [ ];
40+
do {
41+
pathToRoot.push(absoluteStart);
42+
var isWorking = (absoluteStart !== process.cwd()) && notPackage(absoluteStart);
43+
absoluteStart = path.resolve(absoluteStart, '..');
44+
} while (isWorking);
5845

59-
// may be undefined
60-
return result;
46+
// start a queue with the path to the root
47+
var queue = pathToRoot.concat();
48+
49+
// process the queue until empty
50+
// the queue pattern ensures that we favour paths closest the the start path
51+
while (queue.length) {
52+
53+
// shift the first item off the queue, consider it the base for our relative uri
54+
var basePath = queue.shift();
55+
var fullPath = path.resolve(basePath, uri);
56+
57+
// file exists so convert to a dataURI and end
58+
if (fs.existsSync(fullPath)) {
59+
var type = mime.lookup(fullPath);
60+
var contents = fs.readFileSync(fullPath);
61+
var base64 = new Buffer(contents).toString('base64');
62+
return 'url(data:' + type + ';base64,' + base64 + ')';
63+
}
64+
// enqueue subdirectories that are not packages and are not in the root path
65+
else {
66+
fs.readdirSync(basePath)
67+
.filter(function notHidden(filename) {
68+
return (filename.charAt(0) !== '.');
69+
})
70+
.map(function toAbsolute(filename) {
71+
return path.join(basePath, filename);
72+
})
73+
.filter(function directoriesOnly(absolutePath) {
74+
return fs.statSync(absolutePath).isDirectory();
75+
})
76+
.filter(function notInRootPath(absolutePath) {
77+
return (pathToRoot.indexOf(absolutePath) < 0);
78+
})
79+
.filter(notPackage)
80+
.forEach(function enqueue(absolutePath) {
81+
queue.push(absolutePath);
82+
});
83+
}
6184
}
6285
}
6386
}
@@ -124,10 +147,13 @@ module.exports = function (bannerWidth, libraryPaths) {
124147
line: cssStart.line,
125148
column: cssStart.column
126149
});
150+
if (!sassStart.source) {
151+
throw new Error('failed to decode node-sass source map'); // this can occur with regressions in libsass
152+
}
127153
var sassDir = path.dirname(sassStart.source);
128154

129155
// allow multiple url() values in the declaration
130-
// the url will be every second value (i % 2)
156+
// the uri will be every second value (i % 2)
131157
declaration.value = declaration.value
132158
.split(/url\s*\(\s*['"]?([^'"?#]*)[^)]*\)/g) // split by url statements
133159
.map(function (token, i) {
@@ -139,21 +165,20 @@ module.exports = function (bannerWidth, libraryPaths) {
139165

140166
/**
141167
* Handler for successful transpilation using node-sass.
168+
* This functions gets called with an object containing a CSS file and its source-map,
169+
* which is modified and passed through CSS rework, before being pushed to the results.
142170
* @param {string} css Compiled css
143171
* @param {string} map The source-map for the compiled css
144172
*/
145173
function successHandler(css, map) {
146174

147-
// adjust sourcemap
148-
var source = minimatch.makeRe(file.cwd).source
149-
.replace(/^\^|\$$/g, '') // match text anywhere on the line by removing line start/end
150-
.replace(/\\\//g, '[\\\\\\/]') + // detect any platform path format
151-
'|\\.\\.\\/'; // relative paths are an artifact and must be removed
152-
var parsable = slash(map.replace(new RegExp(source, 'g'), ''));
153-
var sourceMap = JSON.parse(parsable);
175+
// adjust source-map
176+
var sourceMap = convert.fromJSON(map).toObject();
154177
sourceMap.sources.forEach(function (value, i, array) {
155178
array[i] = path.resolve(value.replace(/^\//, '').replace(/\b\/+\b/g, '/')); // ensure single slash absolute
156179
});
180+
181+
// prepare the adjusted sass source-map for later look-ups
157182
sourceMapConsumer = new SourceMapConsumer(sourceMap);
158183

159184
// embed sourcemap in css
@@ -179,7 +204,7 @@ module.exports = function (bannerWidth, libraryPaths) {
179204

180205
// write stream output
181206
pushResult('.css', reworked.code + '\n/*# sourceMappingURL=' + mapName + ' */');
182-
pushResult('.css.map', JSON.stringify(reworked.map, null, ' '));
207+
pushResult('.css.map', JSON.stringify(reworked.map, null, 2));
183208
done();
184209
}
185210

@@ -208,19 +233,20 @@ module.exports = function (bannerWidth, libraryPaths) {
208233
}
209234

210235
// perform the sass render
211-
sass.render({
212-
file: file.path,
213-
data: file.contents.toString(),
214-
success: successHandler,
215-
error: errorHandler,
236+
sass.render({
237+
file : file.path,
238+
data : file.contents.toString(),
239+
success : successHandler,
240+
error : errorHandler,
216241
includePaths: libList,
217-
outputStyle: 'compressed',
218-
stats: { },
219-
sourceMap: mapName
242+
outputStyle : 'compressed',
243+
stats : { },
244+
sourceMap : mapName
220245
});
221246

222-
// display the output buffer with padding before and after and between each item
223247
}, function (done) {
248+
249+
// display the output buffer with padding before and after and between each item
224250
if (output.length) {
225251
var width = Number(bannerWidth) || 0;
226252
var hr = new Array(width + 1); // this is a good trick to repeat a character N times

lib/test/karma.js

Lines changed: 21 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ var karmaReporterMatchNameRegex = /^karma-(.+)-reporter$/ ;
4242
*/
4343
function getKarmaReporterPluginPath(reporterName) {
4444
if (typeof reporterName !== 'string') {
45-
throw 'Get Karma Reporter Plugin Path: Reporter name is unspecified';
45+
throw 'Reporter name is unspecified';
4646
}
4747

4848
//Default reporter is a dependency of angularity
@@ -61,8 +61,7 @@ function getKarmaReporterPluginPath(reporterName) {
6161
require(reporterPath);
6262
}
6363
catch (ex) {
64-
throw 'Get Karma Reporter Plugin Path: Attempt to require reporter from path ' +
65-
reporterPath + ' with no success.';
64+
throw 'Attempt to require reporter from path ' + reporterPath + ' with no success.';
6665
}
6766
reporterPath = path.normalize(reporterPath);
6867

@@ -128,8 +127,8 @@ function karmaCreateConfig(reporters, configFileName) {
128127
else {
129128
//non-javascript files, such as source maps, should be included but not tested
130129
files.push({
131-
pattern: file.path,
132-
included: false,
130+
pattern : file.path,
131+
included: false
133132
});
134133
}
135134
transformDone();
@@ -164,8 +163,8 @@ function karmaCreateConfig(reporters, configFileName) {
164163

165164
function specTransformFn(file, encoding, specFileDone) {
166165
files.push({
167-
pattern: file.path,
168-
included: false,
166+
pattern : file.path,
167+
included: false
169168
});
170169
specFileDone();
171170
}
@@ -219,8 +218,8 @@ function karmaRun(reporters, bannerWidth) {
219218
//NOTE this workaround is necessary, see issue:
220219
//https://github.com/sindresorhus/supports-color/issues/13
221220
//TODO @bguiz remove workaround when issue has been resolved
222-
SUPPORTS_COLOR: true,
223-
}),
221+
SUPPORTS_COLOR: true
222+
})
224223
});
225224
karmaBackground.on('close', function(exitCode) {
226225
done();
@@ -229,37 +228,37 @@ function karmaRun(reporters, bannerWidth) {
229228
});
230229
};
231230

232-
var yargsOptionDefiniton = {
233-
key: 'karmareporter',
231+
var yargsOptionDefinition = {
232+
key: 'karma-reporter',
234233
value: {
235-
describe: 'Specify a custom Karma reporter to use. ' +
236-
'Either a locally npm installed module, or an asolute path to one.',
237-
alias: ['k'],
238-
default: defaultReporterName,
239-
string:true,
234+
describe: 'Specify a custom Karma reporter to use. Either a locally npm installed module, or an asolute path to ' +
235+
'one.',
236+
alias : ['k'],
237+
default : defaultReporterName,
238+
string : true
240239
}
241240
};
242241
var checkKarmaReporter = yargs.createCheck()
243242
.withGate(function (argv) {
244243
return !argv.help;
245244
})
246245
.withTest({
247-
karmareporter: function(value) {
246+
'karma-reporter': function(value) {
248247
if (typeof value !== 'undefined') {
249248
try {
250249
getKarmaReporterPluginPath(value);
251250
}
252251
catch (ex) {
253-
return 'Illegal value for "reporter"\n' + ex;
252+
return 'Illegal value for "karma-reporter": ' + ex;
254253
}
255254
}
256-
},
255+
}
257256
})
258257
.commit();
259258

260259
module.exports = {
261260
createConfig: karmaCreateConfig,
262-
run: karmaRun,
263-
yargsCheck: checkKarmaReporter,
264-
yargsOption: yargsOptionDefiniton,
261+
run : karmaRun,
262+
yargsCheck : checkKarmaReporter,
263+
yargsOption : yargsOptionDefinition
265264
};

lib/util/jshint-reporter.js

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ function getJsHintReporter(reporterName) {
3232
// establish a cached copy
3333
if (!resolvedReporter) {
3434
if (typeof reporterName !== 'string') {
35-
throw 'Get JsHint Reporter: Reporter name is unspecified';
35+
throw 'Reporter name is unspecified';
3636
}
3737
else {
3838
var reporterPath;
@@ -58,7 +58,7 @@ function getJsHintReporter(reporterName) {
5858
}
5959
});
6060
if (!resolvedReporter) {
61-
throw 'Get JsHint Reporter: Attempt to require specified reporter with no success.';
61+
throw 'Attempt to require specified reporter with no success.';
6262
}
6363
}
6464
}
@@ -73,34 +73,34 @@ function getJsHintReporter(reporterName) {
7373
return gulpJshint.reporter(resolvedReporter);
7474
}
7575
else {
76-
throw 'Get JsHint Reporter: Given reporter is badly formed';
76+
throw 'Given reporter is badly formed';
7777
}
7878
}
7979

8080
var yargsOptionDefiniton = {
81-
key: 'reporter',
81+
key: 'jshint-reporter',
8282
value: {
8383
describe: 'Specify a custom JsHint reporter to use. Either a locally npm installed module, or the absolute path ' +
8484
'to one.',
85-
alias: ['r'],
86-
default: defaultReporterName,
87-
string: true
85+
alias : ['j'],
86+
default : defaultReporterName,
87+
string : true
8888
}
8989
};
9090
var checkJsHintReporter = yargs.createCheck()
9191
.withGate(function (argv) {
9292
return !argv.help;
9393
})
9494
.withTest({
95-
reporter: function(value) {
95+
'jshint-reporter': function(value) {
9696
if (typeof value === 'undefined') {
9797
return;
9898
}
9999
try {
100100
getJsHintReporter(value);
101101
}
102102
catch (ex) {
103-
return 'Illegal value for "reporter"\n' + ex;
103+
return 'Illegal value for "jshint-reporter": ' + ex;
104104
}
105105
}
106106
})

0 commit comments

Comments
 (0)