diff --git a/CHANGELOG.md b/CHANGELOG.md index 21a9441c41..b4ffb19d3c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Svelte changelog +## Unreleased + +* Fix specificity of certain styles involving a child selector ([#4795](https://github.com/sveltejs/svelte/issues/4795)) +* Fix transitions that are parameterised with stores ([#5244](https://github.com/sveltejs/svelte/issues/5244)) +* Fix scoping of styles involving child selector and `*` ([#5370](https://github.com/sveltejs/svelte/issues/5370)) + ## 3.25.0 * Use `null` rather than `undefined` for coerced bound value of `` ([#1701](https://github.com/sveltejs/svelte/issues/1701)) diff --git a/site/package-lock.json b/site/package-lock.json index 1dbad52271..93932806f8 100644 --- a/site/package-lock.json +++ b/site/package-lock.json @@ -1449,9 +1449,9 @@ } }, "@sveltejs/site-kit": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@sveltejs/site-kit/-/site-kit-1.2.4.tgz", - "integrity": "sha512-W+/PthWX4R8UvKr+IyWIITGoY3cl/54ePZr3dU9ZlyP9r/weEvvKDBvjmW8tAKQFRfbxyySmXUxEGBoPhF8XAA==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@sveltejs/site-kit/-/site-kit-1.2.5.tgz", + "integrity": "sha512-fA1YWW4tYOxPRVocx+jF4S2LGamku8xeKx/+J5aY7ZCbwuo/c4VF+T0K7WuQRI8U6Dw3pJqdiCra+xH4TnCGRw==", "dev": true, "requires": { "@sindresorhus/slugify": "^0.9.1", diff --git a/site/package.json b/site/package.json index d1972c09d2..6e00636476 100644 --- a/site/package.json +++ b/site/package.json @@ -41,7 +41,7 @@ "@rollup/plugin-node-resolve": "^9.0.0", "@rollup/plugin-replace": "^2.2.0", "@sindresorhus/slugify": "^0.9.1", - "@sveltejs/site-kit": "^1.2.4", + "@sveltejs/site-kit": "^1.2.5", "@sveltejs/svelte-repl": "^0.2.1", "degit": "^2.1.4", "dotenv": "^8.1.0", diff --git a/src/compiler/compile/css/Selector.ts b/src/compiler/compile/css/Selector.ts index 6bc046c93e..d18a7e7ba6 100644 --- a/src/compiler/compile/css/Selector.ts +++ b/src/compiler/compile/css/Selector.ts @@ -65,9 +65,8 @@ export default class Selector { transform(code: MagicString, attr: string, max_amount_class_specificity_increased: number) { const amount_class_specificity_to_increase = max_amount_class_specificity_increased - this.blocks.filter(block => block.should_encapsulate).length; - attr = attr.repeat(amount_class_specificity_to_increase + 1); - function encapsulate_block(block: Block) { + function encapsulate_block(block: Block, attr: string) { let i = block.selectors.length; while (i--) { @@ -89,15 +88,14 @@ export default class Selector { } } - this.blocks.forEach((block) => { + this.blocks.forEach((block, index) => { if (block.global) { const selector = block.selectors[0]; const first = selector.children[0]; const last = selector.children[selector.children.length - 1]; code.remove(selector.start, first.start).remove(last.end, selector.end); } - - if (block.should_encapsulate) encapsulate_block(block); + if (block.should_encapsulate) encapsulate_block(block, index === this.blocks.length - 1 ? attr.repeat(amount_class_specificity_to_increase + 1) : attr); }); } @@ -152,7 +150,7 @@ function apply_selector(blocks: Block[], node: Element, stack: Element[], to_enc if (!block) return false; if (!node) { - return blocks.every(block => block.global); + return block.global && blocks.every(block => block.global); } switch (block_might_apply_to_node(block, node)) { @@ -208,7 +206,7 @@ function apply_selector(blocks: Block[], node: Element, stack: Element[], to_enc return true; } -function block_might_apply_to_node(block, node): BlockAppliesToNode { +function block_might_apply_to_node(block: Block, node: Element): BlockAppliesToNode { let i = block.selectors.length; while (i--) { diff --git a/src/compiler/compile/nodes/Transition.ts b/src/compiler/compile/nodes/Transition.ts index a680fde46e..983a6ee6c7 100644 --- a/src/compiler/compile/nodes/Transition.ts +++ b/src/compiler/compile/nodes/Transition.ts @@ -34,7 +34,7 @@ export default class Transition extends Node { } this.expression = info.expression - ? new Expression(component, this, scope, info.expression, true) + ? new Expression(component, this, scope, info.expression) : null; } } diff --git a/src/compiler/compile/render_dom/wrappers/Element/index.ts b/src/compiler/compile/render_dom/wrappers/Element/index.ts index 2e35f0271f..f740560bcd 100644 --- a/src/compiler/compile/render_dom/wrappers/Element/index.ts +++ b/src/compiler/compile/render_dom/wrappers/Element/index.ts @@ -868,6 +868,10 @@ export default class ElementWrapper extends Wrapper { block.chunks.destroy.push(b`if (detaching && ${outro_name}) ${outro_name}.end();`); } } + + if ((intro && intro.expression && intro.expression.dependencies.size) || (outro && outro.expression && outro.expression.dependencies.size)) { + block.maintain_context = true; + } } add_animation(block: Block) { diff --git a/test/css/samples/child-combinator/expected.css b/test/css/samples/child-combinator/expected.css new file mode 100644 index 0000000000..5d50ae16d7 --- /dev/null +++ b/test/css/samples/child-combinator/expected.css @@ -0,0 +1 @@ +main.svelte-xyz button.svelte-xyz.svelte-xyz{background-color:red}main.svelte-xyz div.svelte-xyz>button.svelte-xyz{background-color:blue} \ No newline at end of file diff --git a/test/css/samples/child-combinator/input.svelte b/test/css/samples/child-combinator/input.svelte new file mode 100644 index 0000000000..9d5d8d27e0 --- /dev/null +++ b/test/css/samples/child-combinator/input.svelte @@ -0,0 +1,14 @@ + +
+
+ +
+
\ No newline at end of file diff --git a/test/css/samples/unused-selector-child-combinator/_config.js b/test/css/samples/unused-selector-child-combinator/_config.js new file mode 100644 index 0000000000..becf382147 --- /dev/null +++ b/test/css/samples/unused-selector-child-combinator/_config.js @@ -0,0 +1,45 @@ +export default { + warnings: [ + { + code: "css-unused-selector", + message: 'Unused CSS selector "article > *"', + frame: ` + 1: + +
+

+ Svelte REPLs are svelte. +

+
\ No newline at end of file diff --git a/test/runtime/samples/transition-js-args-dynamic/_config.js b/test/runtime/samples/transition-js-args-dynamic/_config.js new file mode 100644 index 0000000000..513a17486a --- /dev/null +++ b/test/runtime/samples/transition-js-args-dynamic/_config.js @@ -0,0 +1,15 @@ +export default { + test({ assert, component, target, window, raf }) { + component.visible = true; + + const div = target.querySelector('div'); + + assert.equal(div.value, 0); + + raf.tick(200); + + div.value = 'test'; + component.visible = false; + assert.equal(div.value, 'test'); + } +}; diff --git a/test/runtime/samples/transition-js-args-dynamic/main.svelte b/test/runtime/samples/transition-js-args-dynamic/main.svelte new file mode 100644 index 0000000000..1bb149de32 --- /dev/null +++ b/test/runtime/samples/transition-js-args-dynamic/main.svelte @@ -0,0 +1,17 @@ + + +{#if visible} +
+{/if} \ No newline at end of file