Socket
Socket
Sign inDemoInstall

trumpet

Package Overview
Dependencies
6
Maintainers
1
Versions
48
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.4.2 to 1.0.0

example/html/read_all.html

9

example/table.js
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);

@@ -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" }
}
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc