Comparing version 1.0.4 to 1.0.5
@@ -43,5 +43,2 @@ /* jshint node:true */ | ||
Cache.PREFIX_NET = 'net.'; | ||
Cache.PREFIX_PARSER = 'parser.'; | ||
module.exports = Cache; |
154
lib/esi.js
@@ -6,5 +6,3 @@ /* jshint node:true */ | ||
var parse5 = require('parse5'), | ||
getCacheTime = require('./get-cache-time'), | ||
var getCacheTime = require('./get-cache-time'), | ||
Cache = require('./cache'), | ||
@@ -22,8 +20,6 @@ DataProvider = require('./data-provider'), | ||
this.dataProvider = config.dataProvider || new DataProvider(config); | ||
this.parser = config.parser || new parse5.Parser(); | ||
this.serializer = config.serializer || new parse5.Serializer(); | ||
this.logger = new Logger(config); | ||
} | ||
ESI.prototype.processParsed = function(parsedHtml, options, state) { | ||
ESI.prototype.processHtmlText = function(html, options, state) { | ||
var self = this; | ||
@@ -37,22 +33,28 @@ options = options || {}; | ||
var subtasks = [], | ||
i = 0, | ||
maxDepthReached = state.currentDepth > self.maxDepth; | ||
self.walkTree(function (subtree) { | ||
self.findESITags(html, options).forEach(function(tag) { | ||
var placeholder = '<!-- esi-placeholder-' + i + ' -->'; | ||
if (maxDepthReached) { | ||
if (subtree.nodeName.indexOf('esi:') === 0) { | ||
subtasks.push(self.replaceWithBlank(subtree)); | ||
} | ||
} else if (subtree.nodeName === 'esi:include') { | ||
subtasks.push(self.include(subtree, options)); | ||
html = html.replace(tag, ''); | ||
} else if(tag.indexOf('<esi:include') > -1) { | ||
html = html.replace(tag, placeholder); | ||
subtasks[i] = self.getIncludeContents(tag, options).then(function(result) { | ||
html = html.replace(placeholder, result); | ||
return true; | ||
}); | ||
i++; | ||
} | ||
}, parsedHtml); | ||
}); | ||
Promise.all(subtasks).then(function () { | ||
if (self.hasIncludeTag(parsedHtml)) { | ||
if (self.hasESITag(html)) { | ||
state.currentDepth++; | ||
self.processParsed(parsedHtml, options, state).then(function (result) { | ||
self.processHtmlText(html, options, state).then(function (result) { | ||
resolve(result); | ||
}); | ||
} else { | ||
resolve(parsedHtml); | ||
resolve(html); | ||
} | ||
@@ -66,69 +68,45 @@ }); | ||
return self.getParsedHtml(html) | ||
.then(function(parsedHtml) { | ||
return self.processParsed(parsedHtml, options); | ||
}) | ||
.then(function(result) { | ||
return self.serializer.serialize(result); | ||
}); | ||
return self.processHtmlText(html, options); | ||
}; | ||
ESI.prototype.getParsedHtml = function(html) { | ||
var self = this, | ||
cacheKey = Cache.PREFIX_PARSER + html; | ||
return new Promise(function(resolve, reject) { | ||
self.cache.get(cacheKey) | ||
.then(function(cached) { | ||
resolve(cached.value); | ||
}) | ||
.catch(function() { | ||
var parsedHtml = self.parser.parseFragment(html); | ||
self.cache.set(cacheKey, { | ||
value: parsedHtml | ||
}); | ||
resolve(parsedHtml); | ||
}); | ||
}); | ||
ESI.prototype.hasESITag = function(html) { | ||
return html.indexOf('<esi:') > -1; | ||
}; | ||
ESI.prototype.walkTree = function (callback, tree) { | ||
var self = this; | ||
callback(tree); | ||
if (tree.childNodes && tree.childNodes.length > 0) { | ||
tree.childNodes.forEach(self.walkTree.bind(self, callback)); | ||
} | ||
}; | ||
ESI.prototype.findESITags = function(html) { | ||
var OPEN = '<esi:', | ||
CLOSE = '</esi:include>', | ||
tags = [], | ||
nextTagOpen, | ||
nextTagClose, | ||
reducedHtml = html; | ||
ESI.prototype.hasIncludeTag = function (parsedHtml) { | ||
var includeTagPresent = false; | ||
this.walkTree(function (subtree) { | ||
if (subtree.nodeName === 'esi:include') { | ||
includeTagPresent = true; | ||
do { | ||
nextTagOpen = reducedHtml.indexOf(OPEN); | ||
if(nextTagOpen > -1) { | ||
reducedHtml = reducedHtml.substr(nextTagOpen); | ||
nextTagClose = reducedHtml.indexOf(CLOSE); | ||
tags.push(reducedHtml.substr(0, nextTagClose + CLOSE.length)); | ||
reducedHtml = reducedHtml.substr(nextTagClose + CLOSE.length); | ||
} | ||
}, parsedHtml); | ||
} while(nextTagOpen > -1); | ||
return includeTagPresent; | ||
return tags; | ||
}; | ||
ESI.prototype.include = function (node, options) { | ||
ESI.prototype.getIncludeContents = function (tag, options) { | ||
var self = this, | ||
src = self.getIncludeSrc(node); | ||
src = self.getIncludeSrc(tag); | ||
return new Promise(function (resolve, reject) { | ||
self.get(src, options).then(function (html) { | ||
var parsedHtml = self.parser.parseFragment(html); | ||
self.replace(node, parsedHtml); | ||
resolve(); | ||
}); | ||
}); | ||
return self.get(src, options); | ||
}; | ||
ESI.prototype.getIncludeSrc = function (node) { | ||
return node.attrs.filter(function (attr) { | ||
return attr.name === 'src'; | ||
})[0].value; | ||
ESI.prototype.getIncludeSrc = function(tag) { | ||
var OPEN = 'src="', | ||
CLOSE = '"', | ||
srcOpen = tag.indexOf(OPEN), | ||
tagFragment = tag.substr(srcOpen + OPEN.length), | ||
srcClose = tagFragment.indexOf(CLOSE); | ||
return tagFragment.substr(0, srcClose); | ||
}; | ||
@@ -139,6 +117,5 @@ | ||
src = self.dataProvider.toFullyQualifiedURL(src); | ||
var cacheKey = Cache.PREFIX_NET + src; | ||
return new Promise(function (resolve, reject) { | ||
self.cache.get(cacheKey) | ||
self.cache.get(src) | ||
// in cache | ||
@@ -149,3 +126,3 @@ .then(function (result) { | ||
.then(function (result) { | ||
self.setCacheResult(cacheKey, result); | ||
self.setCacheResult(src, result); | ||
}); | ||
@@ -159,3 +136,3 @@ } | ||
.then(function (result) { | ||
self.setCacheResult(cacheKey, result); | ||
self.setCacheResult(src, result); | ||
resolve(result.body); | ||
@@ -186,31 +163,2 @@ }) | ||
ESI.prototype.replace = function (original, replacement) { | ||
var childNodes = original.parentNode.childNodes; | ||
childNodes.forEach(function (childNode, i) { | ||
if (childNode === original) { | ||
// replace nodes | ||
childNodes.splice.apply(childNodes, [i, 1].concat(replacement.childNodes)); | ||
// update parent | ||
replacement.childNodes.forEach(function(replacementChild) { | ||
replacementChild.parentNode = original.parentNode; | ||
}); | ||
} | ||
}); | ||
}; | ||
ESI.prototype.replaceWithBlank = function(original) { | ||
var childNodes = original.parentNode.childNodes; | ||
childNodes.forEach(function (childNode, i) { | ||
if (childNode === original) { | ||
// remove node | ||
childNodes.splice(i, 1); | ||
} | ||
}); | ||
}; | ||
module.exports = ESI; |
{ | ||
"name": "nodesi", | ||
"version": "1.0.4", | ||
"version": "1.0.5", | ||
"description": "ESI: the good parts in node.js", | ||
@@ -14,5 +14,3 @@ "main": "esi.js", | ||
"dependencies": { | ||
"clone": "^1.0.1", | ||
"node.extend": "^1.1.3", | ||
"parse5": "1.4.1", | ||
"clone": "1.0.1", | ||
"request": "2.53.0" | ||
@@ -19,0 +17,0 @@ }, |
19
perf.js
@@ -11,2 +11,3 @@ /* jshint node:true, camelcase:false */ | ||
cp = require('child_process'), | ||
fs = require('fs'), | ||
express = require('express'), | ||
@@ -21,2 +22,7 @@ | ||
perfESI = fs.readFileSync('./perf/esi.html').toString(), | ||
perfReplacement1 = fs.readFileSync('./perf/replacement1.html').toString(), | ||
perfReplacement2 = fs.readFileSync('./perf/replacement2.html').toString(), | ||
perfReplacement3 = fs.readFileSync('./perf/replacement3.html').toString(), | ||
spawn = function(proc, args, options) { | ||
@@ -37,13 +43,20 @@ if(process.platform === 'win32') { | ||
// routes | ||
app.get('/test', function(req, res) { | ||
esi.process('<section><esi:include src="/test2"></esi:include></section>').then(res.send.bind(res)); | ||
esi.process(perfESI).then(res.send.bind(res)); | ||
}); | ||
app.get('/test1', function(req, res) { | ||
res.send(perfReplacement1); | ||
}); | ||
app.get('/test2', function(req, res) { | ||
res.send('<div>hello</div>'); | ||
res.send(perfReplacement2); | ||
}); | ||
app.get('/test3', function(req, res) { | ||
res.send(perfReplacement3); | ||
}); | ||
// bootstrap | ||
@@ -50,0 +63,0 @@ app.listen(PORT, function() { |
@@ -11,5 +11,2 @@ /* jshint node:true */ | ||
Clock = require('./clock'), | ||
parse5 = require('parse5'), | ||
parser = new parse5.Parser(), | ||
serializer = new parse5.Serializer(), | ||
@@ -276,3 +273,3 @@ ESI = require('../lib/esi'), | ||
processed.then(function (response) { | ||
return esi.cache.get(Cache.PREFIX_NET + 'http://localhost:' + port + '/cacheme'); | ||
return esi.cache.get('http://localhost:' + port + '/cacheme'); | ||
}).then(function (cached) { | ||
@@ -285,30 +282,2 @@ assert.equal(cached.value, 'hello'); | ||
it('should populate internal cache with parsed html', function (done) { | ||
// given | ||
server.addListener('request', function (req, res) { | ||
res.writeHead(200, {'Content-Type': 'text/html'}); | ||
res.end('hello'); | ||
}); | ||
var html = '<esi:include src="/cacheme"></esi:include>'; | ||
// when | ||
var esi = new ESI({ | ||
baseUrl: 'http://localhost:' + port | ||
}); | ||
var processed = esi.process(html); | ||
// then | ||
processed.then(function (response) { | ||
return esi.cache.get(Cache.PREFIX_PARSER + html); | ||
}).then(function (cached) { | ||
assert.equal(cached.value.childNodes[0].nodeName, 'esi:include'); | ||
assert.equal(cached.value.childNodes[0].nodeName, parser.parseFragment(html).childNodes[0].nodeName); | ||
done(); | ||
}).catch(done); | ||
}); | ||
it('should return data from the cache', function (done) { | ||
@@ -321,3 +290,3 @@ | ||
var html = '<esi:include src="/cacheme"></esi:include>'; | ||
cache.set(Cache.PREFIX_NET + 'http://example.com/cacheme', { | ||
cache.set('http://example.com/cacheme', { | ||
value: 'stuff' | ||
@@ -417,3 +386,3 @@ }); | ||
var html = '<esi:include src="/cacheme"></esi:include>'; | ||
cache.set(Cache.PREFIX_NET + 'http://example.com/cacheme', { | ||
cache.set('http://example.com/cacheme', { | ||
value: 'stuff', | ||
@@ -420,0 +389,0 @@ expiresIn: 1 |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
957873
2
20
879
5
+ Addedclone@1.0.1(transitive)
- Removednode.extend@^1.1.3
- Removedparse5@1.4.1
- Removedclone@1.0.4(transitive)
- Removedhas@1.0.4(transitive)
- Removedis@3.3.0(transitive)
- Removednode.extend@1.1.8(transitive)
- Removedparse5@1.4.1(transitive)
Updatedclone@1.0.1