You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
svelte/src/generators/server-side-rendering/visitors/Element.ts

76 lines
1.9 KiB

import visitComponent from './Component';
import isVoidElementName from '../../../utils/isVoidElementName';
import visit from '../visit';
import visitWindow from './meta/Window';
import { SsrGenerator } from '../index';
import Block from '../Block';
import { Node } from '../../../interfaces';
const meta = {
':Window': visitWindow
};
function stringifyAttributeValue ( block: Block, chunks: Node[] ) {
return chunks.map( ( chunk: Node ) => {
if ( chunk.type === 'Text' ) {
return chunk.data;
}
const { snippet } = block.contextualise( chunk.expression );
return '${' + snippet + '}';
}).join( '' )
}
export default function visitElement ( generator: SsrGenerator, block: Block, node: Node ) {
if ( node.name in meta ) {
return meta[ node.name ]( generator, block, node );
}
if ( generator.components.has( node.name ) || node.name === ':Self' ) {
visitComponent( generator, block, node );
return;
}
let openingTag = `<${node.name}`;
let textareaContents; // awkward special case
node.attributes.forEach( ( attribute: Node ) => {
if ( attribute.type !== 'Attribute' ) return;
if ( attribute.name === 'value' && node.name === 'textarea' ) {
textareaContents = stringifyAttributeValue( block, attribute.value );
} else {
let str = ` ${attribute.name}`;
if ( attribute.value !== true ) {
str += `="${stringifyAttributeValue( block, attribute.value )}"`;
}
openingTag += str;
}
});
if ( generator.cssId && !generator.elementDepth ) {
openingTag += ` ${generator.cssId}`;
}
openingTag += '>';
generator.append( openingTag );
if ( node.name === 'textarea' && textareaContents !== undefined ) {
generator.append( textareaContents );
} else {
generator.elementDepth += 1;
node.children.forEach( ( child: Node ) => {
visit( generator, block, child );
});
generator.elementDepth -= 1;
}
if ( !isVoidElementName( node.name ) ) {
generator.append( `</${node.name}>` );
}
}