trumpet
Advanced tools
Comparing version 0.4.2 to 1.0.0
var trumpet = require('../'); | ||
var tr = trumpet(); | ||
tr.pipe(process.stdout); | ||
tr.update('tbody', function (html, node) { | ||
return '<tr><td>rawr</td></tr>'; | ||
}); | ||
var ws = tr.select('tbody').createWriteStream(); | ||
ws.end('<tr><td>rawr</td></tr>'); | ||
var fs = require('fs'); | ||
tr.pipe(process.stdout, { end : false }); | ||
fs.createReadStream(__dirname + '/table.html').pipe(tr); | ||
fs.createReadStream(__dirname + '/html/table.html').pipe(tr); |
323
index.js
@@ -1,129 +0,234 @@ | ||
var sax = require('sax'); | ||
var select = require('./lib/select'); | ||
var through = require('through'); | ||
var tokenize = require('./lib/tokenize.js'); | ||
var parseSelector = require('./lib/selector.js'); | ||
var matcher = require('./lib/matcher.js'); | ||
var ent = require('ent'); | ||
var EventEmitter = require('events').EventEmitter; | ||
var inherits = require('inherits'); | ||
var duplexer = require('duplexer'); | ||
module.exports = function (opts) { | ||
if (!opts) opts = {}; | ||
if (!opts.special) { | ||
opts.special = [ | ||
'area', 'base', 'basefont', 'br', 'col', | ||
'hr', 'input', 'img', 'link', 'meta' | ||
]; | ||
} | ||
opts.special = opts.special.map(function (x) { return x.toUpperCase() }); | ||
var selectors = []; | ||
var tokens = tokenize(); | ||
var tokenBuffer = null; | ||
var skipping = false; | ||
var parser = sax.parser(false); | ||
var stream = select(parser, opts, write, end); | ||
tokens.pipe(through(write, end)); | ||
function write (buf) { | ||
var s = buf.toString(); | ||
buffered += s; | ||
parser.write(buf.toString()); | ||
} | ||
var tr = through( | ||
function (buf) { tokens.write(buf) }, | ||
function () { tokens.end() } | ||
); | ||
function end () { | ||
if (pos < parser.position) { | ||
var s = buffered.slice(0, parser.position - pos); | ||
stream.raw(s); | ||
} | ||
stream.queue(null); | ||
} | ||
parser.onerror = function (err) { | ||
stream.emit("error", err) | ||
} | ||
var buffered = ''; | ||
var pos = 0; | ||
var inScript = false; | ||
var scriptLen = 0; | ||
var scriptStart = 0; | ||
var update = function (type, tag) { | ||
var len, src; | ||
if (type === 'script') { | ||
src = tag; | ||
len = tag.length; | ||
scriptLen += len; | ||
inScript = true; | ||
} | ||
else if (type === 'text') { | ||
len = parser.textNode.length; | ||
} | ||
else if (type === 'open' && tag && tag.name === 'SCRIPT' | ||
&& tag.attributes.src) { | ||
len = 0; | ||
} | ||
else if (inScript) { | ||
len = parser.position - scriptLen - parser.startTagPosition + 1; | ||
scriptLen = 0; | ||
inScript = false; | ||
} | ||
else if (type === 'special') { | ||
len = 0; | ||
} | ||
else if (type === 'doctype') { | ||
len = tag.length + 10; | ||
} | ||
else { | ||
len = parser.position - (parser.startTagPosition || 0) + 1; | ||
} | ||
tr.select = function (sel) { | ||
var r = new Result(sel); | ||
r._matcher.once('unmatch', function () { | ||
if (!r._reading && !r._writing) { | ||
var ix = selectors.indexOf(r); | ||
if (ix >= 0) selectors.splice(ix, 1); | ||
} | ||
}); | ||
r.once('read-close', function () { | ||
var ix = selectors.indexOf(r); | ||
if (ix >= 0) selectors.splice(ix, 1); | ||
}); | ||
if (type === 'open' && tag && tag.name === 'SCRIPT') { | ||
scriptLen = len; | ||
} | ||
r.on('_write-begin', function (stream) { | ||
if (stream._skipping !== false) { | ||
tokens.pause(); | ||
} | ||
skipping = true; | ||
stream.pipe(through(write, end)); | ||
stream.resume(); | ||
function write (buf) { | ||
if (Buffer.isBuffer(buf)) { | ||
tr.queue(buf) | ||
} | ||
else if (typeof buf === 'string') { | ||
tr.queue(Buffer(buf)); | ||
} | ||
else { | ||
tr.queue(Buffer(String(buf))); | ||
} | ||
} | ||
function end () { | ||
if (stream._skipping !== false) { | ||
tokens.resume(); | ||
} | ||
} | ||
}); | ||
pos = parser.position; | ||
r.on('_write-end', function () { | ||
skipping = false; | ||
}); | ||
src = src || buffered.slice(0, len); | ||
buffered = buffered.slice(len); | ||
stream.raw(src); | ||
return src; | ||
selectors.push(r); | ||
return r; | ||
}; | ||
var lastOpen; | ||
parser.onopentag = function (tag) { | ||
lastOpen = tag.name; | ||
tr.selectAll = function (sel, cb) { | ||
var r = new Result(sel); | ||
if (cb) r.on('element', cb); | ||
stream.pre('open', tag); | ||
update('open', tag); | ||
stream.post('open', tag); | ||
if (opts.special.indexOf(tag.name) >= 0) { | ||
stream.pre('close', tag.name); | ||
update('special'); | ||
stream.post('close', tag.name); | ||
} | ||
r._matcher.on('open', function (node) { | ||
node.getAttribute = function (name, cb) { | ||
r.getAttribute(name, function (value) { | ||
delete r._getAttr[name.toUpperCase()]; | ||
cb.call(this, value); | ||
}); | ||
}; | ||
node.setAttribute = function (name, value) { | ||
r.setAttribute(name, value); | ||
r._matcher.on('attribute', function (node) { | ||
if (node.name === name.toUpperCase()) { | ||
delete r._setAttr[name.toUpperCase()]; | ||
} | ||
}); | ||
}; | ||
node.createStream = RP.createStream.bind(r); | ||
node.createReadStream = RP.createReadStream.bind(r); | ||
node.createWriteStream = RP.createWriteStream.bind(r); | ||
r.emit('element', node); | ||
}); | ||
var RP = Result.prototype; | ||
r.createStream = undefined; | ||
r.createReadStream = undefined; | ||
r.createWriteStream = undefined; | ||
selectors.push(r); | ||
return r; | ||
}; | ||
parser.oncomment = function(comment) { | ||
src = buffered.slice(0, comment.length + 7) | ||
buffered = buffered.slice(comment.length + 7) | ||
stream.raw(src) | ||
}; | ||
return tr; | ||
parser.onclosetag = function (name) { | ||
stream.pre('close', name); | ||
update('close'); | ||
stream.post('close', name); | ||
}; | ||
function write (lex) { | ||
var sub; | ||
selectors.forEach(function (s) { | ||
s._at(lex); | ||
if (s._substitute !== undefined) { | ||
sub = s._substitute; | ||
s._substitute = undefined; | ||
} | ||
}); | ||
if (skipping) return; | ||
if (sub !== undefined) tr.queue(sub) | ||
else tr.queue(lex[1]) | ||
} | ||
parser.ontext = function (text) { | ||
stream.pre('text', text); | ||
update('text'); | ||
stream.post('text', text); | ||
}; | ||
function end () { | ||
tr.queue(null); | ||
} | ||
}; | ||
inherits(Result, EventEmitter); | ||
function Result (sel) { | ||
var self = this; | ||
self._setAttr = {}; | ||
self._getAttr = {}; | ||
self._readStreams = []; | ||
self._writeStream = null; | ||
parser.onscript = function (src) { | ||
stream.pre('script', src); | ||
update('script', src); | ||
stream.post('script', src); | ||
}; | ||
self._reading = false; | ||
self._writing = false; | ||
self._matcher = matcher(parseSelector(sel)); | ||
parser.ondoctype = function (t) { | ||
stream.pre('doctype', t); | ||
update('doctype', t); | ||
stream.post('doctype', t); | ||
}; | ||
self._matcher.on('tag-end', function (m) { | ||
if (self._readStreams.length) { | ||
self._reading = true; | ||
self._readMatcher = m; | ||
self._readLevel = m.stack.length; | ||
for (var i = 0; i < self._readStreams.length; i++) { | ||
if (self._readStreams[i]._level === undefined) { | ||
self._readStreams[i]._level = self._readLevel; | ||
} | ||
} | ||
} | ||
if (self._writeStream) { | ||
self._writing = true; | ||
self._writeLevel = m.stack.length; | ||
self.emit('_write-begin', self._writeStream); | ||
} | ||
}); | ||
self._matcher.on('attribute', function (node) { | ||
var f = self._getAttr[node.name]; | ||
if (f) f(node.value); | ||
var v = self._setAttr[node.name]; | ||
if (v !== undefined) self._substitute = v; | ||
}); | ||
} | ||
Result.prototype._at = function (lex) { | ||
if (this._reading) { | ||
if (lex[0] === 'closetag') { | ||
var level = this._matcher.matchers[0].stack.length; | ||
var removed = 0; | ||
for (var i = this._readStreams.length - 1; i >= 0; i--) { | ||
var s = this._readStreams[i]; | ||
if (s._level === level) { | ||
s.queue(null); | ||
removed ++; | ||
this._readStreams.splice(i, 1); | ||
} | ||
} | ||
if (this._readStreams.length === 0) { | ||
this._reading = false; | ||
} | ||
if (removed > 0) this.emit('read-close'); | ||
} | ||
for (var i = 0; i < this._readStreams.length; i++) { | ||
var s = this._readStreams[i]; | ||
if (s._level !== undefined) s.queue(lex[1]); | ||
} | ||
} | ||
if (this._writing) { | ||
if (lex[0] === 'closetag') { | ||
var level = this._matcher.matchers[0].stack.length; | ||
if (level === this._writeLevel) { | ||
this._writing = false; | ||
this.emit('_write-end'); | ||
} | ||
} | ||
} | ||
this._matcher.at(lex[0], lex[2]); | ||
}; | ||
Result.prototype.setAttribute = function (key, value) { | ||
var sub = Buffer(ent.encode(key) + '="' + ent.encode(value) + '"'); | ||
this._setAttr[key.toUpperCase()] = sub; | ||
return this; | ||
}; | ||
Result.prototype.getAttribute = function (key, cb) { | ||
this._getAttr[key.toUpperCase()] = cb; | ||
}; | ||
Result.prototype.createWriteStream = function () { | ||
// doesn't work with selectAll() | ||
var stream = through().pause(); | ||
this._writeStream = stream; | ||
return stream; | ||
}; | ||
Result.prototype.createReadStream = function () { | ||
// doesn't work with selectAll() | ||
var stream = through(); | ||
this._readStreams.push(stream); | ||
return stream; | ||
}; | ||
Result.prototype.createStream = function () { | ||
var ws = Result.prototype.createWriteStream.call(this); | ||
ws._skipping = false; | ||
var rs = Result.prototype.createReadStream.call(this); | ||
return duplexer(ws, rs); | ||
}; |
{ | ||
"name" : "trumpet", | ||
"version" : "0.4.2", | ||
"version" : "1.0.0", | ||
"description" : "parse and transform streaming html using css selectors", | ||
"main" : "index.js", | ||
"directories" : { | ||
"lib" : ".", | ||
"example" : "example", | ||
"test" : "test" | ||
}, | ||
"dependencies" : { | ||
"sax" : "~0.3.5", | ||
"ent" : "~0.0.4", | ||
"through": "~2.3.4" | ||
"sax" : "~0.5.4", | ||
"ent" : "~0.0.5", | ||
"through": "~2.3.4", | ||
"duplexer": "~0.1.1", | ||
"buffers": "~0.1.1", | ||
"inherits": "~2.0.0" | ||
}, | ||
"devDependencies" : { | ||
"tap" : "~0.4.0" | ||
"tap" : "~0.4.0", | ||
"tape" : "~1.0.4", | ||
"concat-stream" : "~1.0.0" | ||
}, | ||
@@ -39,4 +39,4 @@ "scripts" : { | ||
}, | ||
"license" : "MIT/X11", | ||
"license" : "MIT", | ||
"engine" : { "node" : ">=0.4" } | ||
} |
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
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
983
1
17
38761
6
3
42
154
1
+ Addedbuffers@~0.1.1
+ Addedduplexer@~0.1.1
+ Addedinherits@~2.0.0
+ Addedbuffers@0.1.1(transitive)
+ Addedduplexer@0.1.2(transitive)
+ Addedinherits@2.0.4(transitive)
+ Addedsax@0.5.8(transitive)
- Removedsax@0.3.5(transitive)
Updatedent@~0.0.5
Updatedsax@~0.5.4