Skip to content

Commit

Permalink
Merge pull request #1494 from sveltejs/gh-1230
Browse files Browse the repository at this point in the history
use CSS classes for ref:* selectors
  • Loading branch information
Rich-Harris committed May 25, 2018
2 parents 058f7ea + 2b3e9a3 commit 29ec07e
Show file tree
Hide file tree
Showing 7 changed files with 20 additions and 32 deletions.
25 changes: 4 additions & 21 deletions src/compile/nodes/Element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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') {
Expand Down Expand Up @@ -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)}`
});
Expand Down Expand Up @@ -858,27 +847,25 @@ 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 {
this.attributes.push(
new Attribute(this.compiler, this, this.scope, {
type: 'Attribute',
name: 'class',
value: [{ type: 'Text', data: `${this.compiler.stylesheet.id}` }]
value: [{ type: 'Text', data: className }]
})
);
}
Expand Down Expand Up @@ -945,10 +932,6 @@ export default class Element extends Node {
});
}

if (this._cssRefAttribute) {
openingTag += ` svelte-ref-${this._cssRefAttribute}`;
}

openingTag += '>';

compiler.target.append(openingTag);
Expand Down
12 changes: 6 additions & 6 deletions src/css/Selector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 }) => {
Expand Down Expand Up @@ -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
});
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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;
}
Expand All @@ -196,15 +196,15 @@ 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;
}
}

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;
}
Expand Down
5 changes: 5 additions & 0 deletions src/css/Stylesheet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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)}`;
Expand Down Expand Up @@ -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) {
Expand Down
2 changes: 1 addition & 1 deletion test/css/samples/refs-qualified/expected.css
Original file line number Diff line number Diff line change
@@ -1 +1 @@
[svelte-ref-button].active.svelte-xyz{color:red}
.svelte-ref-button.active.svelte-xyz{color:red}
2 changes: 1 addition & 1 deletion test/css/samples/refs-qualified/expected.html
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<button svelte-ref-button="" class="active svelte-xyz">deactivate</button>
<button class="active svelte-xyz svelte-ref-button">deactivate</button>
2 changes: 1 addition & 1 deletion test/css/samples/refs/expected.css
Original file line number Diff line number Diff line change
@@ -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}
4 changes: 2 additions & 2 deletions test/css/samples/refs/expected.html
Original file line number Diff line number Diff line change
@@ -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>

0 comments on commit 29ec07e

Please sign in to comment.