diff --git a/src/generators/Generator.ts b/src/generators/Generator.ts
index 72edbe8d0e..0c22212cbc 100644
--- a/src/generators/Generator.ts
+++ b/src/generators/Generator.ts
@@ -9,6 +9,7 @@ import flattenReference from '../utils/flattenReference';
import reservedNames from '../utils/reservedNames';
import namespaces from '../utils/namespaces';
import { removeNode, removeObjectKey } from '../utils/removeNode';
+import nodeToString from '../utils/nodeToString';
import wrapModule from './wrapModule';
import annotateWithScopes, { Scope } from '../utils/annotateWithScopes';
import getName from '../utils/getName';
@@ -599,7 +600,7 @@ export default class Generator {
}
if (templateProperties.namespace) {
- const ns = templateProperties.namespace.value.value;
+ const ns = nodeToString(templateProperties.namespace.value);
this.namespace = namespaces[ns] || ns;
}
@@ -618,7 +619,7 @@ export default class Generator {
}
if (templateProperties.props) {
- this.props = templateProperties.props.value.elements.map((element: Node) => element.value);
+ this.props = templateProperties.props.value.elements.map((element: Node) => nodeToString(element));
}
if (templateProperties.setup) {
@@ -630,7 +631,7 @@ export default class Generator {
}
if (templateProperties.tag) {
- this.tag = templateProperties.tag.value.value;
+ this.tag = nodeToString(templateProperties.tag.value);
}
if (templateProperties.transitions) {
diff --git a/src/utils/nodeToString.ts b/src/utils/nodeToString.ts
new file mode 100644
index 0000000000..1f72233596
--- /dev/null
+++ b/src/utils/nodeToString.ts
@@ -0,0 +1,11 @@
+import { Node } from '../interfaces';
+
+export default function nodeToString(node: Node) {
+ if (node.type === 'Literal' && typeof node.value === 'string') {
+ return node.value;
+ } else if (node.type === 'TemplateLiteral'
+ && node.quasis.length === 1
+ && node.expressions.length === 0) {
+ return node.quasis[0].value.raw;
+ }
+}
diff --git a/src/validate/js/index.ts b/src/validate/js/index.ts
index a0fc3ee017..b6157578db 100644
--- a/src/validate/js/index.ts
+++ b/src/validate/js/index.ts
@@ -3,6 +3,7 @@ import fuzzymatch from '../utils/fuzzymatch';
import checkForDupes from './utils/checkForDupes';
import checkForComputedKeys from './utils/checkForComputedKeys';
import namespaces from '../../utils/namespaces';
+import nodeToString from '../../utils/nodeToString';
import getName from '../../utils/getName';
import { Validator } from '../';
import { Node } from '../../interfaces';
@@ -77,7 +78,7 @@ export default function validateJs(validator: Validator, js: Node) {
});
if (props.has('namespace')) {
- const ns = props.get('namespace').value.value;
+ const ns = nodeToString(props.get('namespace').value);
validator.namespace = namespaces[ns] || ns;
}
diff --git a/src/validate/js/propValidators/namespace.ts b/src/validate/js/propValidators/namespace.ts
index cf887df2bd..e7436f3eb4 100644
--- a/src/validate/js/propValidators/namespace.ts
+++ b/src/validate/js/propValidators/namespace.ts
@@ -1,4 +1,5 @@
import * as namespaces from '../../../utils/namespaces';
+import nodeToString from '../../../utils/nodeToString'
import fuzzymatch from '../../utils/fuzzymatch';
import { Validator } from '../../';
import { Node } from '../../../interfaces';
@@ -6,9 +7,9 @@ import { Node } from '../../../interfaces';
const valid = new Set(namespaces.validNamespaces);
export default function namespace(validator: Validator, prop: Node) {
- const ns = prop.value.value;
+ const ns = nodeToString(prop.value);
- if (prop.value.type !== 'Literal' || typeof ns !== 'string') {
+ if (typeof ns !== 'string') {
validator.error(
`The 'namespace' property must be a string literal representing a valid namespace`,
prop
diff --git a/src/validate/js/propValidators/props.ts b/src/validate/js/propValidators/props.ts
index 57c1fb78ef..6731d6adcf 100644
--- a/src/validate/js/propValidators/props.ts
+++ b/src/validate/js/propValidators/props.ts
@@ -1,5 +1,6 @@
import { Validator } from '../../';
import { Node } from '../../../interfaces';
+import nodeToString from '../../../utils/nodeToString';
export default function props(validator: Validator, prop: Node) {
if (prop.value.type !== 'ArrayExpression') {
@@ -10,7 +11,7 @@ export default function props(validator: Validator, prop: Node) {
}
prop.value.elements.forEach((element: Node) => {
- if (element.type !== 'Literal' || typeof element.value !== 'string') {
+ if (typeof nodeToString(element) !== 'string') {
validator.error(
`'props' must be an array of string literals`,
element
diff --git a/src/validate/js/propValidators/tag.ts b/src/validate/js/propValidators/tag.ts
index 18b79760d9..80a38baa80 100644
--- a/src/validate/js/propValidators/tag.ts
+++ b/src/validate/js/propValidators/tag.ts
@@ -1,15 +1,16 @@
import { Validator } from '../../';
import { Node } from '../../../interfaces';
+import nodeToString from '../../../utils/nodeToString';
export default function tag(validator: Validator, prop: Node) {
- if (prop.value.type !== 'Literal' || typeof prop.value.value !== 'string') {
+ const tag = nodeToString(prop.value);
+ if (typeof tag !== 'string') {
validator.error(
`'tag' must be a string literal`,
prop.value
);
}
- const tag = prop.value.value;
if (!/^[a-zA-Z][a-zA-Z0-9]*-[a-zA-Z0-9-]+$/.test(tag)) {
validator.error(
`tag name must be two or more words joined by the '-' character`,
diff --git a/test/runtime/samples/svg-child-component-declared-namespace-backtick-string/Rect.html b/test/runtime/samples/svg-child-component-declared-namespace-backtick-string/Rect.html
new file mode 100644
index 0000000000..0813c3c143
--- /dev/null
+++ b/test/runtime/samples/svg-child-component-declared-namespace-backtick-string/Rect.html
@@ -0,0 +1,7 @@
+