Socket
Socket
Sign inDemoInstall

trumpet

Package Overview
Dependencies
18
Maintainers
1
Versions
48
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 1.6.3 to 1.6.4

example/delay.js

3

example/uppercase.js

@@ -8,8 +8,5 @@ var trumpet = require('../');

var stream = span.createStream();
stream.end('PLACEHOLDER');
/*
stream.pipe(through(function (buf) {
this.queue(buf.toString().toUpperCase());
})).pipe(stream);
*/
});

@@ -16,0 +13,0 @@

@@ -1,320 +0,183 @@

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 Duplex = require('readable-stream').Duplex;
var inherits = require('inherits');
var duplexer = require('duplexer');
var through = require('through2');
var duplexer = require('duplexer2');
module.exports = function (opts) {
var selectors = [];
var tokens = tokenize();
var tokenBuffer = null;
var skipping = false;
var skipSpace = false;
var lastToken = null;
var tokenize = require('html-tokenize');
var select = require('html-select');
var wrapElem = require('./lib/wrap.js');
module.exports = Trumpet;
inherits(Trumpet, Duplex);
function Trumpet () {
var self = this;
if (!(this instanceof Trumpet)) return new Trumpet;
Duplex.call(this);
this._tokenize = tokenize();
this._writing = false;
this._piping = false;
this._select = this._tokenize.pipe(select());
this._select.once('end', function () {
self.emit('_end');
self.push(null)
});
this.once('finish', function () { self._tokenize.end() });
}
Trumpet.prototype.pipe = function () {
this._piping = true;
return Duplex.prototype.pipe.apply(this, arguments);
};
Trumpet.prototype._read = function (n) {
var self = this;
var buf, read = 0;
var s = this._select;
while ((row = s.read()) !== null) {
if (row[1].length) {
this.push(row[1]);
read ++;
}
}
if (read === 0) s.once('readable', function () { self._read(n) });
};
Trumpet.prototype._write = function (buf, enc, next) {
if (!this._writing && !this._piping) {
this._piping = true;
this.resume();
}
return this._tokenize._write(buf, enc, next);
};
Trumpet.prototype.select = function (str, cb) {
var self = this;
var first = true;
tokens.pipe(through(write, end));
var res = self._selectAll(str, function (elem) {
if (!first) return;
first = false;
res.createReadStream = function () {};
res.createWriteStream = function () {};
res.createStream = function () {};
if (cb) cb(elem);
});
return res;
};
Trumpet.prototype.selectAll = function (str, cb) {
return this._selectAll(str, cb);
};
Trumpet.prototype._selectAll = function (str, cb) {
var self = this;
var readers = [], writers = [], duplex = [];
var gets = [], getss = [], sets = [], removes = [];
var tr = through(
function (buf) { tokens.write(buf) },
function () { tokens.end() }
);
tr.select = function (sel) {
var r = createResult(sel, { all: false });
return r;
};
tr.selectAll = function (sel, cb) {
var r = createResult(sel, { all: true });
r._matcher.on('pre-open', function (m) {
r.name = m.current.name;
r.attributes = m.current.attributes;
r.isSelfClosing = m.current.isSelfClosing;
cb(r);
this.once('_end', function () {
readers.splice(0).forEach(function (r) {
r.end();
r.resume();
});
r._matcher.on('tag-end', function (node) {
r._getAttr = {};
r._setAttr = {};
r._rmAttr = {};
duplex.splice(0).forEach(function (d) {
d.end();
d.resume();
});
};
tr.createReadStream = function (sel, opts) {
return tr.select(sel).createReadStream(opts);
};
tr.createWriteStream = function (sel, opts) {
return tr.select(sel).createWriteStream(opts);
};
tr.createStream = function (sel, opts) {
return tr.select(sel).createStream(opts);
};
// End any read streams of unmatched selectors
tr.on("end", function() {
selectors.forEach(function(r) {
r._readStreams.forEach(function(s) {
if (s.readable) s.end();
});
});
});
return tr;
function createResult (sel, opts) {
var r = new Result(sel);
var element, welem;
this._select.select(str, function (elem) {
element = elem;
welem = wrapElem(elem);
if (cb) cb(welem);
if (opts.all === false) {
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);
});
}
elem.once('close', function () {
element = null;
welem = null;
});
r.on('_write-begin', function (stream) {
if (lastToken[0] === 'tag-end'
&& lastToken[1].length > 0
&& '>' === String.fromCharCode(lastToken[1][lastToken[1].length-1])
) {
if (lastToken[1].length) tr.queue(lastToken[1]);
}
if (stream._skipping !== false) {
tokens.pause();
}
skipping = true;
stream.pipe(through(write, end));
stream.resume();
function write (buf) {
if (Buffer.isBuffer(buf)) {
if (buf.length) tr.queue(buf)
}
else if (typeof buf === 'string') {
if (buf.length) tr.queue(Buffer(buf));
}
else {
buf = String(buf);
if (buf.length) tr.queue(Buffer(buf));
}
}
function end () {
if (stream._skipping !== false) {
tokens.resume();
}
}
readers.splice(0).forEach(function (r) {
welem.createReadStream(r._options).pipe(r);
});
r.on('_write-end', function () {
skipping = false;
writers.splice(0).forEach(function (w) {
w.pipe(welem.createWriteStream(w._options));
});
r.on('queue', function (buf) { tr.queue(buf) });
duplex.splice(0).forEach(function (d) {
d.input.pipe(welem.createStream(d.options))
.pipe(d.output)
;
});
selectors.push(r);
return r;
}
function write (lex) {
lastToken = lex;
var writeSkip = false;
gets.splice(0).forEach(function (g) {
welem.getAttribute(g[0], g[1]);
});
var sub;
selectors.forEach(function (s) {
s._at(lex);
if (s._substitute !== undefined) {
sub = s._substitute;
s._substitute = undefined;
}
if (s._writing === 'next') {
s._writing = false;
s.emit('_write-end');
writeSkip = true;
}
getss.splice(0).forEach(function (cb) {
welem.getAttributes(cb);
});
if (skipSpace) {
skipSpace = false;
if (lex[0] === 'tag-space') return;
}
if (skipping || writeSkip) return;
sets.splice(0).forEach(function (g) {
welem.setAttribute(g[0], g[1]);
});
if (sub === undefined) {
if (lex[1].length) tr.queue(lex[1]);
}
else if (sub === null) {
skipSpace = true;
}
else if (sub.length) tr.queue(sub);
}
function end () {
tr.queue(null);
}
};
inherits(Result, EventEmitter);
function Result (sel) {
var self = this;
self._setAttr = {};
self._rmAttr = {};
self._getAttr = {};
self._readStreams = [];
self._writeStream = null;
self._reading = false;
self._writing = false;
self._matcher = matcher(parseSelector(sel));
var remainingSets = [];
self._matcher.on('open', function (m) {
remainingSets = Object.keys(self._setAttr);
if (self._writeStream && self._writeStream.outer) {
self._writing = true;
self._writeLevel = m.stack.length;
self.emit('_write-begin', self._writeStream);
}
removes.splice(0).forEach(function (key) {
welem.removeAttribute(key);
});
});
self._matcher.on('tag-end', function (m) {
for (var i = 0; i < remainingSets.length; i++) {
var key = remainingSets[i];
self.emit('queue', Buffer(' ' + self._setAttr[key]));
return {
getAttribute: function (key, cb) {
if (welem) return welem.getAttribute(key, cb);
gets.push([ key, cb ]);
},
getAttributes: function (cb) {
getss.push(cb);
},
setAttribute: function (key, value) {
if (welem) return welem.setAttribute(key, value);
sets.push([ key, value ]);
},
removeAttribute: function (key) {
if (welem) return welem.removeAttribute(key);
removes.push(key);
},
createReadStream: function (opts) {
if (welem) return welem.createReadStream(opts);
var r = through();
r._options = opts;
readers.push(r);
return r;
},
createWriteStream: function (opts) {
if (welem) return welem.createWriteStream(opts);
var w = through();
w._options = opts;
writers.push(w);
return w;
},
createStream: function (opts) {
if (welem) return welem.createStream(opts);
var d = { input: through(), output: through() };
d.options = opts;
duplex.push(d);
return duplexer(d.input, d.output);
}
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._writeStream.outer) {
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;
var ix = remainingSets.indexOf(node.name);
if (ix >= 0) remainingSets.splice(ix, 1);
}
if (self._rmAttr[node.name]) {
self._substitute = null;
}
});
}
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) {
if (s.outer && lex[1].length) s.queue(lex[1]);
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 && lex[1].length) s.queue(lex[1]);
}
}
if (this._writing === 'next') {
this._writing = false;
this.emit('_write-end');
}
else if (this._writing && lex[0] === 'closetag') {
var level = this._matcher.matchers[0].stack.length;
if (level === this._writeLevel) {
if (this._writeStream.outer) {
this._writing = 'next';
}
else {
this._writing = false;
this.emit('_write-end');
}
}
}
var matching = this._matcher.at(lex[0], lex[2]);
if (matching) {
for (var i = 0; i < this._readStreams.length; i++) {
var rs = this._readStreams[i];
if (rs.outer && lex[1].length) rs.queue(lex[1]);
}
}
};
};
Result.prototype.setAttribute = function (key, value) {
var sub = Buffer(ent.encode(key) + '="' + ent.encode(value) + '"');
this._setAttr[key.toUpperCase()] = sub;
return this;
Trumpet.prototype.createReadStream = function (sel, opts) {
return this.select(sel).createReadStream(opts);
};
Result.prototype.removeAttribute = function (key) {
this._rmAttr[key.toUpperCase()] = true;
return this;
Trumpet.prototype.createWriteStream = function (sel, opts) {
return this.select(sel).createWriteStream(opts);
};
Result.prototype.getAttribute = function (key, cb) {
this._getAttr[key.toUpperCase()] = cb;
Trumpet.prototype.createStream = function (sel, opts) {
return this.select(sel).createStream(opts);
};
Result.prototype.createWriteStream = function (opts) {
if (!opts) opts = {};
var stream = through().pause();
if (opts.outer) stream.outer = true;
this._writeStream = stream;
return stream;
};
Result.prototype.createReadStream = function (opts) {
if (!opts) opts = {};
var stream = through();
if (opts.outer) stream.outer = true;
this._readStreams.push(stream);
return stream;
};
Result.prototype.createStream = function (opts) {
var ws = Result.prototype.createWriteStream.call(this, opts);
ws._skipping = false;
var rs = Result.prototype.createReadStream.call(this, opts);
return duplexer(ws, rs);
};
{
"name" : "trumpet",
"version" : "1.6.3",
"description" : "parse and transform streaming html using css selectors",
"main" : "index.js",
"dependencies" : {
"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",
"tape" : "~1.0.4",
"concat-stream" : "~1.0.0"
},
"scripts" : {
"test" : "tap test/*.js"
},
"repository" : {
"type" : "git",
"url" : "http://github.com/substack/node-trumpet.git"
},
"keywords" : [
"html",
"streaming",
"parser",
"transform",
"selectors",
"css"
],
"author" : {
"name" : "James Halliday",
"email" : "mail@substack.net",
"url" : "http://substack.net"
},
"license" : "MIT",
"engine" : { "node" : ">=0.4" }
"name": "trumpet",
"version": "1.6.4",
"description": "parse and transform streaming html using css selectors",
"main": "index.js",
"dependencies": {
"html-select": "^2.3.5",
"html-tokenize": "^1.1.1",
"through2": "^1.0.0",
"duplexer2": "~0.0.2",
"inherits": "^2.0.0",
"readable-stream": "^1.0.27-1"
},
"devDependencies": {
"tape": "~2.12.3",
"concat-stream": "~1.4.5",
"through": "~2.3.4"
},
"scripts": {
"test": "tape test/*.js"
},
"repository": {
"type": "git",
"url": "http://github.com/substack/node-trumpet.git"
},
"keywords": [
"html",
"streaming",
"parser",
"transform",
"selectors",
"css"
],
"author": {
"name": "James Halliday",
"email": "mail@substack.net",
"url": "http://substack.net"
},
"license": "MIT",
"engine": {
"node": ">=0.4"
}
}
var test = require('tape');
var trumpet = require('../');
var through = require('through');
var through = require('through2');
var concat = require('concat-stream');

@@ -13,4 +13,5 @@ var fs = require('fs');

var loud = tr.select('.loud').createStream();
loud.pipe(through(function (buf) {
this.queue(buf.toString().toUpperCase());
loud.pipe(through(function (buf, enc, next) {
this.push(buf.toString().toUpperCase());
next();
})).pipe(loud);

@@ -17,0 +18,0 @@

@@ -23,3 +23,3 @@ var trumpet = require('../');

tr.selectAll('.b span', function (span) {
t.equal(span.name, 'SPAN');
t.equal(span.name, 'span');
var rs = span.createReadStream();

@@ -26,0 +26,0 @@ rs.pipe(output, { end: false });

@@ -77,3 +77,3 @@ var trumpet = require('../');

var c_ = classes.shift();
t.equal(div.attributes.CLASS, c_);
t.equal(div.getAttribute('class'), c_);

@@ -80,0 +80,0 @@ div.getAttribute('class', function (c) {

@@ -11,3 +11,3 @@ var trumpet = require('../');

tr.selectAll('input[type=text]', function (elem) {
elem.setAttribute('value', elem.attributes.VALUE.toUpperCase());
elem.setAttribute('value', elem.getAttribute('value').toUpperCase());
});

@@ -14,0 +14,0 @@

@@ -10,3 +10,3 @@ var trumpet = require('../');

var tr = trumpet();
var elem = tr.select('.a + .d');
var elem = tr.select('.b + .d');
elem.getAttribute('class', function (value) {

@@ -13,0 +13,0 @@ t.equal(value, 'd');

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

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