You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							76 lines
						
					
					
						
							2.2 KiB
						
					
					
				
			
		
		
	
	
							76 lines
						
					
					
						
							2.2 KiB
						
					
					
				'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(); | 
						|
}; | 
						|
 | 
						|
 |