XUO/SWE-PolyBench huggingface dataset:
Repository: sveltejs/svelte (JavaScript) — Bug Fix

Issue:
Parser does not accept if or each block argument in parentheses
Attempting to parse `{{#if (condition)}}...{{/if}}` results in an `Expected }}` parsing error at the `)`. And attempting to parse `{{#each (list) as item}}...{{/each}}` results in an `Expected as` parsing error at the `)`.


Discussion:
Looks like this affects regular mustaches as well. `{{(a)}}` fails to parse.

Not sure whether this is a bug in Acorn, or just something about their API I'm not understanding. `acorn.parseExpressionAt('{{(a)}}', 2)` returns `{ type: 'Identifier', start: 3, end: 4, name: 'a' }`. I suppose this makes sense from Acorn's point of view, but it's a bit unfortunate in this case.
This can be addressed with the `{ preserveParens: true }` option in Acorn. This doesn't appear to have any ill effects. I'll submit a PR shortly.

Resolving patch:
diff --git a/src/parse/read/expression.js b/src/parse/read/expression.js
--- a/src/parse/read/expression.js
+++ b/src/parse/read/expression.js
@@ -34,7 +34,7 @@ export default function readExpression ( parser ) {
 	parser.index = start;
 
 	try {
-		const node = parseExpressionAt( parser.template, parser.index );
+		const node = parseExpressionAt( parser.template, parser.index, { preserveParens: true } );
 		parser.index = node.end;
 
 		return node;


Test patch:
diff --git a/test/runtime/samples/paren-wrapped-expressions/_config.js b/test/runtime/samples/paren-wrapped-expressions/_config.js
new file mode 100644
--- /dev/null
+++ b/test/runtime/samples/paren-wrapped-expressions/_config.js
@@ -0,0 +1,16 @@
+export default {
+	data: {
+		a: 'foo',
+		b: true,
+		c: [ 1, 2, 3 ],
+	},
+
+	html: `
+		<span>foo</span>
+		<span class="foo"></span>
+		<span>true</span>
+		<span>1</span>
+		<span>2</span>
+		<span>3</span>
+	`
+};
diff --git a/test/runtime/samples/paren-wrapped-expressions/main.html b/test/runtime/samples/paren-wrapped-expressions/main.html
new file mode 100644
--- /dev/null
+++ b/test/runtime/samples/paren-wrapped-expressions/main.html
@@ -0,0 +1,8 @@
+<span>{{ (a) }}</span>
+<span class='{{ (a) }}'></span>
+{{#if (b) }}
+	<span>true</span>
+{{/if}}
+{{#each (c) as x}}
+	<span>{{x}}</span>
+{{/each}}
Repository: sveltejs/svelte (JavaScript) — Bug Fix

Issue:
Unnecessary error during build: "invalid callee"
I'm adding some methods at instantiation-time, ala #284.

This now causes an error at build-time: `Error: '[method name]' is an invalid callee (should be one of this.*, event.*, set, fire, destroy, complete or restore) while parsing file: [filename]`

This should probably just be a warning.


Discussion:

Resolving patch:
diff --git a/src/validate/html/validateEventHandler.js b/src/validate/html/validateEventHandler.js
--- a/src/validate/html/validateEventHandler.js
+++ b/src/validate/html/validateEventHandler.js
@@ -31,5 +31,5 @@ export default function validateEventHandlerCallee ( validator, attribute ) {
 		message += `. '${callee.name}' exists on 'helpers', did you put it in the wrong place?`;
 	}
 
-	validator.error( message, start );
-}
\ No newline at end of file
+	validator.warn( message, start );
+}


Test patch:
diff --git a/test/validator/samples/method-nonexistent-helper/errors.json b/test/validator/samples/method-nonexistent-helper/warnings.json
similarity index 100%
rename from test/validator/samples/method-nonexistent-helper/errors.json
rename to test/validator/samples/method-nonexistent-helper/warnings.json
diff --git a/test/validator/samples/method-nonexistent/errors.json b/test/validator/samples/method-nonexistent/warnings.json
similarity index 100%
rename from test/validator/samples/method-nonexistent/errors.json
rename to test/validator/samples/method-nonexistent/warnings.json
diff --git a/test/validator/samples/window-event-invalid/errors.json b/test/validator/samples/window-event-invalid/warnings.json
similarity index 100%
rename from test/validator/samples/window-event-invalid/errors.json
rename to test/validator/samples/window-event-invalid/warnings.json
Repository: sveltejs/svelte (JavaScript) — Security

Issue:
Unsafe characters in event names
From @stalkerg - [chat](https://gitter.im/sveltejs/svelte?at=592fc1c0631b8e4e6132c526)

Handler names are being generated from the event name without sanitizing it first.


Discussion:

Resolving patch:
diff --git a/src/generators/dom/visitors/Element/EventHandler.ts b/src/generators/dom/visitors/Element/EventHandler.ts
--- a/src/generators/dom/visitors/Element/EventHandler.ts
+++ b/src/generators/dom/visitors/Element/EventHandler.ts
@@ -47,9 +47,7 @@ export default function visitEventHandler ( generator: DomGenerator, block: Bloc
 
 	// get a name for the event handler that is globally unique
 	// if hoisted, locally unique otherwise
-	const handlerName = shouldHoist ?
-		generator.getUniqueName( `${name}_handler` ) :
-		block.getUniqueName( `${name}_handler` );
+	const handlerName = ( shouldHoist ? generator : block ).getUniqueName( `${name.replace( /[^a-zA-Z0-9_$]/g, '_' )}_handler` );
 
 	// create the handler body
 	const handlerBody = deindent`
@@ -71,7 +69,7 @@ export default function visitEventHandler ( generator: DomGenerator, block: Bloc
 		`;
 
 	if ( shouldHoist ) {
-		generator.blocks.push({
+		generator.blocks.push(<Block>{
 			render: () => handler
 		});
 	} else {
@@ -91,4 +89,4 @@ export default function visitEventHandler ( generator: DomGenerator, block: Bloc
 			${generator.helper( 'removeEventListener' )}( ${state.parentNode}, '${name}', ${handlerName} );
 		` );
 	}
-}
\ No newline at end of file
+}


Test patch:
diff --git a/test/runtime/samples/event-handler-sanitize/_config.js b/test/runtime/samples/event-handler-sanitize/_config.js
new file mode 100644
--- /dev/null
+++ b/test/runtime/samples/event-handler-sanitize/_config.js
@@ -0,0 +1,21 @@
+export default {
+	html: `
+		<div>toggle</div>
+	`,
+
+	test ( assert, component, target, window ) {
+		const div = target.querySelector( 'div' );
+		const event = new window.MouseEvent( 'some-event' );
+
+		div.dispatchEvent( event );
+		assert.htmlEqual( target.innerHTML, `
+			<div>toggle</div>
+			<p>hello!</p>
+		` );
+
+		div.dispatchEvent( event );
+		assert.htmlEqual( target.innerHTML, `
+			<div>toggle</div>
+		` );
+	}
+};
diff --git a/test/runtime/samples/event-handler-sanitize/main.html b/test/runtime/samples/event-handler-sanitize/main.html
new file mode 100644
--- /dev/null
+++ b/test/runtime/samples/event-handler-sanitize/main.html
@@ -0,0 +1,5 @@
+<div on:some-event='set({ visible: !visible })'>toggle</div>
+
+{{#if visible}}
+	<p>hello!</p>
+{{/if}}
Repository: sveltejs/svelte (JavaScript) — Bug Fix

Issue:
Fix for @ disappearing in CSS breaks colours CSS :(
It appears that the fix for `@` in CSS stops colours being rendered correctly.

I'm seeing:
```
    background-color: \#009fdf;
    border-bottom: 3px solid \#02719e;
```

rendered in my browser, and all my colours have disappeared.

Reproduction - inspect the `h1` element to see the broken CSS:
https://svelte.technology/repl?version=1.26.0&gist=69efbf45d04be6b8f3117cc5fa7025c8


Discussion:
oh no! sorry about that — not in a position to fix it right now, but will prioritise it as soon as I am
Is the svelte website down for anyone else? repl link brings me to a zeit.co page.
Ugh, yeah — just merged a PR on svelte.technology, and that triggered a redeploy (CI). It's supposed to only alias after a successful deploy, must be improperly configured. No idea why it's taking so long to build — now flakes out like this sometimes. I'll try deploying from this machine instead.
Fixed now
> Fixed now

(the website, not this issue!)



Resolving patch:
diff --git a/src/generators/dom/index.ts b/src/generators/dom/index.ts
--- a/src/generators/dom/index.ts
+++ b/src/generators/dom/index.ts
@@ -269,8 +269,9 @@ export default function dom(
 
 	let result = builder
 		.toString()
-		.replace(/(\\\\)?@(\w*)/g, (match: string, escaped: string, name: string) => {
+		.replace(/(\\\\)?([@#])(\w*)/g, (match: string, escaped: string, sigil: string, name: string) => {
 			if (escaped) return match.slice(2);
+			if (sigil !== '@') return match;
 
 			if (name in shared) {
 				if (options.dev && `${name}Dev` in shared) name = `${name}Dev`;


Test patch:
diff --git a/test/runtime/samples/css/Widget.html b/test/runtime/samples/css/Widget.html
--- a/test/runtime/samples/css/Widget.html
+++ b/test/runtime/samples/css/Widget.html
@@ -2,6 +2,6 @@
 
 <style>
 	p {
-		color: red;
+		color: #f00;
 	}
 </style>
diff --git a/test/runtime/samples/css/_config.js b/test/runtime/samples/css/_config.js
--- a/test/runtime/samples/css/_config.js
+++ b/test/runtime/samples/css/_config.js
@@ -3,6 +3,6 @@ export default {
 		const [ control, test ] = target.querySelectorAll( 'p' );
 
 		assert.equal( window.getComputedStyle( control ).color, '' );
-		assert.equal( window.getComputedStyle( test ).color, 'red' );
+		assert.equal( window.getComputedStyle( test ).color, 'rgb(255, 0, 0)' );
 	}
 };
Repository: sveltejs/svelte (JavaScript) — Bug Fix

Issue:
CSS @media tags compiled incorrectly
<!--
Thanks for raising an issue! (For *questions*, we recommend instead using https://stackoverflow.com and adding the 'svelte' tag.)

To help us help you, if you've found a bug please consider the following:

* If you can demonstrate the bug using https://svelte.technology/repl, please do.
* If that's not possible, we recommend creating a small repo that illustrates the problem.
* Make sure you include information about the browser, and which version of Svelte you're using

Reproductions should be small, self-contained, correct examples – http://sscce.org.

Occasionally, this won't be possible, and that's fine – we still appreciate you raising the issue. But please understand that Svelte is run by unpaid volunteers in their free time, and issues that follow these instructions will get fixed faster.

If you have a stack trace to include, we recommend putting inside a `<details>` block for the sake of the thread's readability:

<details>
  <summary>Stack trace</summary>

  Stack trace goes here...
</details>
-->
ISSUE:
`@media` blocks are compiled such that the `@media` tag and any successive word have no space between. Browsers then throw away the erroneous block.

For example,
```
@media only screen and (min-width: 42em) {...}
```
compiles to
```
'...@mediaonly screen and (min-width: 42em) {...}...'
```

REPRO/REFERENCE:
https://gist.github.com/anonymous/3ae1fefbef1a4fe1deb280a7654fa3c3


Discussion:
Current workaround: Avoid using words; use only the parenthesized condition. Browsers will treat the parentheses as a word boundary.
For example:
```
@media (min-width: 42em) {}
```

Resolving patch:
diff --git a/src/css/Stylesheet.ts b/src/css/Stylesheet.ts
--- a/src/css/Stylesheet.ts
+++ b/src/css/Stylesheet.ts
@@ -144,7 +144,8 @@ class Atrule {
 
 	minify(code: MagicString, cascade: boolean) {
 		if (this.node.name === 'media') {
-			let c = this.node.start + 6;
+			const expressionChar = code.original[this.node.expression.start];
+			let c = this.node.start + (expressionChar === '(' ? 6 : 7);
 			if (this.node.expression.start > c) code.remove(c, this.node.expression.start);
 
 			this.node.expression.children.forEach((query: Node) => {


Test patch:
diff --git a/test/css/samples/media-query-word/expected.css b/test/css/samples/media-query-word/expected.css
new file mode 100644
--- /dev/null
+++ b/test/css/samples/media-query-word/expected.css
@@ -0,0 +1 @@
+@media only screen and (min-width: 400px){div[svelte-xyz],[svelte-xyz] div{color:red}}
\ No newline at end of file
diff --git a/test/css/samples/media-query-word/input.html b/test/css/samples/media-query-word/input.html
new file mode 100644
--- /dev/null
+++ b/test/css/samples/media-query-word/input.html
@@ -0,0 +1,9 @@
+<div>hello</div>
+
+<style>
+	@media only screen and (min-width: 400px) {
+		div {
+			color: red;
+		}
+	}
+</style>
\ No newline at end of file
Repository: sveltejs/svelte (JavaScript) — Bug Fix

Issue:
CSS selector removal causing style errors
[REPL](https://svelte.technology/repl?version=1.31.0&gist=ad2b365b960c0273a8565114faebcf28):

```html
<!--<p class='foo'>foo</p>-->
<p class='bar'>bar</p>
<p class='baz'>baz</p>

<style>
	.foo, .bar, .baz {
		color: red;
	}
</style>
```

The `.foo` gets removed, but not the following comma, so this is the resulting broken CSS:

```css
,.bar[svelte-680739708],.baz[svelte-680739708]{color:red}
```


Discussion:

Resolving patch:
diff --git a/src/css/Stylesheet.ts b/src/css/Stylesheet.ts
--- a/src/css/Stylesheet.ts
+++ b/src/css/Stylesheet.ts
@@ -30,15 +30,19 @@ class Rule {
 
 	minify(code: MagicString, cascade: boolean) {
 		let c = this.node.start;
+		let started = false;
+
 		this.selectors.forEach((selector, i) => {
 			if (cascade || selector.used) {
-				const separator = i > 0 ? ',' : '';
+				const separator = started ? ',' : '';
 				if ((selector.node.start - c) > separator.length) {
 					code.overwrite(c, selector.node.start, separator);
 				}
 
 				if (!cascade) selector.minify(code);
 				c = selector.node.end;
+
+				started = true;
 			}
 		});
 


Test patch:
diff --git a/test/css/samples/unused-selector-leading/_config.js b/test/css/samples/unused-selector-leading/_config.js
new file mode 100644
--- /dev/null
+++ b/test/css/samples/unused-selector-leading/_config.js
@@ -0,0 +1,39 @@
+export default {
+	cascade: false,
+
+	warnings: [
+		{
+			filename: "SvelteComponent.html",
+			message: "Unused CSS selector",
+			loc: {
+				line: 4,
+				column: 1
+			},
+			pos: 34,
+			frame: `
+				2:
+				3: <style>
+				4:   .foo, .bar, .baz {
+				     ^
+				5:     color: red;
+				6:   }`
+		},
+
+		{
+			filename: "SvelteComponent.html",
+			message: "Unused CSS selector",
+			loc: {
+				line: 4,
+				column: 13
+			},
+			pos: 46,
+			frame: `
+				2:
+				3: <style>
+				4:   .foo, .bar, .baz {
+				                 ^
+				5:     color: red;
+				6:   }`
+		}
+	]
+};
\ No newline at end of file
diff --git a/test/css/samples/unused-selector-leading/expected.css b/test/css/samples/unused-selector-leading/expected.css
new file mode 100644
--- /dev/null
+++ b/test/css/samples/unused-selector-leading/expected.css
@@ -0,0 +1 @@
+.bar[svelte-xyz]{color:red}
\ No newline at end of file
diff --git a/test/css/samples/unused-selector-leading/expected.html b/test/css/samples/unused-selector-leading/expected.html
new file mode 100644
--- /dev/null
+++ b/test/css/samples/unused-selector-leading/expected.html
@@ -0,0 +1 @@
+<div svelte-xyz="" class="bar"></div>
\ No newline at end of file
diff --git a/test/css/samples/unused-selector-leading/input.html b/test/css/samples/unused-selector-leading/input.html
new file mode 100644
--- /dev/null
+++ b/test/css/samples/unused-selector-leading/input.html
@@ -0,0 +1,7 @@
+<div class='bar'></div>
+
+<style>
+	.foo, .bar, .baz {
+		color: red;
+	}
+</style>
\ No newline at end of file
Repository: sveltejs/svelte (JavaScript) — Bug Fix

Issue:
Warn/error if transition directives are applied to component
Via https://github.com/sveltejs/svelte-transitions/issues/4


Discussion:

Resolving patch:
diff --git a/src/validate/html/validateElement.ts b/src/validate/html/validateElement.ts
--- a/src/validate/html/validateElement.ts
+++ b/src/validate/html/validateElement.ts
@@ -116,6 +116,10 @@ export default function validateElement(validator: Validator, node: Node, refs:
 		} else if (attribute.type === 'EventHandler') {
 			validateEventHandler(validator, attribute, refCallees);
 		} else if (attribute.type === 'Transition') {
+			if (isComponent) {
+				validator.error(`Transitions can only be applied to DOM elements, not components`, attribute.start);
+			}
+
 			const bidi = attribute.intro && attribute.outro;
 
 			if (hasTransition) {


Test patch:
diff --git a/test/validator/samples/transition-on-component/errors.json b/test/validator/samples/transition-on-component/errors.json
new file mode 100644
--- /dev/null
+++ b/test/validator/samples/transition-on-component/errors.json
@@ -0,0 +1,8 @@
+[{
+	"message": "Transitions can only be applied to DOM elements, not components",
+	"loc": {
+		"line": 1,
+		"column": 8
+	},
+	"pos": 8
+}]
\ No newline at end of file
diff --git a/test/validator/samples/transition-on-component/input.html b/test/validator/samples/transition-on-component/input.html
new file mode 100644
--- /dev/null
+++ b/test/validator/samples/transition-on-component/input.html
@@ -0,0 +1,15 @@
+<Widget in:foo/>
+
+<script>
+	import Widget from './Widget.html';
+
+	export default {
+		components: {
+			Widget
+		},
+
+		transitions: {
+			foo() {}
+		}
+	};
+</script>
\ No newline at end of file
Repository: sveltejs/svelte (JavaScript) — Bug Fix

Issue:
CSS variables cause build failure
Setting a CSS variable in a `<style>` section of a svelte template triggers a build error:

```html
<style>
.foo {  --test: 10; }
</style>
```
```
Module build failed: Error: TypeError: Cannot read property '0' of undefined
```

- [**repl link**](https://svelte.technology/repl?version=1.29.0&gist=85a1cead27ae3861081a7ccc406181d9)

I don't have any experience using CSS variables, but it seems like this should work.


Discussion:
[Here's how css-tree parses that.](https://astexplorer.net/#/gist/244e2fb4da940df52bf0f4b94277db44/cec0e01c3dd7b6102fa42c4919e413c26c785180) The value of the custom property declaration has `type: 'Raw'`, and has no `children` array, and so an error is thrown [here](https://github.com/sveltejs/svelte/blob/8dd23b81df5bbbb5b549ea9cfe9e2a4818a21740/src/css/Stylesheet.ts#L124). We could try skipping minifying the value in that case - or maybe we could just `.trim()` it. I've never used CSS custom properties either, so I haven't thought about what sorts of transforming is safe to do on the value.
Skipping or `.trim()` both seem like reasonable places to start. :)

(My actual use case involves setting a variable to length values, and I think the other common use case is a color value. Seems like there probably isn't a huge amount to win in trying to minify it.)

Resolving patch:
diff --git a/src/css/Stylesheet.ts b/src/css/Stylesheet.ts
--- a/src/css/Stylesheet.ts
+++ b/src/css/Stylesheet.ts
@@ -135,10 +135,15 @@ class Declaration {
 
 	minify(code: MagicString) {
 		const c = this.node.start + this.node.property.length;
-		const first = this.node.value.children[0];
+		const first = this.node.value.children  ?
+			this.node.value.children[0] :
+			this.node.value;
 
-		if (first.start - c > 1) {
-			code.overwrite(c, first.start, ':');
+		let start = first.start;
+		while (/\s/.test(code.original[start])) start += 1;
+
+		if (start - c > 1) {
+			code.overwrite(c, start, ':');
 		}
 	}
 }


Test patch:
diff --git a/test/css/samples/css-vars/expected.css b/test/css/samples/css-vars/expected.css
new file mode 100644
--- /dev/null
+++ b/test/css/samples/css-vars/expected.css
@@ -0,0 +1 @@
+div[svelte-xyz],[svelte-xyz] div{--test:10}
\ No newline at end of file
diff --git a/test/css/samples/css-vars/input.html b/test/css/samples/css-vars/input.html
new file mode 100644
--- /dev/null
+++ b/test/css/samples/css-vars/input.html
@@ -0,0 +1,7 @@
+<div></div>
+
+<style>
+	div {
+		--test: 10;
+	}
+</style>
\ No newline at end of file
Repository: sveltejs/svelte (JavaScript) — Bug Fix

Issue:
[foo=bar] crashes
[REPL](https://svelte.technology/repl?version=1.34.0&gist=27d1a1b7aeb1d0fe4c5240cda1c08dad). `[foo='bar']` is fine, but `[foo=bar]` is not.


Discussion:

Resolving patch:
diff --git a/src/css/Selector.ts b/src/css/Selector.ts
--- a/src/css/Selector.ts
+++ b/src/css/Selector.ts
@@ -160,7 +160,7 @@ function applySelector(blocks: Block[], node: Node, stack: Node[], toEncapsulate
 		}
 
 		else if (selector.type === 'AttributeSelector') {
-			if (!attributeMatches(node, selector.name.name, selector.value && unquote(selector.value.value), selector.operator, selector.flags)) return false;
+			if (!attributeMatches(node, selector.name.name, selector.value && unquote(selector.value), selector.operator, selector.flags)) return false;
 		}
 
 		else if (selector.type === 'TypeSelector') {
@@ -245,10 +245,13 @@ function isDynamic(value: Node) {
 	return value.length > 1 || value[0].type !== 'Text';
 }
 
-function unquote(str: string) {
+function unquote(value: Node) {
+	if (value.type === 'Identifier') return value.name;
+	const str = value.value;
 	if (str[0] === str[str.length - 1] && str[0] === "'" || str[0] === '"') {
 		return str.slice(1, str.length - 1);
 	}
+	return str;
 }
 
 class Block {


Test patch:
diff --git a/test/css/samples/attribute-selector-unquoted/_config.js b/test/css/samples/attribute-selector-unquoted/_config.js
new file mode 100644
--- /dev/null
+++ b/test/css/samples/attribute-selector-unquoted/_config.js
@@ -0,0 +1,3 @@
+export default {
+	cascade: false
+};
\ No newline at end of file
diff --git a/test/css/samples/attribute-selector-unquoted/expected.css b/test/css/samples/attribute-selector-unquoted/expected.css
new file mode 100644
--- /dev/null
+++ b/test/css/samples/attribute-selector-unquoted/expected.css
@@ -0,0 +1 @@
+[foo=bar][svelte-xyz]{color:red}
\ No newline at end of file
diff --git a/test/css/samples/attribute-selector-unquoted/input.html b/test/css/samples/attribute-selector-unquoted/input.html
new file mode 100644
--- /dev/null
+++ b/test/css/samples/attribute-selector-unquoted/input.html
@@ -0,0 +1,7 @@
+<div foo='bar'></div>
+
+<style>
+	[foo=bar] {
+		color: red;
+	}
+</style>
\ No newline at end of file
Repository: sveltejs/svelte (JavaScript) — Bug Fix

Issue:
Observe work incorrect if component has bindings from parent
Subj. REPL example: https://svelte.technology/repl?version=1.34.0&gist=f9ea84a2f4f0c6c1a2745244023e8ae8

just try change field.

Example with directly observed from parent:
https://svelte.technology/repl?version=1.34.0&gist=43722dc52a63412f3f89726b5aecc16a


Discussion:

Resolving patch:
diff --git a/src/generators/dom/visitors/Component.ts b/src/generators/dom/visitors/Component.ts
--- a/src/generators/dom/visitors/Component.ts
+++ b/src/generators/dom/visitors/Component.ts
@@ -185,7 +185,7 @@ export default function visitComponent(
 				_bind: function(changed, childState) {
 					var state = #component.get(), newState = {};
 					${setParentFromChildOnChange}
-					${name_updating} = changed;
+					${name_updating} = @assign({}, changed);
 					#component._set(newState);
 					${name_updating} = {};
 				}


Test patch:
diff --git a/test/runtime/samples/observe-binding-ignores-unchanged/Nested.html b/test/runtime/samples/observe-binding-ignores-unchanged/Nested.html
new file mode 100644
--- /dev/null
+++ b/test/runtime/samples/observe-binding-ignores-unchanged/Nested.html
@@ -0,0 +1 @@
+<input type="number" bind:value="field1">
\ No newline at end of file
diff --git a/test/runtime/samples/observe-binding-ignores-unchanged/_config.js b/test/runtime/samples/observe-binding-ignores-unchanged/_config.js
new file mode 100644
--- /dev/null
+++ b/test/runtime/samples/observe-binding-ignores-unchanged/_config.js
@@ -0,0 +1,28 @@
+export default {
+	html: `
+		<input type='number'>
+		<p>field1: 1</p>
+		<p>field2: 2</p>
+	`,
+
+	test(assert, component, target, window) {
+		let triggered = false;
+		component.refs.nested.observe('field2', () => {
+			triggered = true;
+		}, { init: false });
+
+		const input = target.querySelector('input');
+		const event = new window.Event('input');
+
+		input.value = 3;
+		input.dispatchEvent(event); // will throw error if observer fires incorrectly
+
+		assert.ok(!triggered);
+
+		assert.htmlEqual(target.innerHTML, `
+			<input type='number'>
+			<p>field1: 3</p>
+			<p>field2: 2</p>
+		`);
+	}
+};
\ No newline at end of file
diff --git a/test/runtime/samples/observe-binding-ignores-unchanged/main.html b/test/runtime/samples/observe-binding-ignores-unchanged/main.html
new file mode 100644
--- /dev/null
+++ b/test/runtime/samples/observe-binding-ignores-unchanged/main.html
@@ -0,0 +1,21 @@
+<Nested ref:nested bind:field1="myObject.field1" bind:field2="myObject.field2" />
+<p>field1: {{myObject.field1}}</p>
+<p>field2: {{myObject.field2}}</p>
+
+<script>
+	import Nested from './Nested.html';
+
+	export default {
+		components: {
+			Nested
+		},
+		data() {
+			return {
+				myObject: {
+					field1: 1,
+					field2: 2
+				}
+			};
+		}
+	};
+</script>
\ No newline at end of file
Repository: sveltejs/svelte (JavaScript) — Bug Fix

Issue:
Each blocks misbehaving inside SVGs
[REPL](https://svelte.technology/repl?version=1.39.1&gist=7bac07e911a5116432ff6436ba445916). Checking the checkbox causes the extra ticks to be rendered in front of the `<rect>` elements, incorrectly.


Discussion:

Resolving patch:
diff --git a/src/generators/dom/preprocess.ts b/src/generators/dom/preprocess.ts
--- a/src/generators/dom/preprocess.ts
+++ b/src/generators/dom/preprocess.ts
@@ -417,6 +417,8 @@ function preprocessChildren(
 		const preprocessor = preprocessors[child.type];
 		if (preprocessor) preprocessor(generator, block, state, child, inEachBlock, elementStack, componentStack, stripWhitespace, cleaned[i + 1] || nextSibling);
 
+		if (child.shouldSkip) return;
+
 		if (lastChild) lastChild.next = child;
 		child.prev = lastChild;
 


Test patch:
diff --git a/test/runtime/samples/svg-each-block-anchor/_config.js b/test/runtime/samples/svg-each-block-anchor/_config.js
new file mode 100644
--- /dev/null
+++ b/test/runtime/samples/svg-each-block-anchor/_config.js
@@ -0,0 +1,25 @@
+export default {
+	data: {
+		foo: ['a'],
+		bar: ['c']
+	},
+
+	html: `
+		<svg>
+			<g class='foo'>a</g>
+			<g class='bar'>c</g>
+		</svg>
+	`,
+
+	test(assert, component, target) {
+		component.set({ foo: ['a', 'b'] });
+
+		assert.htmlEqual(target.innerHTML, `
+			<svg>
+				<g class='foo'>a</g>
+				<g class='foo'>b</g>
+				<g class='bar'>c</g>
+			</svg>
+		`);
+	}
+};
diff --git a/test/runtime/samples/svg-each-block-anchor/main.html b/test/runtime/samples/svg-each-block-anchor/main.html
new file mode 100644
--- /dev/null
+++ b/test/runtime/samples/svg-each-block-anchor/main.html
@@ -0,0 +1,9 @@
+<svg>
+	{{#each foo as x}}
+		<g class='foo'></g>
+	{{/each}}
+
+	{{#each bar as y}}
+		<g class='bar'></g>
+	{{/each}}
+</svg>
\ No newline at end of file
Repository: sveltejs/svelte (JavaScript) — Bug Fix

Issue:
Attribute name only (no value) CSS selector throws if html attribute has a value.
This is fine:

```html
<button foo></button>

<style>
button[foo] {}
</style>
```

But this throws `TypeError: operators[operator] is not a function`:

```html
<button foo="bar"></button>

<style>
button[foo] {}
</style>
```

[REPL](https://svelte.technology/repl?version=1.41.1&gist=9ba8d98eb5b84696a61aa4caca984923)

<details>
  <summary>Stack trace</summary>
    TypeError: operators[operator] is not a function
      at attributeMatches (Selector.ts:228)
      at _loop_1 (Selector.ts:163)
      at applySelector (Selector.ts:141)
      at Selector.apply (Selector.ts:30)
      at Stylesheet.ts:23
      at Array.forEach (<anonymous>)
      at Rule.apply (Stylesheet.ts:23)
      at Stylesheet.apply (Stylesheet.ts:343)
      at Element (preprocess.ts:427)
      at preprocess.ts:482
</details>


Discussion:

Resolving patch:
diff --git a/src/css/Selector.ts b/src/css/Selector.ts
--- a/src/css/Selector.ts
+++ b/src/css/Selector.ts
@@ -224,6 +224,7 @@ function attributeMatches(node: Node, name: string, expectedValue: string, opera
 	if (!attr) return false;
 	if (attr.value === true) return operator === null;
 	if (attr.value.length > 1) return true;
+	if (!expectedValue) return true;
 
 	const pattern = operators[operator](expectedValue, caseInsensitive ? 'i' : '');
 	const value = attr.value[0];


Test patch:
diff --git a/test/css/samples/attribute-selector-only-name/_config.js b/test/css/samples/attribute-selector-only-name/_config.js
new file mode 100644
--- /dev/null
+++ b/test/css/samples/attribute-selector-only-name/_config.js
@@ -0,0 +1,3 @@
+export default {
+	cascade: false
+};
\ No newline at end of file
diff --git a/test/css/samples/attribute-selector-only-name/expected.css b/test/css/samples/attribute-selector-only-name/expected.css
new file mode 100644
--- /dev/null
+++ b/test/css/samples/attribute-selector-only-name/expected.css
@@ -0,0 +1 @@
+[foo][svelte-xyz]{color:red}[baz][svelte-xyz]{color:blue}
\ No newline at end of file
diff --git a/test/css/samples/attribute-selector-only-name/input.html b/test/css/samples/attribute-selector-only-name/input.html
new file mode 100644
--- /dev/null
+++ b/test/css/samples/attribute-selector-only-name/input.html
@@ -0,0 +1,11 @@
+<div foo='bar'></div>
+<div baz></div>
+
+<style>
+	[foo] {
+		color: red;
+	}
+	[baz] {
+		color: blue;
+	}
+</style>
Repository: sveltejs/svelte (JavaScript) — Bug Fix

Issue:
Each block inside slotted content does not get updated
I ran across a slight issue with each blocks and slotted content: if the each block outputs directly to a slot, the state updates are not rendered. If the each block is wrapped with an element, it works:

https://svelte.technology/repl?version=1.41.3&gist=64a25260abf9c36de5bb0b4d244499e7


Discussion:

Resolving patch:
diff --git a/src/generators/dom/visitors/EachBlock.ts b/src/generators/dom/visitors/EachBlock.ts
--- a/src/generators/dom/visitors/EachBlock.ts
+++ b/src/generators/dom/visitors/EachBlock.ts
@@ -21,7 +21,7 @@ export default function visitEachBlock(
 	const iterations = block.getUniqueName(`${each}_blocks`);
 	const params = block.params.join(', ');
 
-	const needsAnchor = node.next ? !isDomNode(node.next, generator) : !state.parentNode;
+	const needsAnchor = node.next ? !isDomNode(node.next, generator) : !state.parentNode || !isDomNode(node.parent, generator);
 	const anchor = needsAnchor
 		? block.getUniqueName(`${each}_anchor`)
 		: (node.next && node.next.var) || 'null';
@@ -219,7 +219,7 @@ function keyed(
 	`);
 
 	const dynamic = node._block.hasUpdateMethod;
-	const parentNode = state.parentNode || `${anchor}.parentNode`;
+	const parentNode = isDomNode(node.parent, generator) ? node.parent.var : `${anchor}.parentNode`;
 
 	let destroy;
 	if (node._block.hasOutroMethod) {
@@ -414,7 +414,7 @@ function unkeyed(
 		.map(dependency => `changed.${dependency}`)
 		.join(' || ');
 
-	const parentNode = state.parentNode || `${anchor}.parentNode`;
+	const parentNode = isDomNode(node.parent, generator) ? node.parent.var : `${anchor}.parentNode`;
 
 	if (condition !== '') {
 		const forLoopBody = node._block.hasUpdateMethod


Test patch:
diff --git a/test/runtime/samples/component-slot-each-block/Nested.html b/test/runtime/samples/component-slot-each-block/Nested.html
new file mode 100644
--- /dev/null
+++ b/test/runtime/samples/component-slot-each-block/Nested.html
@@ -0,0 +1,3 @@
+<div>
+	<slot/>
+</div>
\ No newline at end of file
diff --git a/test/runtime/samples/component-slot-each-block/_config.js b/test/runtime/samples/component-slot-each-block/_config.js
new file mode 100644
--- /dev/null
+++ b/test/runtime/samples/component-slot-each-block/_config.js
@@ -0,0 +1,24 @@
+export default {
+	data: {
+		things: [1, 2, 3]
+	},
+
+	html: `
+		<div>
+			<span>1</span>
+			<span>2</span>
+			<span>3</span>
+		</div>`,
+
+	test(assert, component, target) {
+		component.set({ things: [1, 2, 3, 4] });
+		assert.htmlEqual(target.innerHTML, `
+			<div>
+				<span>1</span>
+				<span>2</span>
+				<span>3</span>
+				<span>4</span>
+			</div>
+		`);
+	}
+};
diff --git a/test/runtime/samples/component-slot-each-block/main.html b/test/runtime/samples/component-slot-each-block/main.html
new file mode 100644
--- /dev/null
+++ b/test/runtime/samples/component-slot-each-block/main.html
@@ -0,0 +1,13 @@
+<Nested>
+	{{#each things as thing}}
+		<span>{{thing}}</span>
+	{{/each}}
+</Nested>
+
+<script>
+	import Nested from './Nested.html';
+
+	export default {
+		components: { Nested }
+	};
+</script>
\ No newline at end of file
Repository: sveltejs/svelte (JavaScript) — Bug Fix

Issue:
<:Window bind:online/> doesn't work
Not sure how I missed this ([REPL](https://svelte.technology/repl?version=1.42.0&gist=72dd99d984ef7f7e7860d942a11f2e0a)). PR inbound




Discussion:

Resolving patch:
diff --git a/src/validate/html/validateWindow.ts b/src/validate/html/validateWindow.ts
--- a/src/validate/html/validateWindow.ts
+++ b/src/validate/html/validateWindow.ts
@@ -12,6 +12,7 @@ const validBindings = [
 	'outerHeight',
 	'scrollX',
 	'scrollY',
+	'online'
 ];
 
 export default function validateWindow(validator: Validator, node: Node, refs: Map<string, Node[]>, refCallees: Node[]) {


Test patch:
diff --git a/test/validator/samples/window-binding-invalid/errors.json b/test/validator/samples/window-binding-invalid/errors.json
--- a/test/validator/samples/window-binding-invalid/errors.json
+++ b/test/validator/samples/window-binding-invalid/errors.json
@@ -1,5 +1,5 @@
 [{
-	"message": "'potato' is not a valid binding on <:Window> — valid bindings are innerWidth, innerHeight, outerWidth, outerHeight, scrollX or scrollY",
+	"message": "'potato' is not a valid binding on <:Window> — valid bindings are innerWidth, innerHeight, outerWidth, outerHeight, scrollX, scrollY or online",
 	"loc": {
 		"line": 1,
 		"column": 9
diff --git a/test/validator/samples/window-binding-online/errors.json b/test/validator/samples/window-binding-online/errors.json
new file mode 100644
--- /dev/null
+++ b/test/validator/samples/window-binding-online/errors.json
@@ -0,0 +1 @@
+[]
\ No newline at end of file
diff --git a/test/validator/samples/window-binding-online/input.html b/test/validator/samples/window-binding-online/input.html
new file mode 100644
--- /dev/null
+++ b/test/validator/samples/window-binding-online/input.html
@@ -0,0 +1 @@
+<:Window bind:online/>
\ No newline at end of file
Repository: sveltejs/svelte (JavaScript) — Bug Fix

Issue:
Dev mode protection against this.set(<string>) doesn't work
In `dev` mode, svelte wraps `set` calls in `_setDev` which checks to ensure that the first arg is an object, to protect against `this.set("foo", 1)`. Which is great.

Except it doesn't currently work due to a quirk of the `set()` implementation.

[`set(newState)` uses `this._set(assign({}, newState))`](https://github.com/sveltejs/svelte/blob/master/src/shared/index.js#L138), which is calling out to the [`assign()`](https://github.com/sveltejs/svelte/blob/master/src/shared/utils.js#L3) function. So far so good.

Except that when the `newState` value is a string, `assign()` doesn't handle it very well.

So `_setDev()` ends up getting passed a nonsense object, which bypasses the check for a string value and the error is never shown.

```html
<h1>{{key}}</h1>
<script>
export default {
   data() {
        return { key : false };
    },
    oncreate() {
        this.set("key", true);
    }
}
</script>
```

Will end up invoking `_setDev()` with an arg like `{ 0 : "k", 1 : "e", 2 : "y" }`, which passes the `typeof` check and then does nothing useful.


Discussion:

Resolving patch:
diff --git a/src/shared/index.js b/src/shared/index.js
--- a/src/shared/index.js
+++ b/src/shared/index.js
@@ -165,15 +165,15 @@ export function _set(newState) {
 	}
 }
 
-export function _setDev(newState) {
+export function setDev(newState) {
 	if (typeof newState !== 'object') {
 		throw new Error(
-			this._debugName + ' .set was called without an object of data key-values to update.'
+			this._debugName + '.set was called without an object of data key-values to update.'
 		);
 	}
 
 	this._checkReadOnly(newState);
-	_set.call(this, newState);
+	set.call(this, newState);
 }
 
 export function callAll(fns) {
@@ -220,10 +220,10 @@ export var protoDev = {
 	fire: fire,
 	observe: observeDev,
 	on: onDev,
-	set: set,
+	set: setDev,
 	teardown: destroyDev,
 	_recompute: noop,
-	_set: _setDev,
+	_set: _set,
 	_mount: _mount,
 	_unmount: _unmount
 };


Test patch:
diff --git a/test/runtime/samples/dev-warning-bad-set-argument/_config.js b/test/runtime/samples/dev-warning-bad-set-argument/_config.js
new file mode 100644
--- /dev/null
+++ b/test/runtime/samples/dev-warning-bad-set-argument/_config.js
@@ -0,0 +1,7 @@
+export default {
+	dev: true,
+
+	error(assert, error) {
+		assert.equal(error.message, `<Main$>.set was called without an object of data key-values to update.`);
+	}
+};
diff --git a/test/runtime/samples/dev-warning-bad-set-argument/main.html b/test/runtime/samples/dev-warning-bad-set-argument/main.html
new file mode 100644
--- /dev/null
+++ b/test/runtime/samples/dev-warning-bad-set-argument/main.html
@@ -0,0 +1,11 @@
+<script>
+	export default {
+		data() {
+			return { key : false };
+		},
+
+		oncreate() {
+			this.set("key", true);
+		}
+	};
+</script>
\ No newline at end of file
Repository: sveltejs/svelte (JavaScript) — Bug Fix

Issue:
ssr/register should sanitize filenames
This doesn't work:

```js
require('svelte/ssr/register');
const Thing = require('./pages/:thing.html');
```

We get this error:

> options.name must be a valid identifier


Discussion:

Resolving patch:
diff --git a/src/server-side-rendering/register.js b/src/server-side-rendering/register.js
--- a/src/server-side-rendering/register.js
+++ b/src/server-side-rendering/register.js
@@ -26,10 +26,14 @@ function _deregister(extension) {
 
 function _register(extension) {
 	require.extensions[extension] = function(module, filename) {
+		const name = path.basename(filename)
+			.slice(0, -path.extname(filename).length)
+			.replace(/^\d/, '_$&')
+			.replace(/[^a-zA-Z0-9_$]/g, '');
+
 		const options = Object.assign({}, compileOptions, {
 			filename,
-			name: capitalise(path.basename(filename)
-				.replace(new RegExp(`${extension.replace('.', '\\.')}$`), '')),
+			name: capitalise(name),
 			generate: 'ssr'
 		});
 


Test patch:
diff --git a/test/helpers.js b/test/helpers.js
--- a/test/helpers.js
+++ b/test/helpers.js
@@ -175,11 +175,17 @@ function capitalise(str) {
 export function showOutput(cwd, options = {}, s = svelte) {
 	glob.sync('**/*.html', { cwd }).forEach(file => {
 		if (file[0] === '_') return;
+
+		const name = path.basename(file)
+			.slice(0, -path.extname(file).length)
+			.replace(/^\d/, '_$&')
+			.replace(/[^a-zA-Z0-9_$]/g, '');
+
 		const { code } = s.compile(
 			fs.readFileSync(`${cwd}/${file}`, 'utf-8'),
 			Object.assign(options, {
 				filename: file,
-				name: capitalise(path.basename(file).replace(/\.html$/, ''))
+				name: capitalise(name)
 			})
 		);
 
diff --git a/test/server-side-rendering/samples/sanitize-name/@foo.html b/test/server-side-rendering/samples/sanitize-name/@foo.html
new file mode 100644
--- /dev/null
+++ b/test/server-side-rendering/samples/sanitize-name/@foo.html
@@ -0,0 +1 @@
+<p>foo!</p>
\ No newline at end of file
diff --git a/test/server-side-rendering/samples/sanitize-name/_expected.html b/test/server-side-rendering/samples/sanitize-name/_expected.html
new file mode 100644
--- /dev/null
+++ b/test/server-side-rendering/samples/sanitize-name/_expected.html
@@ -0,0 +1 @@
+<p>foo!</p>
\ No newline at end of file
diff --git a/test/server-side-rendering/samples/sanitize-name/main.html b/test/server-side-rendering/samples/sanitize-name/main.html
new file mode 100644
--- /dev/null
+++ b/test/server-side-rendering/samples/sanitize-name/main.html
@@ -0,0 +1,9 @@
+<Foo/>
+
+<script>
+	import Foo from './@foo.html';
+
+	export default {
+		components: { Foo }
+	};
+</script>
\ No newline at end of file
Repository: sveltejs/svelte (JavaScript) — Bug Fix

Issue:
SSR component render() toString method returns undefined
When using `${app.render()}` in a template literal, I get undefined. That seems to be caused by a bug in `toString()`:
```
var result = { head: '', addComponent: addComponent };
...
var html = AddToCart._render(result, state, options);
return {
    html: html,
    head: result.head,
    css: { code: cssCode, map: null },
    toString: function toString() {
        return result.html;                <-- probably should return html
    }
};
```
Workaround: use `${app.render().html}` in template literals.
SSR component render() toString method returns undefined
When using `${app.render()}` in a template literal, I get undefined. That seems to be caused by a bug in `toString()`:
```
var result = { head: '', addComponent: addComponent };
...
var html = AddToCart._render(result, state, options);
return {
    html: html,
    head: result.head,
    css: { code: cssCode, map: null },
    toString: function toString() {
        return result.html;                <-- probably should return html
    }
};
```
Workaround: use `${app.render().html}` in template literals.


Discussion:

Resolving patch:
diff --git a/src/generators/server-side-rendering/index.ts b/src/generators/server-side-rendering/index.ts
--- a/src/generators/server-side-rendering/index.ts
+++ b/src/generators/server-side-rendering/index.ts
@@ -124,7 +124,7 @@ export default function ssr(
 				head: result.head,
 				css: { code: cssCode, map: null },
 				toString() {
-					return result.html;
+					return html;
 				}
 			};
 		}


Test patch:
diff --git a/test/js/samples/ssr-no-oncreate-etc/expected-bundle.js b/test/js/samples/ssr-no-oncreate-etc/expected-bundle.js
--- a/test/js/samples/ssr-no-oncreate-etc/expected-bundle.js
+++ b/test/js/samples/ssr-no-oncreate-etc/expected-bundle.js
@@ -25,7 +25,7 @@ SvelteComponent.render = function(state, options = {}) {
 		head: result.head,
 		css: { code: cssCode, map: null },
 		toString() {
-			return result.html;
+			return html;
 		}
 	};
 };
diff --git a/test/js/samples/ssr-no-oncreate-etc/expected.js b/test/js/samples/ssr-no-oncreate-etc/expected.js
--- a/test/js/samples/ssr-no-oncreate-etc/expected.js
+++ b/test/js/samples/ssr-no-oncreate-etc/expected.js
@@ -27,7 +27,7 @@ SvelteComponent.render = function(state, options = {}) {
 		head: result.head,
 		css: { code: cssCode, map: null },
 		toString() {
-			return result.html;
+			return html;
 		}
 	};
 }
diff --git a/test/server-side-rendering/index.js b/test/server-side-rendering/index.js
--- a/test/server-side-rendering/index.js
+++ b/test/server-side-rendering/index.js
@@ -59,7 +59,11 @@ describe("ssr", () => {
 
 				const data = tryToLoadJson(`${dir}/data.json`);
 
-				const { html, css, head } = component.render(data);
+				const rendered = component.render(data);
+				const { html, css, head } = rendered;
+
+				// rendered.toString() === rendered.html
+				assert.equal(rendered, html);
 
 				fs.writeFileSync(`${dir}/_actual.html`, html);
 				if (css.code) fs.writeFileSync(`${dir}/_actual.css`, css.code);
Repository: sveltejs/svelte (JavaScript) — Bug Fix

Issue:
Two-way data binding issue with dynamic components
REPL: https://svelte.technology/repl?version=1.49.1&gist=7e3783cd296545111c21728d131c1c06

Seems like when you do a two-way binding, it reverts back to the original data when a component is switched.

However, if it is just a one-way data binding, it works as expected, without reverting back to original data on switching.


Discussion:

Resolving patch:
diff --git a/src/generators/nodes/Component.ts b/src/generators/nodes/Component.ts
--- a/src/generators/nodes/Component.ts
+++ b/src/generators/nodes/Component.ts
@@ -256,13 +256,13 @@ export default class Component extends Node {
 				var ${switch_vars.value} = ${snippet};
 
 				function ${switch_vars.props}(${params}) {
+					${statements.length > 0 && statements.join('\n')}
 					return {
 						${componentInitProperties.join(',\n')}
 					};
 				}
 
 				if (${switch_vars.value}) {
-					${statements.length > 0 && statements.join('\n')}
 					var ${name} = new ${expression}(${switch_vars.props}(${params}));
 
 					${beforecreate}


Test patch:
diff --git a/test/runtime/samples/dynamic-component-bindings-recreated/Green.html b/test/runtime/samples/dynamic-component-bindings-recreated/Green.html
new file mode 100644
--- /dev/null
+++ b/test/runtime/samples/dynamic-component-bindings-recreated/Green.html
@@ -0,0 +1 @@
+<p>green {{foo}}</p>
\ No newline at end of file
diff --git a/test/runtime/samples/dynamic-component-bindings-recreated/Red.html b/test/runtime/samples/dynamic-component-bindings-recreated/Red.html
new file mode 100644
--- /dev/null
+++ b/test/runtime/samples/dynamic-component-bindings-recreated/Red.html
@@ -0,0 +1 @@
+<p>red {{foo}}</p>
\ No newline at end of file
diff --git a/test/runtime/samples/dynamic-component-bindings-recreated/_config.js b/test/runtime/samples/dynamic-component-bindings-recreated/_config.js
new file mode 100644
--- /dev/null
+++ b/test/runtime/samples/dynamic-component-bindings-recreated/_config.js
@@ -0,0 +1,29 @@
+export default {
+	data: {
+		x: true,
+		foo: 'one'
+	},
+
+	html: `
+		<p>green one</p>
+	`,
+
+	test(assert, component, target) {
+		component.set({
+			x: false
+		});
+
+		assert.htmlEqual(target.innerHTML, `
+			<p>red one</p>
+		`);
+
+		component.set({
+			x: true,
+			foo: 'two'
+		});
+
+		assert.htmlEqual(target.innerHTML, `
+			<p>green two</p>
+		`);
+	}
+};
\ No newline at end of file
diff --git a/test/runtime/samples/dynamic-component-bindings-recreated/main.html b/test/runtime/samples/dynamic-component-bindings-recreated/main.html
new file mode 100644
--- /dev/null
+++ b/test/runtime/samples/dynamic-component-bindings-recreated/main.html
@@ -0,0 +1,15 @@
+<:Component {x ? Green : Red} bind:foo />
+
+<script>
+	import Green from './Green.html';
+	import Red from './Red.html';
+
+	export default {
+		data() {
+			return {
+				Green,
+				Red
+			};
+		}
+	};
+</script>
\ No newline at end of file
Repository: sveltejs/svelte (JavaScript) — Bug Fix

Issue:
<option> outside of <select> throws error
Using svelte 1.47.2 and 1.45.0.

REPL: https://svelte.technology/repl?version=1.47.2&gist=7d15de2a904b723c8c0395a1dee35df8

When an `<option>` element is not contained in a `<select>` (or any element for that matter), it throws an error as the special handling for `<option>` elements expects the parent to be a `<select>`. While there are few use cases for an option outside of a select, my use case is one where the option element needs its own component space for state subscription purposes.


Discussion:
Interesting, this doesn't happen in 1.44.0: https://svelte.technology/repl?version=1.44.0&gist=d6fadd5e8b755b8d0fb7301d61a727c7

Resolving patch:
diff --git a/src/generators/nodes/Element.ts b/src/generators/nodes/Element.ts
--- a/src/generators/nodes/Element.ts
+++ b/src/generators/nodes/Element.ts
@@ -55,7 +55,7 @@ export default class Element extends Node {
 							attribute.name === 'value'
 						) {
 							let select = this.parent;
-							while (select && select.type !== 'Element' || select.name !== 'select') select = select.parent;
+							while (select && (select.type !== 'Element' || select.name !== 'select')) select = select.parent;
 
 							if (select && select.selectBindingDependencies) {
 								select.selectBindingDependencies.forEach(prop => {


Test patch:
diff --git a/test/runtime/samples/option-without-select/_config.js b/test/runtime/samples/option-without-select/_config.js
new file mode 100644
--- /dev/null
+++ b/test/runtime/samples/option-without-select/_config.js
@@ -0,0 +1,14 @@
+export default {
+	data: {
+		foo: 'hello'
+	},
+
+	html: `<option value='hello'>hello</option>`,
+
+	test(assert, component, target) {
+		component.set({ foo: 'goodbye' });
+		assert.htmlEqual(target.innerHTML, `
+			<option value='goodbye'>goodbye</option>
+		`);
+	}
+};
\ No newline at end of file
diff --git a/test/runtime/samples/option-without-select/main.html b/test/runtime/samples/option-without-select/main.html
new file mode 100644
--- /dev/null
+++ b/test/runtime/samples/option-without-select/main.html
@@ -0,0 +1 @@
+<option value='{{foo}}'>{{foo}}</option>
\ No newline at end of file