diff --git a/src/css/Selector.ts b/src/css/Selector.ts index 1ca0b240f2..aea2abbe07 100644 --- a/src/css/Selector.ts +++ b/src/css/Selector.ts @@ -31,7 +31,7 @@ export default class Selector { if (toEncapsulate.length > 0) { toEncapsulate.filter((_, i) => i === 0 || i === toEncapsulate.length - 1).forEach(({ node, block }) => { - node._needsCssAttribute = true; + node.addCssClass(); block.shouldEncapsulate = true; }); diff --git a/src/css/Stylesheet.ts b/src/css/Stylesheet.ts index 3b37ca526e..cf0b8d523f 100644 --- a/src/css/Stylesheet.ts +++ b/src/css/Stylesheet.ts @@ -353,7 +353,7 @@ export default class Stylesheet { } if (this.cascade) { - if (stack.length === 0) node._needsCssAttribute = true; + if (stack.length === 0) node.addCssClass(); return; } diff --git a/src/generators/nodes/Attribute.ts b/src/generators/nodes/Attribute.ts index 69d8808730..57b387d20b 100644 --- a/src/generators/nodes/Attribute.ts +++ b/src/generators/nodes/Attribute.ts @@ -141,10 +141,6 @@ export default class Attribute { shouldCache = true; } - if (node._needsCssAttribute && name === 'class') { - value = `(${value}) + " ${this.generator.stylesheet.id}"`; - } - const isSelectValueAttribute = name === 'value' && node.name === 'select'; @@ -227,21 +223,10 @@ export default class Attribute { ); } } else { - const isScopedClassAttribute = ( - name === 'class' && - this.parent._needsCssAttribute && - !this.generator.customElement - ); - - const value = isScopedClassAttribute && this.value !== true - ? this.value.length === 0 - ? `'${this.generator.stylesheet.id}'` - : stringify(this.value[0].data.concat(` ${this.generator.stylesheet.id}`)) - : this.value === true - ? 'true' - : this.value.length === 0 - ? `''` - : stringify(this.value[0].data); + const value = + this.value === true + ? 'true' + : this.value.length === 0 ? `''` : stringify(this.value[0].data); const statement = ( isLegacyInputType diff --git a/src/generators/nodes/Element.ts b/src/generators/nodes/Element.ts index e836d072ce..1b5b49f498 100644 --- a/src/generators/nodes/Element.ts +++ b/src/generators/nodes/Element.ts @@ -212,22 +212,11 @@ export default class Element extends Node { block.builders.unmount.addLine(`@detachNode(${name});`); } - // add CSS encapsulation attribute - if (this._needsCssAttribute && !this.generator.customElement) { - if (!this.attributes.find(a => a.type === 'Attribute' && a.name === 'class')) { - block.builders.hydrate.addLine( - this.namespace - ? `@setAttribute(${name}, "class", "${this.generator.stylesheet.id}");` - : `${name}.className = "${this.generator.stylesheet.id}";` - ); - } - - // TODO move this into a class as well? - if (this._cssRefAttribute) { - block.builders.hydrate.addLine( - `@setAttribute(${name}, "svelte-ref-${this._cssRefAttribute}", "");` - ) - } + // TODO move this into a class as well? + if (this._cssRefAttribute) { + block.builders.hydrate.addLine( + `@setAttribute(${name}, "svelte-ref-${this._cssRefAttribute}", "");` + ) } // insert static children with textContent or innerHTML @@ -438,17 +427,9 @@ export default class Element extends Node { } node.attributes.forEach((attr: Node) => { - const value = (node._needsCssAttribute && attr.name === 'class') - ? [{ type: 'Text', data: `${attr.value[0].data} ${generator.stylesheet.id}` }] - : attr.value; - - open += ` ${fixAttributeCasing(attr.name)}${stringifyAttributeValue(value)}` + open += ` ${fixAttributeCasing(attr.name)}${stringifyAttributeValue(attr.value)}` }); - if (node._needsCssAttribute && !node.attributes.find(a => a.name === 'class')) { - open += ` class="${generator.stylesheet.id}"`; - } - if (isVoidElementName(node.name)) return open + '>'; return `${open}>${node.children.map(toHTML).join('')}`; @@ -688,6 +669,30 @@ export default class Element extends Node { return `@appendNode(${this.var}, ${name}._slotted${this.generator.legacy ? `["default"]` : `.default`});`; } + + addCssClass() { + if (this._addedCssClass || this.generator.customElement) return; + this._addedCssClass = true; + const classAttribute = this.attributes.find(a => a.name === 'class'); + if (classAttribute && classAttribute.value !== true) { + if (classAttribute.value.length === 1 && classAttribute.value[0].type === 'Text') { + classAttribute.value[0].data += ` ${this.generator.stylesheet.id}`; + } else { + (classAttribute.value).push( + new Node({ type: 'Text', data: ` ${this.generator.stylesheet.id}` }) + ); + } + } else { + this.attributes.push( + new Attribute({ + generator: this.generator, + name: 'class', + value: [new Node({ type: 'Text', data: `${this.generator.stylesheet.id}` })], + parent: this, + }) + ); + } + } } function getRenderStatement( diff --git a/src/generators/server-side-rendering/visitors/Element.ts b/src/generators/server-side-rendering/visitors/Element.ts index e8a5c91c3b..62c1fc8703 100644 --- a/src/generators/server-side-rendering/visitors/Element.ts +++ b/src/generators/server-side-rendering/visitors/Element.ts @@ -50,25 +50,12 @@ export default function visitElement( block.contextualise(attribute.value[0].expression); openingTag += '${' + attribute.value[0].metadata.snippet + ' ? " ' + attribute.name + '" : "" }'; } else { - const value = attribute.name === 'class' && node._needsCssAttribute - ? attribute.value.concat({ - type: 'Text', - data: ` ${generator.stylesheet.id}` - }) - : attribute.value; - - openingTag += ` ${attribute.name}="${stringifyAttributeValue(block, value)}"`; + openingTag += ` ${attribute.name}="${stringifyAttributeValue(block, attribute.value)}"`; } }); - if (node._needsCssAttribute && !node.attributes.find(a => a.type === 'Attribute' && a.name === 'class')) { - openingTag += ` class="${generator.stylesheet.id}"`; - } - - if (node._needsCssAttribute) { - if (node._cssRefAttribute) { - openingTag += ` svelte-ref-${node._cssRefAttribute}`; - } + if (node._cssRefAttribute) { + openingTag += ` svelte-ref-${node._cssRefAttribute}`; } openingTag += '>';