2
0
mirror of https://github.com/tenrok/BBob.git synced 2026-05-15 11:59:37 +03:00

fix(parser): dont process nested tags as string if parent is not allowed (#84)

* fix(parser): dont process nested tags as string if parent is not allowed

* fix(plugin-helper): toString method with default params
This commit is contained in:
Nikolay Kostyurin
2020-12-16 23:51:28 +02:00
committed by GitHub
parent 0d839fa947
commit 70ff2e6660
3 changed files with 128 additions and 56 deletions
+14 -3
View File
@@ -1,4 +1,5 @@
import TagNode from '@bbob/plugin-helper/lib/TagNode';
import { CLOSE_BRAKET, OPEN_BRAKET } from '@bbob/plugin-helper/lib/char';
import { isTagNode } from '@bbob/plugin-helper/lib/index';
import { createLexer } from './lexer';
import { createList } from './utils';
@@ -16,6 +17,8 @@ import { createList } from './utils';
*/
const parse = (input, opts = {}) => {
const options = opts;
const openTag = options.openTag || OPEN_BRAKET;
const closeTag = options.closeTag || CLOSE_BRAKET;
let tokenizer = null;
@@ -114,7 +117,15 @@ const parse = (input, opts = {}) => {
if (isAllowedTag(node.tag)) {
items.push(node.toTagNode());
} else {
items.push(node.toString());
items.push(node.toTagStart({ openTag, closeTag }));
if (node.content.length) {
node.content.forEach((item) => {
items.push(item);
});
items.push(node.toTagEnd({ openTag, closeTag }));
}
}
} else {
items.push(node);
@@ -240,8 +251,8 @@ const parse = (input, opts = {}) => {
tokenizer = (opts.createTokenizer ? opts.createTokenizer : createLexer)(input, {
onToken,
onlyAllowTags: options.onlyAllowTags,
openTag: options.openTag,
closeTag: options.closeTag,
openTag,
closeTag,
enableEscapeTags: options.enableEscapeTags,
});
+99 -46
View File
@@ -25,27 +25,106 @@ describe('Parser', () => {
expectOutput(ast, output);
});
test('parse only allowed tags', () => {
const ast = parse('[h1 name=value]Foo [Bar] [/h1]', {
onlyAllowTags: ['h1']
});
const output = [
{
tag: 'h1',
attrs: {
name: 'value',
describe('onlyAllowTags', () => {
test('parse only allowed tags', () => {
const ast = parse('[h1 name=value]Foo [Bar] [/h1]', {
onlyAllowTags: ['h1']
});
const output = [
{
tag: 'h1',
attrs: {
name: 'value',
},
content: [
'Foo',
' ',
'[Bar]',
' '
],
},
content: [
'Foo',
' ',
'[Bar]',
' '
],
},
];
];
expectOutput(ast, output);
});
expectOutput(ast, output);
});
test('parse only allowed tags with params', () => {
const options = {
onlyAllowTags: ['b', 'i', 'u']
};
const ast = parse('hello [blah foo="bar"]world[/blah]', options);
expectOutput(ast, [
'hello',
' ',
'[blah foo="bar"]',
'world',
'[/blah]'
])
});
test('parse only allowed tags with named param', () => {
const options = {
onlyAllowTags: ['b', 'i', 'u']
};
const ast = parse('hello [blah="bar"]world[/blah]', options);
expectOutput(ast, [
'hello',
' ',
'[blah="bar"]',
'world',
'[/blah]'
])
});
test('parse only allowed tags inside disabled tags', () => {
const ast = parse('[tab] [ch]E[/ch]\nA cripple walks amongst you[/tab]\n[tab] [ch]A[/ch]\nAll you tired human beings[/tab]', {
onlyAllowTags: ['ch']
});
const output = [
'[tab]',
' ',
{
tag: 'ch',
attrs: {},
content: ['E'],
},
'\n',
'A',
' ',
'cripple',
' ',
'walks',
' ',
'amongst',
' ',
'you',
'[/tab]',
'\n',
'[tab]',
' ',
{
tag: 'ch',
attrs: {},
content: ['A'],
},
'\n',
'All',
' ',
'you',
' ',
'tired',
' ',
'human',
' ',
'beings',
'[/tab]',
];
expectOutput(ast, output);
});
})
test('parse inconsistent tags', () => {
const ast = parse('[h1 name=value]Foo [Bar] /h1]');
@@ -126,32 +205,6 @@ describe('Parser', () => {
expect(onError).toHaveBeenCalled();
});
test('parse only allowed tags with params', () => {
const options = {
onlyAllowTags: ['b', 'i', 'u']
};
const ast = parse('hello [blah foo="bar"]world[/blah]', options);
expectOutput(ast, [
'hello',
' ',
'[blah foo="bar"]world[/blah]',
])
});
test('parse only allowed tags with named param', () => {
const options = {
onlyAllowTags: ['b', 'i', 'u']
};
const ast = parse('hello [blah="bar"]world[/blah]', options);
expectOutput(ast, [
'hello',
' ',
'[blah="bar"]world[/blah]',
])
});
test('parse few tags without spaces', () => {
const ast = parse('[mytag1 size="15"]Tag1[/mytag1][mytag2 size="16"]Tag2[/mytag2][mytag3]Tag3[/mytag3]');
const output = [
@@ -189,7 +242,7 @@ describe('Parser', () => {
attrs: {},
content: ['hello'],
},
' ',
' ',
{
tag: 'textarea',
attrs: {
+15 -7
View File
@@ -43,22 +43,30 @@ class TagNode {
return getNodeLength(this);
}
toTagStart({ openTag = OPEN_BRAKET, closeTag = CLOSE_BRAKET } = {}) {
const tagAttrs = getTagAttrs(this.tag, this.attrs);
return `${openTag}${tagAttrs}${closeTag}`;
}
toTagEnd({ openTag = OPEN_BRAKET, closeTag = CLOSE_BRAKET } = {}) {
return `${openTag}${SLASH}${this.tag}${closeTag}`;
}
toTagNode() {
return new TagNode(this.tag.toLowerCase(), this.attrs, this.content);
}
toString() {
const OB = OPEN_BRAKET;
const CB = CLOSE_BRAKET;
toString({ openTag = OPEN_BRAKET, closeTag = CLOSE_BRAKET } = {}) {
const isEmpty = this.content.length === 0;
const content = this.content.reduce((r, node) => r + node.toString(), '');
const tagAttrs = getTagAttrs(this.tag, this.attrs);
const content = this.content.reduce((r, node) => r + node.toString({ openTag, closeTag }), '');
const tagStart = this.toTagStart({ openTag, closeTag });
if (isEmpty) {
return `${OB}${tagAttrs}${CB}`;
return tagStart;
}
return `${OB}${tagAttrs}${CB}${content}${OB}${SLASH}${this.tag}${CB}`;
return `${tagStart}${content}${this.toTagEnd({ openTag, closeTag })}`;
}
}