Skip to content

Commit

Permalink
Merge pull request #15495 from stefan-schweiger/15494-void-elements
Browse files Browse the repository at this point in the history
Angular: Fix void element selectors
  • Loading branch information
shilman committed Jan 10, 2022
2 parents d838b3c + c6ef520 commit fc03acf
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 1 deletion.
Expand Up @@ -77,6 +77,22 @@ describe('angular source decorator', () => {
});
});

describe('with component with void element and attribute selector', () => {
@Component({
selector: 'input[foo]',
template: '<button></button>',
})
class VoidElementWithAttributeComponent {}

it('should create without separate closing tag', async () => {
const component = VoidElementWithAttributeComponent;
const props = {};
const argTypes: ArgTypes = {};
const source = computesTemplateSourceFromComponent(component, props, argTypes);
expect(source).toEqual(`<input foo />`);
});
});

describe('with component with attribute and value only selector', () => {
@Component({
selector: '[foo="bar"]',
Expand All @@ -93,6 +109,22 @@ describe('angular source decorator', () => {
});
});

describe('with component with void element, attribute and value only selector', () => {
@Component({
selector: 'input[foo="bar"]',
template: '<button></button>',
})
class VoidElementWithAttributeComponent {}

it('should create and add attribute to template without separate closing tag', async () => {
const component = VoidElementWithAttributeComponent;
const props = {};
const argTypes: ArgTypes = {};
const source = computesTemplateSourceFromComponent(component, props, argTypes);
expect(source).toEqual(`<input foo="bar" />`);
});
});

describe('with component with class selector', () => {
@Component({
selector: 'doc-button.foo',
Expand Down
Expand Up @@ -141,6 +141,26 @@ const buildTemplate = (
inputs: string,
outputs: string
) => {
// https://www.w3.org/TR/2011/WD-html-markup-20110113/syntax.html#syntax-elements
const voidElements = [
'area',
'base',
'br',
'col',
'command',
'embed',
'hr',
'img',
'input',
'keygen',
'link',
'meta',
'param',
'source',
'track',
'wbr',
];

const firstSelector = selector.split(',')[0];
const templateReplacers: [
string | RegExp,
Expand All @@ -153,7 +173,14 @@ const buildTemplate = (
[/#([\w-]+)/, ` id="$1"`],
[/((\.[\w-]+)+)/, (_, c) => ` class="${c.split`.`.join` `.trim()}"`],
[/(\[.+?])/g, (_, a) => ` ${a.slice(1, -1)}`],
[/([\S]+)(.*)/, `<$1$2${inputs}${outputs}>${innerTemplate}</$1>`],
[
/([\S]+)(.*)/,
(template, elementSelector) => {
return voidElements.some((element) => elementSelector === element)
? template.replace(/([\S]+)(.*)/, `<$1$2${inputs}${outputs} />`)
: template.replace(/([\S]+)(.*)/, `<$1$2${inputs}${outputs}>${innerTemplate}</$1>`);
},
],
];

return templateReplacers.reduce(
Expand Down

0 comments on commit fc03acf

Please sign in to comment.