diff --git a/src/utils/namespaces.js b/src/utils/namespaces.js index 2ab0b116f0..595d0f0def 100644 --- a/src/utils/namespaces.js +++ b/src/utils/namespaces.js @@ -5,4 +5,9 @@ export const xlink = 'http://www.w3.org/1999/xlink'; export const xml = 'http://www.w3.org/XML/1998/namespace'; export const xmlns = 'http://www.w3.org/2000/xmlns'; +export const validNamespaces = [ + 'html', 'mathml', 'svg', 'xlink', 'xml', 'xmlns', + html, mathml, svg, xlink, xml, xmlns +]; + export default { html, mathml, svg, xlink, xml, xmlns }; diff --git a/src/validate/html/index.js b/src/validate/html/index.js index 2e831ee9c1..f54c4d4fe5 100644 --- a/src/validate/html/index.js +++ b/src/validate/html/index.js @@ -18,7 +18,7 @@ export default function validateHtml ( validator, html ) { node.children.forEach( visit ); } - if (node.else ) { + if ( node.else ) { visit( node.else ); } diff --git a/src/validate/index.js b/src/validate/index.js index e1e536f4bd..4efdee8d47 100644 --- a/src/validate/index.js +++ b/src/validate/index.js @@ -36,7 +36,9 @@ export default function validate ( parsed, source, { onerror, onwarn, name, file }); }, - namespace: null + namespace: null, + defaultExport: null, + properties: {} }; if ( name && !/^[a-zA-Z_$][a-zA-Z_$0-9]*$/.test( name ) ) { diff --git a/src/validate/js/index.js b/src/validate/js/index.js index cdef266c96..d0fc396320 100644 --- a/src/validate/js/index.js +++ b/src/validate/js/index.js @@ -23,19 +23,19 @@ export default function validateJs ( validator, js ) { checkForComputedKeys( validator, node.declaration.properties ); checkForDupes( validator, node.declaration.properties ); - const templateProperties = {}; + const props = validator.properties; node.declaration.properties.forEach( prop => { - templateProperties[ prop.key.name ] = prop; + props[ prop.key.name ] = prop; }); // Remove these checks in version 2 - if ( templateProperties.oncreate && templateProperties.onrender ) { - validator.error( 'Cannot have both oncreate and onrender', templateProperties.onrender.start ); + if ( props.oncreate && props.onrender ) { + validator.error( 'Cannot have both oncreate and onrender', props.onrender.start ); } - if ( templateProperties.ondestroy && templateProperties.onteardown ) { - validator.error( 'Cannot have both ondestroy and onteardown', templateProperties.onteardown.start ); + if ( props.ondestroy && props.onteardown ) { + validator.error( 'Cannot have both ondestroy and onteardown', props.onteardown.start ); } // ensure all exported props are valid @@ -56,8 +56,8 @@ export default function validateJs ( validator, js ) { } }); - if ( templateProperties.namespace ) { - const ns = templateProperties.namespace.value.value; + if ( props.namespace ) { + const ns = props.namespace.value.value; validator.namespace = namespaces[ ns ] || ns; } diff --git a/src/validate/js/propValidators/namespace.js b/src/validate/js/propValidators/namespace.js index ca664261ef..ec8bad0a04 100644 --- a/src/validate/js/propValidators/namespace.js +++ b/src/validate/js/propValidators/namespace.js @@ -1,5 +1,22 @@ +import * as namespaces from '../../../utils/namespaces.js'; +import FuzzySet from '../utils/FuzzySet.js'; + +const fuzzySet = new FuzzySet( namespaces.validNamespaces ); +const valid = new Set( namespaces.validNamespaces ); + export default function namespace ( validator, prop ) { - if ( prop.value.type !== 'Literal' || typeof prop.value.value !== 'string' ) { + const ns = prop.value.value; + + if ( prop.value.type !== 'Literal' || typeof ns !== 'string' ) { validator.error( `The 'namespace' property must be a string literal representing a valid namespace`, prop.start ); } + + if ( !valid.has( ns ) ) { + const matches = fuzzySet.get( ns ); + if ( matches && matches[0] && matches[0][0] > 0.7 ) { + validator.error( `Invalid namespace '${ns}' (did you mean '${matches[0][1]}'?)`, prop.start ); + } else { + validator.error( `Invalid namespace '${ns}'`, prop.start ); + } + } } diff --git a/test/validator/samples/namespace-invalid/errors.json b/test/validator/samples/namespace-invalid/errors.json new file mode 100644 index 0000000000..b7f6d4d898 --- /dev/null +++ b/test/validator/samples/namespace-invalid/errors.json @@ -0,0 +1,8 @@ +[{ + "message": "Invalid namespace 'http://www.w3.org/1999/svg' (did you mean 'http://www.w3.org/2000/svg'?)", + "pos": 29, + "loc": { + "line": 3, + "column": 2 + } +}] diff --git a/test/validator/samples/namespace-invalid/input.html b/test/validator/samples/namespace-invalid/input.html new file mode 100644 index 0000000000..a2e5baf39b --- /dev/null +++ b/test/validator/samples/namespace-invalid/input.html @@ -0,0 +1,5 @@ + \ No newline at end of file