diff --git a/src/generators/dom/visitors/attributes/addComponentBinding.js b/src/generators/dom/visitors/attributes/addComponentBinding.js index 5b740aa29f..07ae7fefe8 100644 --- a/src/generators/dom/visitors/attributes/addComponentBinding.js +++ b/src/generators/dom/visitors/attributes/addComponentBinding.js @@ -3,7 +3,7 @@ import flattenReference from '../../../../utils/flattenReference.js'; import getSetter from './binding/getSetter.js'; export default function createBinding ( generator, node, attribute, current, local ) { - const { name } = flattenReference( attribute.value ); + const { name, keypath } = flattenReference( attribute.value ); const { snippet, contexts, dependencies } = generator.contextualise( attribute.value ); if ( dependencies.length > 1 ) throw new Error( 'An unexpected situation arose. Please raise an issue at https://github.com/sveltejs/svelte/issues — thanks!' ); @@ -35,7 +35,7 @@ export default function createBinding ( generator, node, attribute, current, loc prop }); - const setter = getSetter({ current, name, context: '_context', attribute, dependencies, snippet, value: 'value' }); + const setter = getSetter({ current, name, keypath, context: '_context', attribute, dependencies, value: 'value' }); generator.hasComplexBindings = true; diff --git a/src/generators/dom/visitors/attributes/addElementAttributes.js b/src/generators/dom/visitors/attributes/addElementAttributes.js index de0699e4e4..1f1132aa73 100644 --- a/src/generators/dom/visitors/attributes/addElementAttributes.js +++ b/src/generators/dom/visitors/attributes/addElementAttributes.js @@ -184,7 +184,7 @@ export default function addElementAttributes ( generator, node, local ) { local.init.addBlock( deindent` var ${handlerName} = ${generator.alias( 'template' )}.events.${name}.call( ${generator.current.component}, ${local.name}, function ( event ) { ${handlerBody} - }); + }.bind( ${local.name} ) ); ` ); generator.current.builders.teardown.addLine( deindent` diff --git a/src/generators/dom/visitors/attributes/addElementBinding.js b/src/generators/dom/visitors/attributes/addElementBinding.js index ee222dc304..a13d254dfb 100644 --- a/src/generators/dom/visitors/attributes/addElementBinding.js +++ b/src/generators/dom/visitors/attributes/addElementBinding.js @@ -21,7 +21,7 @@ export default function createBinding ( generator, node, attribute, current, loc const value = getBindingValue( generator, local, node, attribute, isMultipleSelect, bindingGroup, type ); const eventName = getBindingEventName( node ); - let setter = getSetter({ current, name, context: '__svelte', attribute, dependencies, snippet, value }); + let setter = getSetter({ current, name, keypath, context: '__svelte', attribute, dependencies, value }); let updateElement; // + {{#each components as component}} + + {{/each}} + \ No newline at end of file diff --git a/test/generator/samples/component-binding-deep-b/Editor.html b/test/generator/samples/component-binding-deep-b/Editor.html new file mode 100644 index 0000000000..34ed70114b --- /dev/null +++ b/test/generator/samples/component-binding-deep-b/Editor.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/test/generator/samples/component-binding-deep-b/_config.js b/test/generator/samples/component-binding-deep-b/_config.js new file mode 100644 index 0000000000..b058bdeb43 --- /dev/null +++ b/test/generator/samples/component-binding-deep-b/_config.js @@ -0,0 +1,84 @@ +const components = [ + { + name: 'One', + source: 'one source' + }, + { + name: 'Two', + source: 'two source' + } +]; + +const selectedComponent = components[0]; + +export default { + skip: true, // doesn't reflect real-world bug, maybe a JSDOM quirk + + data: { + components, + selectedComponent + }, + + html: ` + + + + +
ONE SOURCE\nTWO SOURCE
+ `, + + test ( assert, component, target, window ) { + const event = new window.MouseEvent( 'input' ); + const textarea = target.querySelector( 'textarea' ); + + textarea.value = 'one source changed'; + textarea.dispatchEvent( event ); + + assert.equal( component.get( 'compiled' ), 'ONE SOURCE CHANGED\nTWO SOURCE' ); + assert.htmlEqual( target.innerHTML, ` + + + + +
ONE SOURCE CHANGED\nTWO SOURCE
+ ` ); + + // const select = target.querySelector( 'select' ); + // console.log( `select.options[0].selected`, select.options[0].selected ) + // console.log( `select.options[1].selected`, select.options[1].selected ) + // console.log( `select.value`, select.value ) + // console.log( `select.__value`, select.__value ) + // select.options[1].selected = true; + // console.log( `select.options[0].selected`, select.options[0].selected ) + // console.log( `select.options[1].selected`, select.options[1].selected ) + // console.log( `select.value`, select.value ) + // console.log( `select.__value`, select.__value ) + // select.dispatchEvent( new window.Event( 'change' ) ); + component.set({ selectedComponent: components[1] }); + + assert.equal( textarea.value, 'two source' ); + + textarea.value = 'two source changed'; + textarea.dispatchEvent( event ); + + assert.equal( component.get( 'compiled' ), 'ONE SOURCE CHANGED\nTWO SOURCE CHANGED' ); + assert.htmlEqual( target.innerHTML, ` + + + + +
ONE SOURCE CHANGED\nTWO SOURCE CHANGED
+ ` ); + + component.destroy(); + } +}; diff --git a/test/generator/samples/component-binding-deep-b/main.html b/test/generator/samples/component-binding-deep-b/main.html new file mode 100644 index 0000000000..46cdd2f6d0 --- /dev/null +++ b/test/generator/samples/component-binding-deep-b/main.html @@ -0,0 +1,42 @@ + + + +
+{{compiled}}
+
+ + \ No newline at end of file diff --git a/test/generator/samples/event-handler-custom-node-context/_config.js b/test/generator/samples/event-handler-custom-node-context/_config.js new file mode 100644 index 0000000000..e2099f96bc --- /dev/null +++ b/test/generator/samples/event-handler-custom-node-context/_config.js @@ -0,0 +1,15 @@ +export default { + 'skip-ssr': true, + + html: '', + + test ( assert, component, target, window ) { + const event = new window.MouseEvent( 'click' ); + + const button = target.querySelector( 'button' ); + + button.dispatchEvent( event ); + + assert.equal( target.innerHTML, '' ); + } +}; diff --git a/test/generator/samples/event-handler-custom-node-context/main.html b/test/generator/samples/event-handler-custom-node-context/main.html new file mode 100644 index 0000000000..916001d82c --- /dev/null +++ b/test/generator/samples/event-handler-custom-node-context/main.html @@ -0,0 +1,25 @@ + + + diff --git a/test/generator/samples/select-one-way-bind/_config.js b/test/generator/samples/select-one-way-bind/_config.js new file mode 100644 index 0000000000..7fd1f668f9 --- /dev/null +++ b/test/generator/samples/select-one-way-bind/_config.js @@ -0,0 +1,19 @@ +export default { + 'skip-ssr': true, + + data: { + foo: 'a' + }, + + test ( assert, component, target ) { + const options = target.querySelectorAll( 'option' ); + + assert.equal( options[0].selected, true ); + assert.equal( options[1].selected, false ); + + component.set( { foo: 'b' } ); + + assert.equal( options[0].selected, false ); + assert.equal( options[1].selected, true ); + } +}; diff --git a/test/generator/samples/select-one-way-bind/main.html b/test/generator/samples/select-one-way-bind/main.html new file mode 100644 index 0000000000..9072a822b8 --- /dev/null +++ b/test/generator/samples/select-one-way-bind/main.html @@ -0,0 +1,4 @@ + diff --git a/test/sourcemaps/samples/binding/test.js b/test/sourcemaps/samples/binding/test.js index a8803c0063..8737930371 100644 --- a/test/sourcemaps/samples/binding/test.js +++ b/test/sourcemaps/samples/binding/test.js @@ -1,10 +1,10 @@ export function test ({ assert, smc, locateInSource, locateInGenerated }) { - const expected = locateInSource( 'foo.bar.baz' ); + const expected = locateInSource( 'bar.baz' ); let loc; let actual; - loc = locateInGenerated( 'foo.bar.baz' ); + loc = locateInGenerated( 'bar.baz' ); actual = smc.originalPositionFor({ line: loc.line + 1, @@ -18,7 +18,7 @@ export function test ({ assert, smc, locateInSource, locateInGenerated }) { column: expected.column }); - loc = locateInGenerated( 'foo.bar.baz', loc.character + 1 ); + loc = locateInGenerated( 'bar.baz', loc.character + 1 ); actual = smc.originalPositionFor({ line: loc.line + 1, diff --git a/test/validator/samples/import-root/errors.json b/test/validator/samples/import-root/errors.json new file mode 100644 index 0000000000..ec9384b0c8 --- /dev/null +++ b/test/validator/samples/import-root/errors.json @@ -0,0 +1,8 @@ +[{ + "message": "Imported identifiers cannot have a name of 'root' due to technical limitations", + "pos": 17, + "loc": { + "line": 2, + "column": 8 + } +}] diff --git a/test/validator/samples/import-root/input.html b/test/validator/samples/import-root/input.html new file mode 100644 index 0000000000..d1cda13562 --- /dev/null +++ b/test/validator/samples/import-root/input.html @@ -0,0 +1,3 @@ +