mirror of
https://github.com/sveltejs/svelte.git
synced 2024-12-01 17:30:59 +01:00
add support for declared namespaces – fixes #147
This commit is contained in:
parent
7f392e562b
commit
fbe130835d
@ -4,6 +4,7 @@ import deindent from '../utils/deindent.js';
|
||||
import isReference from '../utils/isReference.js';
|
||||
import counter from './utils/counter.js';
|
||||
import flattenReference from '../utils/flattenReference.js';
|
||||
import namespaces from '../utils/namespaces.js';
|
||||
import getIntro from './utils/getIntro.js';
|
||||
import getOutro from './utils/getOutro.js';
|
||||
import visitors from './visitors/index.js';
|
||||
@ -277,9 +278,17 @@ export default function generate ( parsed, source, options, names ) {
|
||||
});
|
||||
}
|
||||
|
||||
let namespace = null;
|
||||
if ( templateProperties.namespace ) {
|
||||
const ns = templateProperties.namespace.value;
|
||||
namespace = namespaces[ ns ] || ns;
|
||||
|
||||
// TODO remove the namespace property from the generated code, it's unused past this point
|
||||
}
|
||||
|
||||
generator.push({
|
||||
name: 'renderMainFragment',
|
||||
namespace: null,
|
||||
namespace,
|
||||
target: 'target',
|
||||
elementDepth: 0,
|
||||
localElementDepth: 0,
|
||||
|
8
src/utils/namespaces.js
Normal file
8
src/utils/namespaces.js
Normal file
@ -0,0 +1,8 @@
|
||||
export const html = 'http://www.w3.org/1999/xhtml';
|
||||
export const mathml = 'http://www.w3.org/1998/Math/MathML';
|
||||
export const svg = 'http://www.w3.org/2000/svg';
|
||||
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 default { html, mathml, svg, xlink, xml, xmlns };
|
@ -1,13 +1,31 @@
|
||||
import * as namespaces from '../../utils/namespaces.js';
|
||||
|
||||
const svg = /^(?:altGlyph|altGlyphDef|altGlyphItem|animate|animateColor|animateMotion|animateTransform|circle|clipPath|color-profile|cursor|defs|desc|discard|ellipse|feBlend|feColorMatrix|feComponentTransfer|feComposite|feConvolveMatrix|feDiffuseLighting|feDisplacementMap|feDistantLight|feDropShadow|feFlood|feFuncA|feFuncB|feFuncG|feFuncR|feGaussianBlur|feImage|feMerge|feMergeNode|feMorphology|feOffset|fePointLight|feSpecularLighting|feSpotLight|feTile|feTurbulence|filter|font|font-face|font-face-format|font-face-name|font-face-src|font-face-uri|foreignObject|g|glyph|glyphRef|hatch|hatchpath|hkern|image|line|linearGradient|marker|mask|mesh|meshgradient|meshpatch|meshrow|metadata|missing-glyph|mpath|path|pattern|polygon|polyline|radialGradient|rect|set|solidcolor|stop|switch|symbol|text|textPath|title|tref|tspan|unknown|use|view|vkern)$/;
|
||||
|
||||
export default function validateHtml ( validator, html ) {
|
||||
let elementDepth = 0;
|
||||
|
||||
function visit ( node ) {
|
||||
if ( node.type === 'EachBlock' ) {
|
||||
if ( !~validator.names.indexOf( node.context ) ) validator.names.push( node.context );
|
||||
if ( node.index && !~validator.names.indexOf( node.index ) ) validator.names.push( node.index );
|
||||
}
|
||||
|
||||
if ( node.type === 'Element' ) {
|
||||
if ( elementDepth === 0 && validator.namespace !== namespaces.svg && svg.test( node.name ) ) {
|
||||
validator.warn( `<${node.name}> is an SVG element – did you forget to add { namespace: 'svg' } ?`, node.start );
|
||||
}
|
||||
|
||||
elementDepth += 1;
|
||||
}
|
||||
|
||||
if ( node.children ) {
|
||||
node.children.forEach( visit );
|
||||
}
|
||||
|
||||
if ( node.type === 'Element' ) {
|
||||
elementDepth -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
html.children.forEach( visit );
|
||||
|
@ -40,17 +40,19 @@ export default function validate ( parsed, source, options ) {
|
||||
|
||||
templateProperties: {},
|
||||
|
||||
names: []
|
||||
};
|
||||
names: [],
|
||||
|
||||
if ( parsed.html ) {
|
||||
validateHtml( validator, parsed.html );
|
||||
}
|
||||
namespace: null
|
||||
};
|
||||
|
||||
if ( parsed.js ) {
|
||||
validateJs( validator, parsed.js );
|
||||
}
|
||||
|
||||
if ( parsed.html ) {
|
||||
validateHtml( validator, parsed.html );
|
||||
}
|
||||
|
||||
return {
|
||||
names: validator.names
|
||||
};
|
||||
|
@ -2,6 +2,7 @@ import propValidators from './propValidators/index.js';
|
||||
import FuzzySet from './utils/FuzzySet.js';
|
||||
import checkForDupes from './utils/checkForDupes.js';
|
||||
import checkForComputedKeys from './utils/checkForComputedKeys.js';
|
||||
import namespaces from '../../utils/namespaces.js';
|
||||
|
||||
const validPropList = Object.keys( propValidators );
|
||||
|
||||
@ -29,7 +30,7 @@ export default function validateJs ( validator, js ) {
|
||||
checkForDupes( validator, validator.defaultExport.declaration.properties );
|
||||
|
||||
validator.defaultExport.declaration.properties.forEach( prop => {
|
||||
validator.templateProperties[ prop.key.value ] = prop;
|
||||
validator.templateProperties[ prop.key.name ] = prop;
|
||||
});
|
||||
|
||||
validator.defaultExport.declaration.properties.forEach( prop => {
|
||||
@ -48,5 +49,10 @@ export default function validateJs ( validator, js ) {
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if ( validator.templateProperties.namespace ) {
|
||||
const ns = validator.templateProperties.namespace.value.value;
|
||||
validator.namespace = namespaces[ ns ] || ns;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ import helpers from './helpers.js';
|
||||
import methods from './methods.js';
|
||||
import components from './components.js';
|
||||
import events from './events.js';
|
||||
import namespace from './namespace.js';
|
||||
|
||||
export default {
|
||||
data,
|
||||
@ -15,5 +16,6 @@ export default {
|
||||
helpers,
|
||||
methods,
|
||||
components,
|
||||
events
|
||||
events,
|
||||
namespace
|
||||
};
|
||||
|
5
src/validate/js/propValidators/namespace.js
Normal file
5
src/validate/js/propValidators/namespace.js
Normal file
@ -0,0 +1,5 @@
|
||||
export default function namespace ( validator, prop ) {
|
||||
if ( prop.value.type !== 'Literal' || typeof prop.value.value !== 'string' ) {
|
||||
validator.error( `The 'namespace' property must be a string literal representing a valid namespace`, prop.start );
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
<rect x='{{x}}' y='{{y}}' width='{{width}}' height='{{height}}'/>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
namespace: 'svg'
|
||||
};
|
||||
</script>
|
@ -1,12 +1,13 @@
|
||||
export default {
|
||||
skip: true,
|
||||
data: {
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: 100,
|
||||
height: 100
|
||||
},
|
||||
|
||||
html: `<svg><rect x="0" y="0" width="100" height="100"></rect></svg>`,
|
||||
|
||||
test ( assert, component, target ) {
|
||||
const svg = target.querySelector( 'svg' );
|
||||
const rect = target.querySelector( 'rect' );
|
@ -1,6 +1,7 @@
|
||||
<svg>
|
||||
<Rect x='{{x}}' y='{{y}}' width='{{width}}' height='{{height}}'/>
|
||||
</svg>
|
||||
|
||||
<script>
|
||||
import Rect from './Rect.html';
|
||||
|
Before Width: | Height: | Size: 178 B After Width: | Height: | Size: 179 B |
@ -0,0 +1,7 @@
|
||||
<rect x='{{x}}' y='{{y}}' width='{{width}}' height='{{height}}'/>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
namespace: 'http://www.w3.org/2000/svg'
|
||||
};
|
||||
</script>
|
@ -0,0 +1,21 @@
|
||||
export default {
|
||||
data: {
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: 100,
|
||||
height: 100
|
||||
},
|
||||
|
||||
html: `<svg><rect x="0" y="0" width="100" height="100"></rect></svg>`,
|
||||
|
||||
test ( assert, component, target ) {
|
||||
const svg = target.querySelector( 'svg' );
|
||||
const rect = target.querySelector( 'rect' );
|
||||
|
||||
assert.equal( svg.namespaceURI, 'http://www.w3.org/2000/svg' );
|
||||
assert.equal( rect.namespaceURI, 'http://www.w3.org/2000/svg' );
|
||||
|
||||
component.set({ width: 150, height: 50 });
|
||||
assert.equal( target.innerHTML, `<svg><rect x="0" y="0" width="150" height="50"></rect></svg>` );
|
||||
}
|
||||
};
|
@ -0,0 +1,11 @@
|
||||
<svg>
|
||||
<Rect x='{{x}}' y='{{y}}' width='{{width}}' height='{{height}}'/>
|
||||
</svg>
|
||||
|
||||
<script>
|
||||
import Rect from './Rect.html';
|
||||
|
||||
export default {
|
||||
components: { Rect }
|
||||
};
|
||||
</script>
|
After Width: | Height: | Size: 179 B |
@ -0,0 +1,7 @@
|
||||
<rect x='{{x}}' y='{{y}}' width='{{width}}' height='{{height}}'/>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
namespace: 'svg'
|
||||
};
|
||||
</script>
|
@ -0,0 +1 @@
|
||||
[]
|
@ -0,0 +1,8 @@
|
||||
[{
|
||||
"message": "<rect> is an SVG element – did you forget to add { namespace: 'svg' } ?",
|
||||
"loc": {
|
||||
"line": 1,
|
||||
"column": 0
|
||||
},
|
||||
"pos": 0
|
||||
}]
|
Loading…
Reference in New Issue
Block a user