Skip to content

Commit

Permalink
Don’t strip a newline after closing pre/textarea tags
Browse files Browse the repository at this point in the history
  • Loading branch information
CvX committed Jun 28, 2019
1 parent 9a894bd commit e1b023b
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 2 deletions.
25 changes: 23 additions & 2 deletions src/evented-tokenizer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export default class EventedTokenizer {
reset() {
this.transitionTo(TokenizerState.beforeData);
this.input = '';
this.tagNameBuffer = '';

this.index = 0;
this.line = 1;
Expand Down Expand Up @@ -124,10 +125,12 @@ export default class EventedTokenizer {
} else {
if (char === '\n') {
let tag = this.tagNameBuffer.toLowerCase();

if (tag === 'pre' || tag === 'textarea') {
this.consume();
}
}

this.transitionTo(TokenizerState.data);
this.delegate.beginData();
}
Expand Down Expand Up @@ -168,7 +171,7 @@ export default class EventedTokenizer {
markupDeclarationOpen() {
let char = this.consume();

if (char === '-' && this.input.charAt(this.index) === '-') {
if (char === '-' && this.peek() === '-') {
this.consume();
this.transitionTo(TokenizerState.commentStart);
this.delegate.beginComment();
Expand Down Expand Up @@ -251,6 +254,24 @@ export default class EventedTokenizer {
}
},

endTagName() {
let char = this.consume();

if (isSpace(char)) {
this.transitionTo(TokenizerState.beforeAttributeName);
this.tagNameBuffer = '';
} else if (char === '/') {
this.transitionTo(TokenizerState.selfClosingStartTag);
this.tagNameBuffer = '';
} else if (char === '>') {
this.delegate.finishTag();
this.transitionTo(TokenizerState.beforeData);
this.tagNameBuffer = '';
} else {
this.appendToTagName(char);
}
},

beforeAttributeName() {
let char = this.peek();

Expand Down Expand Up @@ -453,7 +474,7 @@ export default class EventedTokenizer {
let char = this.consume();

if (char === '@' || char === ':' || isAlpha(char)) {
this.transitionTo(TokenizerState.tagName);
this.transitionTo(TokenizerState.endTagName);
this.tagNameBuffer = '';
this.delegate.beginEndTag();
this.appendToTagName(char);
Expand Down
1 change: 1 addition & 0 deletions src/generated/tokenizer-states.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export const enum TokenizerState {
tagOpen = 'tagOpen',
endTagOpen = 'endTagOpen',
tagName = 'tagName',
endTagName = 'endTagName',
rcdataLessThanSign = 'rcdataLessThanSign',
rcdataEndTagOpen = 'rcdataEndTagOpen',
rcdataEndTagName = 'rcdataEndTagName',
Expand Down
5 changes: 5 additions & 0 deletions tests/tokenizer-tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,11 @@ QUnit.test('A newline immediately following a <pre> tag is stripped', function(a
assert.deepEqual(tokens, [startTag('pre'), chars('hello'), endTag('pre')]);
});

QUnit.test('A newline immediately following a closing </pre> tag is not stripped', function(assert) {
let tokens = tokenize("\n<pre>\nhello</pre>\n");
assert.deepEqual(tokens, [chars('\n'), startTag('pre'), chars('hello'), endTag('pre'), chars('\n')]);
});

// https://html.spec.whatwg.org/multipage/syntax.html#element-restrictions
QUnit.test('A newline immediately following a <PRE> tag is stripped', function(assert) {
let tokens = tokenize("<PRE>\nhello</PRE>");
Expand Down

0 comments on commit e1b023b

Please sign in to comment.