combohandler
Advanced tools
Comparing version 0.2.0 to 0.2.1
Combo Handler History | ||
===================== | ||
0.2.0 | ||
----- | ||
0.2.1 (2013-04-01) | ||
------------------ | ||
* Added a `basePath` config option that can be used to specify a | ||
non-combohandled base path. Relative URLs in combohandled CSS files will | ||
be automatically rewritten to be relative to this base path rather than the | ||
combo URL. [Ryan Cannon] | ||
0.2.0 (2012-11-03) | ||
------------------ | ||
* Supports Express 3.0. | ||
@@ -8,0 +17,0 @@ |
var fs = require('fs'), | ||
path = require('path'), | ||
util = require('util'), | ||
URI = require("URIjs"), | ||
@@ -20,2 +21,3 @@ // Default set of MIME types supported by the combo handler. Attempts to | ||
mimeTypes = config.mimeTypes || MIME_TYPES, | ||
basePath = config.basePath || "", | ||
@@ -30,2 +32,6 @@ // Intentionally using the sync method because this only runs when the | ||
} | ||
if ((/[^\/]$/).test(basePath)) { | ||
basePath += "/"; | ||
} | ||
@@ -39,2 +45,3 @@ return function (req, res, next) { | ||
type = fileTypes.length === 1 && mimeTypes[fileTypes[0]], | ||
rewrite = basePath && ("text/css" === type), | ||
lastModified; | ||
@@ -109,3 +116,3 @@ | ||
body[i] = data; | ||
body[i] = rewrite ? rewriteCSSURLs(basePath, relativePath, data) : data; | ||
pending -= 1; | ||
@@ -186,1 +193,28 @@ | ||
} | ||
function rewriteCSSURLs(base, path, data) { | ||
return data.replace(/[\s:]url\(\s*(['"]?)(\S+)\1\s*\)/g, function (substr, quote, match) { | ||
var root, | ||
dest; | ||
// There is a ton of complexity related to URL parsing related | ||
// to unicode, escapement, etc. Rather than try to capture that, | ||
// this just does a simple sniff to validate whether the URL | ||
// needs to be rewritten. | ||
if (!URI(match).is("relative")) { | ||
return substr; | ||
} | ||
// the current directory | ||
root = (base + path).split("/"), | ||
// the place to which we're traversing | ||
dest = match.split("/"); | ||
// pull off the file name | ||
root.pop(); | ||
// while the destination contains "../", knock that off and | ||
// knock off the last directory of root | ||
while (dest.length > 1 && ".." === dest[0]) { | ||
root.pop(); | ||
dest.shift(); | ||
} | ||
return substr.replace(match, root.concat(dest).join("/")); | ||
}); | ||
} |
{ | ||
"name" : "combohandler", | ||
"description": "Simple Yahoo!-style combo handler.", | ||
"version" : "0.2.0", | ||
"version" : "0.2.1", | ||
"keywords" : [ | ||
@@ -27,3 +27,4 @@ "combo", "combohandler", "combohandle", "combine", "cdn", "css", "yui" | ||
"dependencies": { | ||
"express": "3.0.0" | ||
"express": "3.1.1", | ||
"URIjs" : "1.10.0" | ||
}, | ||
@@ -30,0 +31,0 @@ |
@@ -168,2 +168,27 @@ Combo Handler | ||
### Rewriting URLs in CSS files | ||
Because the combo handler changes the path from which CSS files are loaded, | ||
relative URLs in CSS files need to be updated to be relative to the | ||
combohandled path. Set the `basePath` configuration option to have the combo | ||
handler do this automatically. | ||
```js | ||
// This static route can be used to load images and other assets that shouldn't | ||
// be combined. | ||
// | ||
app.use('/public', express.static(__dirname + '/public')); | ||
// This route will combine requests for files in the public directory, and will | ||
// also automatically rewrite relative paths in CSS files to point to the | ||
// non-combohandled static route defined above. | ||
// | ||
app.get('/combo', combohandler.combine({ | ||
rootPath: __dirname + '/public', | ||
basePath: '/public' | ||
}), function (req, res) { | ||
res.send(res.body); | ||
}); | ||
``` | ||
Using as a YUI 3 combo handler | ||
@@ -170,0 +195,0 @@ ------------------------------ |
@@ -20,5 +20,18 @@ var combo = require('../'), | ||
'/css': __dirname + '/fixtures/root/css', | ||
'/js' : __dirname + '/fixtures/root/js' | ||
'/js' : __dirname + '/fixtures/root/js', | ||
'/norewrite': __dirname + '/fixtures/rewrite' | ||
} | ||
}); | ||
app.get('/rewrite', combo.combine({ | ||
rootPath: __dirname + '/fixtures/rewrite', | ||
basePath: "/rewritten" | ||
}), function (req, res) { | ||
res.send(res.body); | ||
}); | ||
app.get('/rewrite-noslash', combo.combine({ | ||
rootPath: __dirname + '/fixtures/rewrite', | ||
basePath: "/rewritten/" | ||
}), function (req, res) { | ||
res.send(res.body); | ||
}); | ||
@@ -215,2 +228,60 @@ httpServer = app.listen(PORT); | ||
}); | ||
// -- URL Rewrites --------------------------------------------------------- | ||
describe("url rewrites", function () { | ||
it ("should allow the basePath to end in a slash", function (done) { | ||
request(BASE_URL + "/rewrite-noslash?urls.css", function (err, res, body) { | ||
assert.equal(err, null); | ||
body.should.equal([ | ||
"#no-quotes { background: url(/rewritten/no-quotes.png);}", | ||
"#single-quotes { background: url(\'/rewritten/single-quotes.png\');}", | ||
"#double-quotes { background: url(\"/rewritten/double-quotes.png\");}", | ||
"#spaces { background: url(", | ||
" \"/rewritten/spaces.png\" );}", | ||
"#data-url { background: url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==);}", | ||
"#absolute-url { background: url(http://www.example.com/foo.gif?a=b&c=d#bebimbop);}", | ||
"#protocol-relative-url { background: url(//www.example.com/foo.gif?a=b&c=d#bebimbop);}", | ||
"#escaped-stuff { background:url(\"/rewritten/\\)\\\";\\'\\(.png\"); }", | ||
].join("\n")); | ||
done(); | ||
}); | ||
}); | ||
it ("should not rewrite without a basePath", function (done) { | ||
request(BASE_URL + "/norewrite?urls.css", function (err, res, body) { | ||
assert.equal(err, null); | ||
body.should.equal([ | ||
"#no-quotes { background: url(no-quotes.png);}", | ||
"#single-quotes { background: url(\'single-quotes.png\');}", | ||
"#double-quotes { background: url(\"double-quotes.png\");}", | ||
"#spaces { background: url(", | ||
" \"spaces.png\" );}", | ||
"#data-url { background: url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==);}", | ||
"#absolute-url { background: url(http://www.example.com/foo.gif?a=b&c=d#bebimbop);}", | ||
"#protocol-relative-url { background: url(//www.example.com/foo.gif?a=b&c=d#bebimbop);}", | ||
"#escaped-stuff { background:url(\"\\)\\\";\\'\\(.png\"); }" | ||
].join("\n")); | ||
done(); | ||
}); | ||
}); | ||
it ("should rewrite valid urls", function (done) { | ||
request(BASE_URL + "/rewrite?urls.css&deeper/more.css", function (err, res, body) { | ||
assert.equal(err, null); | ||
body.should.equal([ | ||
"#no-quotes { background: url(/rewritten/no-quotes.png);}", | ||
"#single-quotes { background: url(\'/rewritten/single-quotes.png\');}", | ||
"#double-quotes { background: url(\"/rewritten/double-quotes.png\");}", | ||
"#spaces { background: url(", | ||
" \"/rewritten/spaces.png\" );}", | ||
"#data-url { background: url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==);}", | ||
"#absolute-url { background: url(http://www.example.com/foo.gif?a=b&c=d#bebimbop);}", | ||
"#protocol-relative-url { background: url(//www.example.com/foo.gif?a=b&c=d#bebimbop);}", | ||
"#escaped-stuff { background:url(\"/rewritten/\\)\\\";\\'\\(.png\"); }", | ||
"#depth { background: url(/rewritten/deeper/deeper.png);}", | ||
"#up-one { background: url(/rewritten/shallower.png);}", | ||
"#down-one { background: url(/rewritten/deeper/more/down-one.png);}" | ||
].join("\n")); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
}); |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
33201
19
517
234
0
2
+ AddedURIjs@1.10.0
+ AddedURIjs@1.10.0(transitive)
+ Addedbuffer-crc32@0.1.10.2.13(transitive)
+ Addedbytes@0.2.0(transitive)
+ Addedconnect@2.7.4(transitive)
+ Addedcookie@0.0.5(transitive)
+ Addedcookie-signature@0.0.1(transitive)
+ Addedexpress@3.1.1(transitive)
+ Addedmkdirp@0.3.5(transitive)
- Removedbytes@0.1.0(transitive)
- Removedconnect@2.6.0(transitive)
- Removedcookie@0.0.4(transitive)
- Removedcrc@0.2.0(transitive)
- Removedexpress@3.0.0(transitive)
- Removedmkdirp@0.3.3(transitive)
- Removedsend@0.0.4(transitive)
Updatedexpress@3.1.1