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.
92 lines
2.3 KiB
92 lines
2.3 KiB
'use strict';
|
|
|
|
const SAXParser = require('parse5-sax-parser');
|
|
const { escapeString } = require('parse5/lib/serializer');
|
|
|
|
class RewritingStream extends SAXParser {
|
|
constructor() {
|
|
super({ sourceCodeLocationInfo: true });
|
|
|
|
this.posTracker = this.locInfoMixin.posTracker;
|
|
}
|
|
|
|
_transformChunk(chunk) {
|
|
// NOTE: ignore upstream return value as we want to push to
|
|
// the Writable part of Transform stream ourselves.
|
|
super._transformChunk(chunk);
|
|
}
|
|
|
|
_getRawHtml(location) {
|
|
const droppedBufferSize = this.posTracker.droppedBufferSize;
|
|
const start = location.startOffset - droppedBufferSize;
|
|
const end = location.endOffset - droppedBufferSize;
|
|
|
|
return this.tokenizer.preprocessor.html.slice(start, end);
|
|
}
|
|
|
|
// Events
|
|
_handleToken(token) {
|
|
if (!super._handleToken(token)) {
|
|
this.emitRaw(this._getRawHtml(token.location));
|
|
}
|
|
|
|
// NOTE: don't skip new lines after <pre> and other tags,
|
|
// otherwise we'll have incorrect raw data.
|
|
this.parserFeedbackSimulator.skipNextNewLine = false;
|
|
}
|
|
|
|
// Emitter API
|
|
_emitToken(eventName, token) {
|
|
this.emit(eventName, token, this._getRawHtml(token.sourceCodeLocation));
|
|
}
|
|
|
|
emitDoctype(token) {
|
|
let res = `<!DOCTYPE ${token.name}`;
|
|
|
|
if (token.publicId !== null) {
|
|
res += ` PUBLIC "${token.publicId}"`;
|
|
} else if (token.systemId !== null) {
|
|
res += ' SYSTEM';
|
|
}
|
|
|
|
if (token.systemId !== null) {
|
|
res += ` "${token.systemId}"`;
|
|
}
|
|
|
|
res += '>';
|
|
|
|
this.push(res);
|
|
}
|
|
|
|
emitStartTag(token) {
|
|
let res = `<${token.tagName}`;
|
|
|
|
const attrs = token.attrs;
|
|
|
|
for (let i = 0; i < attrs.length; i++) {
|
|
res += ` ${attrs[i].name}="${escapeString(attrs[i].value, true)}"`;
|
|
}
|
|
|
|
res += token.selfClosing ? '/>' : '>';
|
|
|
|
this.push(res);
|
|
}
|
|
|
|
emitEndTag(token) {
|
|
this.push(`</${token.tagName}>`);
|
|
}
|
|
|
|
emitText({ text }) {
|
|
this.push(escapeString(text, false));
|
|
}
|
|
|
|
emitComment(token) {
|
|
this.push(`<!--${token.text}-->`);
|
|
}
|
|
|
|
emitRaw(html) {
|
|
this.push(html);
|
|
}
|
|
}
|
|
|
|
module.exports = RewritingStream;
|