Skip to content

Commit 1affd0e

Browse files
authored
Added text node to script or style tags even if empty (#17)
* added text node to script or style tags even if empty * add the text node in "scryle" even if it's a zero-length string * actually avoid adding unnecessary text node and add text property only on script and style tags * add test for text node in script * add test for text node in style tags * remove temporary test file
1 parent c802592 commit 1affd0e

File tree

4 files changed

+136
-8
lines changed

4 files changed

+136
-8
lines changed

index.js

+11-4
Original file line numberDiff line numberDiff line change
@@ -1399,9 +1399,16 @@ function text(state) {
13991399
const start = match.index;
14001400
const end = re.lastIndex;
14011401
state.scryle = null; // reset the script/style flag now
1402-
// write the tag content, if any
1402+
// write the tag content
14031403
if (start > pos) {
14041404
parseSpecialTagsContent(state, name, match);
1405+
} else if (name !== TEXTAREA_TAG) {
1406+
state.last.text = {
1407+
type: TEXT,
1408+
text: '',
1409+
start: pos,
1410+
end: pos
1411+
};
14051412
}
14061413
// now the closing tag, either </script> or </style>
14071414
pushTag(state, `/${name}`, start, end);
@@ -1598,19 +1605,19 @@ const TREE_BUILDER_STRUCT = Object.seal({
15981605
},
15991606
pushText(store, node) {
16001607
const text = node.text;
1601-
const empty = !/\S/.test(text);
16021608
const scryle = store.scryle;
16031609
if (!scryle) {
16041610
// store.last always have a nodes property
16051611
const parent = store.last;
1606-
1612+
16071613
const pack = this.compact && !parent[IS_RAW];
1614+
const empty = !/\S/.test(text);
16081615
if (pack && empty) {
16091616
return
16101617
}
16111618
this.split(node, text, node.start, pack);
16121619
parent.nodes.push(node);
1613-
} else if (!empty) {
1620+
} else {
16141621
scryle.text = node;
16151622
}
16161623
},

src/parsers/text.js

+8-1
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,16 @@ export default function text(state) {
3232
const start = match.index
3333
const end = re.lastIndex
3434
state.scryle = null // reset the script/style flag now
35-
// write the tag content, if any
35+
// write the tag content
3636
if (start > pos) {
3737
parseSpecialTagsContent(state, name, match)
38+
} else if (name !== TEXTAREA_TAG) {
39+
state.last.text = {
40+
type: TEXT,
41+
text: '',
42+
start: pos,
43+
end: pos
44+
}
3845
}
3946
// now the closing tag, either </script> or </style>
4047
pushTag(state, `/${name}`, start, end)

src/tree-builder.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -175,19 +175,19 @@ const TREE_BUILDER_STRUCT = Object.seal({
175175
},
176176
pushText(store, node) {
177177
const text = node.text
178-
const empty = !/\S/.test(text)
179178
const scryle = store.scryle
180179
if (!scryle) {
181180
// store.last always have a nodes property
182181
const parent = store.last
183-
182+
184183
const pack = this.compact && !parent[IS_RAW]
184+
const empty = !/\S/.test(text)
185185
if (pack && empty) {
186186
return
187187
}
188188
this.split(node, text, node.start, pack)
189189
parent.nodes.push(node)
190-
} else if (!empty) {
190+
} else {
191191
scryle.text = node
192192
}
193193
},

test/tparser.js

+114
Original file line numberDiff line numberDiff line change
@@ -698,19 +698,133 @@ export default {
698698
valueStart: 18,
699699
},
700700
],
701+
text: { type: 3, text: '', start: 37, end: 37 },
701702
},
702703
{ type: 1, name: '/script', start: 37, end: 46 },
703704
{
704705
type: 1,
705706
name: 'script',
706707
start: 46,
707708
end: 54,
709+
text: { type: 3, text: '', start: 54, end: 54 },
708710
},
709711
{ type: 1, name: '/script', start: 54, end: 63 },
710712
{ type: 1, name: '/div', start: 63, end: 69 },
711713
],
712714
},
713715

716+
'script tag with zero-length content has empty text node': {
717+
data: "<component><script></script></component>",
718+
expected: [
719+
{
720+
type: 1,
721+
name: 'component',
722+
start: 0,
723+
end: 11,
724+
isCustom: true,
725+
},
726+
{
727+
type: 1,
728+
name: 'script',
729+
start: 11,
730+
end: 19,
731+
text: { type: 3, text: '', start: 19, end: 19 },
732+
},
733+
{ type: 1, name: '/script', start: 19, end: 28 },
734+
{
735+
type: 1,
736+
name: '/component',
737+
start: 28,
738+
end: 40,
739+
isCustom: true,
740+
},
741+
]
742+
},
743+
744+
'script tag with content containing only whiteline characters has text node': {
745+
data: "<component><script> </script></component>",
746+
expected: [
747+
{
748+
type: 1,
749+
name: 'component',
750+
start: 0,
751+
end: 11,
752+
isCustom: true,
753+
},
754+
{
755+
type: 1,
756+
name: 'script',
757+
start: 11,
758+
end: 19,
759+
},
760+
{ type: 3, text: ' ', start: 19, end: 21 },
761+
{ type: 1, name: '/script', start: 21, end: 30 },
762+
{
763+
type: 1,
764+
name: '/component',
765+
start: 30,
766+
end: 42,
767+
isCustom: true,
768+
},
769+
]
770+
},
771+
772+
'style tag with zero-length content has empty text node': {
773+
data: "<component><style></style></component>",
774+
expected: [
775+
{
776+
type: 1,
777+
name: 'component',
778+
start: 0,
779+
end: 11,
780+
isCustom: true,
781+
},
782+
{
783+
type: 1,
784+
name: 'style',
785+
start: 11,
786+
end: 18,
787+
text: { type: 3, text: '', start: 18, end: 18 },
788+
},
789+
{ type: 1, name: '/style', start: 18, end: 26 },
790+
{
791+
type: 1,
792+
name: '/component',
793+
start: 26,
794+
end: 38,
795+
isCustom: true,
796+
},
797+
]
798+
},
799+
800+
'style tag with content containing only whiteline characters has text node': {
801+
data: "<component><style> </style></component>",
802+
expected: [
803+
{
804+
type: 1,
805+
name: 'component',
806+
start: 0,
807+
end: 11,
808+
isCustom: true,
809+
},
810+
{
811+
type: 1,
812+
name: 'style',
813+
start: 11,
814+
end: 18,
815+
},
816+
{ type: 3, text: ' ', start: 18, end: 20 },
817+
{ type: 1, name: '/style', start: 20, end: 28 },
818+
{
819+
type: 1,
820+
name: '/component',
821+
start: 28,
822+
end: 40,
823+
isCustom: true,
824+
},
825+
]
826+
},
827+
714828
'whitespace after the tag name is ignored #1': {
715829
data: '<div\t\n\n \n\t/>',
716830
expected: [{ type: _T.TAG, name: 'div', end: 13, isSelfClosing: true }],

0 commit comments

Comments
 (0)