apply CSS scoping classes directly to AST (WIP)

pull/1228/head
Conduitry 7 years ago
parent eae98f952d
commit e4032ea543

@ -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;
});

@ -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;
}

@ -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

@ -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('')}</${node.name}>`;
@ -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 {
(<Node[]>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(

@ -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 += '>';

Loading…
Cancel
Save