12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576 |
- 'use strict';
- var WritableStream = require('stream').Writable,
- inherits = require('util').inherits,
- Parser = require('./index');
- var ParserStream = module.exports = function (options) {
- WritableStream.call(this);
- this.parser = new Parser(options);
- this.lastChunkWritten = false;
- this.writeCallback = null;
- this.pausedByScript = false;
- this.document = this.parser.treeAdapter.createDocument();
- this.pendingHtmlInsertions = [];
- this._resume = this._resume.bind(this);
- this._documentWrite = this._documentWrite.bind(this);
- this._scriptHandler = this._scriptHandler.bind(this);
- this.parser._bootstrap(this.document, null);
- };
- inherits(ParserStream, WritableStream);
- //WritableStream implementation
- ParserStream.prototype._write = function (chunk, encoding, callback) {
- this.writeCallback = callback;
- this.parser.tokenizer.write(chunk.toString('utf8'), this.lastChunkWritten);
- this._runParsingLoop();
- };
- ParserStream.prototype.end = function (chunk, encoding, callback) {
- this.lastChunkWritten = true;
- WritableStream.prototype.end.call(this, chunk || '', encoding, callback);
- };
- //Scriptable parser implementation
- ParserStream.prototype._runParsingLoop = function () {
- this.parser.runParsingLoopForCurrentChunk(this.writeCallback, this._scriptHandler);
- };
- ParserStream.prototype._resume = function () {
- if (!this.pausedByScript)
- throw new Error('Parser was already resumed');
- while (this.pendingHtmlInsertions.length) {
- var html = this.pendingHtmlInsertions.pop();
- this.parser.tokenizer.insertHtmlAtCurrentPos(html);
- }
- this.pausedByScript = false;
- //NOTE: keep parsing if we don't wait for the next input chunk
- if (this.parser.tokenizer.active)
- this._runParsingLoop();
- };
- ParserStream.prototype._documentWrite = function (html) {
- if (!this.parser.stopped)
- this.pendingHtmlInsertions.push(html);
- };
- ParserStream.prototype._scriptHandler = function (scriptElement) {
- if (this.listeners('script').length) {
- this.pausedByScript = true;
- this.emit('script', scriptElement, this._documentWrite, this._resume);
- }
- else
- this._runParsingLoop();
- };
|