use CSS classes for ref:* selectors (#1230)

pull/1494/head
Conduitry 6 years ago
parent 9e52cf931d
commit 2b3e9a3523

@ -300,13 +300,6 @@ export default class Element extends Node {
block.builders.destroy.addConditional('detach', `@detachNode(${name});`);
}
// 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
if (!this.namespace && this.canUseInnerHTML && this.children.length > 0) {
if (this.children.length === 1 && this.children[0].type === 'Text') {
@ -394,10 +387,6 @@ export default class Element extends Node {
let open = `<${node.name}`;
if (node._cssRefAttribute) {
open += ` svelte-ref-${node._cssRefAttribute}`;
}
node.attributes.forEach((attr: Node) => {
open += ` ${fixAttributeCasing(attr.name)}${stringifyAttributeValue(attr.chunks)}`
});
@ -858,19 +847,17 @@ export default class Element extends Node {
return `@appendNode(${this.var}, ${name}._slotted.default);`;
}
addCssClass() {
addCssClass(className = this.compiler.stylesheet.id) {
const classAttribute = this.attributes.find(a => a.name === 'class');
if (classAttribute && !classAttribute.isTrue) {
if (classAttribute.chunks.length === 1 && classAttribute.chunks[0].type === 'Text') {
(<Text>classAttribute.chunks[0]).data += ` ${this.compiler.stylesheet.id}`;
(<Text>classAttribute.chunks[0]).data += ` ${className}`;
} else {
(<Node[]>classAttribute.chunks).push(
new Text(this.compiler, this, this.scope, {
type: 'Text',
data: ` ${this.compiler.stylesheet.id}`
data: ` ${className}`
})
// new Text({ type: 'Text', data: ` ${this.compiler.stylesheet.id}` })
);
}
} else {
@ -878,7 +865,7 @@ export default class Element extends Node {
new Attribute(this.compiler, this, this.scope, {
type: 'Attribute',
name: 'class',
value: [{ type: 'Text', data: `${this.compiler.stylesheet.id}` }]
value: [{ type: 'Text', data: className }]
})
);
}
@ -945,10 +932,6 @@ export default class Element extends Node {
});
}
if (this._cssRefAttribute) {
openingTag += ` svelte-ref-${this._cssRefAttribute}`;
}
openingTag += '>';
compiler.target.append(openingTag);

@ -30,7 +30,7 @@ export default class Selector {
apply(node: Node, stack: Node[]) {
const toEncapsulate: Node[] = [];
applySelector(this.localBlocks.slice(), node, stack.slice(), toEncapsulate);
applySelector(this.stylesheet, this.localBlocks.slice(), node, stack.slice(), toEncapsulate);
if (toEncapsulate.length > 0) {
toEncapsulate.filter((_, i) => i === 0 || i === toEncapsulate.length - 1).forEach(({ node, block }) => {
@ -76,7 +76,7 @@ export default class Selector {
const selector = block.selectors[i];
if (selector.type === 'RefSelector') {
code.overwrite(selector.start, selector.end, `[svelte-ref-${selector.name}]`, {
code.overwrite(selector.start, selector.end, `.svelte-ref-${selector.name}`, {
contentOnly: true,
storeName: false
});
@ -136,7 +136,7 @@ function isDescendantSelector(selector: Node) {
return selector.type === 'WhiteSpace' || selector.type === 'Combinator';
}
function applySelector(blocks: Block[], node: Node, stack: Node[], toEncapsulate: any[]): boolean {
function applySelector(stylesheet: Stylesheet, blocks: Block[], node: Node, stack: Node[], toEncapsulate: any[]): boolean {
const block = blocks.pop();
if (!block) return false;
@ -179,7 +179,7 @@ function applySelector(blocks: Block[], node: Node, stack: Node[], toEncapsulate
else if (selector.type === 'RefSelector') {
if (node.ref === selector.name) {
node._cssRefAttribute = selector.name;
stylesheet.nodesWithRefCssClass.set(selector.name, node);
toEncapsulate.push({ node, block });
return true;
}
@ -196,7 +196,7 @@ function applySelector(blocks: Block[], node: Node, stack: Node[], toEncapsulate
if (block.combinator) {
if (block.combinator.type === 'WhiteSpace') {
while (stack.length) {
if (applySelector(blocks.slice(), stack.pop(), stack, toEncapsulate)) {
if (applySelector(stylesheet, blocks.slice(), stack.pop(), stack, toEncapsulate)) {
toEncapsulate.push({ node, block });
return true;
}
@ -204,7 +204,7 @@ function applySelector(blocks: Block[], node: Node, stack: Node[], toEncapsulate
return false;
} else if (block.combinator.name === '>') {
if (applySelector(blocks, stack.pop(), stack, toEncapsulate)) {
if (applySelector(stylesheet, blocks, stack.pop(), stack, toEncapsulate)) {
toEncapsulate.push({ node, block });
return true;
}

@ -247,6 +247,7 @@ export default class Stylesheet {
keyframes: Map<string, string>;
nodesWithCssClass: Set<Node>;
nodesWithRefCssClass: Map<String, Node>;
constructor(source: string, ast: Ast, filename: string, dev: boolean) {
this.source = source;
@ -258,6 +259,7 @@ export default class Stylesheet {
this.keyframes = new Map();
this.nodesWithCssClass = new Set();
this.nodesWithRefCssClass = new Map();
if (ast.css && ast.css.children.length) {
this.id = `svelte-${hash(ast.css.content.styles)}`;
@ -337,6 +339,9 @@ export default class Stylesheet {
this.nodesWithCssClass.forEach((node: Node) => {
node.addCssClass();
});
this.nodesWithRefCssClass.forEach((node: Node, name: String) => {
node.addCssClass(`svelte-ref-${name}`);
})
}
render(cssOutputFilename: string, shouldTransformSelectors: boolean) {

@ -1 +1 @@
[svelte-ref-button].active.svelte-xyz{color:red}
.svelte-ref-button.active.svelte-xyz{color:red}

@ -1 +1 @@
<button svelte-ref-button="" class="active svelte-xyz">deactivate</button>
<button class="active svelte-xyz svelte-ref-button">deactivate</button>

@ -1 +1 @@
[svelte-ref-a].svelte-xyz{color:red}[svelte-ref-b].svelte-xyz{color:green}
.svelte-ref-a.svelte-xyz{color:red}.svelte-ref-b.svelte-xyz{color:green}

@ -1,3 +1,3 @@
<div class="svelte-xyz" svelte-ref-a=''></div>
<div class="svelte-xyz" svelte-ref-b=''></div>
<div class="svelte-xyz svelte-ref-a"></div>
<div class="svelte-xyz svelte-ref-b"></div>
<div></div>
Loading…
Cancel
Save