Recomputes css hash id when unused selectors are present

This is an attempt to fix #4313 which demonstrates that incorrect css can be produced when two components have the same style rules and the first component to be included has unused selectors.
pull/4326/head
Colin Casey 6 years ago
parent efe8ab9ca5
commit 8f2e39b324

@ -170,6 +170,8 @@ export default class Component {
this.walk_instance_js_post_template();
this.stylesheet.recompute_stylesheet_hash(this);
if (!compile_options.customElement) this.stylesheet.reify();
this.stylesheet.warn_on_unused_selectors(this);
@ -1450,4 +1452,4 @@ function get_relative_path(from: string, to: string) {
}
return from_parts.concat(to_parts).join('/');
}
}

@ -376,6 +376,35 @@ export default class Stylesheet {
}
}
recompute_stylesheet_hash(component: Component) {
const collectIf = (test_function) => (acc, child) => {
if (child instanceof Atrule) {
child.children.forEach(rule => {
if (test_function(rule)) {
acc.push(rule);
}
});
} else {
if (test_function(child)) {
acc.push(child);
}
}
return acc;
};
const used_rules = this.children.reduce(collectIf(rule => rule.is_used(component.compile_options.dev)), []);
const unused_rules = this.children.reduce(collectIf(rule => !rule.is_used(component.compile_options.dev)), []);
if (unused_rules.length > 0) {
const new_hash = hash(used_rules.reduce((acc, rule: Rule) => {
for (let i = rule.node.start; i < rule.node.end; i++) {
acc += component.source.charAt(i);
}
return acc;
}, ''));
this.id = `svelte-${new_hash}`;
}
}
reify() {
this.nodes_with_css_class.forEach((node: Element) => {
node.add_css_class();

@ -0,0 +1,10 @@
<div class="component-1 red"> Red </div>
<style>
.red {
background: red;
}
.yellow {
background: yellow;
}
</style>

@ -0,0 +1,11 @@
<div class="component-2 red"> Red </div>
<div class="component-2 yellow"> Yellow </div>
<style>
.red {
background: red;
}
.yellow {
background: yellow;
}
</style>

@ -0,0 +1,10 @@
export default {
test({ assert, component, target, window }) {
const [component_one_red] = target.querySelectorAll('.component-1');
const [component_two_red, component_two_yellow] = target.querySelectorAll('.component-2');
assert.equal(window.getComputedStyle(component_one_red).background, 'red');
assert.equal(window.getComputedStyle(component_two_red).background, 'red');
assert.equal(window.getComputedStyle(component_two_yellow).background, 'yellow');
}
};

@ -0,0 +1,7 @@
<script>
import Component1 from './Component1.svelte'
import Component2 from './Component2.svelte'
</script>
<Component1 />
<Component2 />
Loading…
Cancel
Save