From 52dbc882a7e7396e76d17be8fa5357b3be14e188 Mon Sep 17 00:00:00 2001 From: Tan Li Hau Date: Wed, 25 Dec 2019 00:53:18 +0800 Subject: [PATCH 01/79] feat order attributes + actions too (#4156) Co-authored-by: Conduitry --- .../render_dom/wrappers/Element/index.ts | 52 +++++++++--------- .../render_dom/wrappers/shared/add_actions.ts | 54 +++++++++---------- .../wrappers/shared/add_event_handlers.ts | 10 +++- src/runtime/internal/utils.ts | 6 ++- .../action-custom-event-handler/expected.js | 10 ++-- test/js/samples/action/expected.js | 7 +-- .../apply-directives-in-order-2/_config.js | 38 +++++++++++++ .../apply-directives-in-order-2/main.svelte | 34 ++++++++++++ 8 files changed, 149 insertions(+), 62 deletions(-) create mode 100644 test/runtime/samples/apply-directives-in-order-2/_config.js create mode 100644 test/runtime/samples/apply-directives-in-order-2/main.svelte diff --git a/src/compiler/compile/render_dom/wrappers/Element/index.ts b/src/compiler/compile/render_dom/wrappers/Element/index.ts index 0478702c7c..ef33022402 100644 --- a/src/compiler/compile/render_dom/wrappers/Element/index.ts +++ b/src/compiler/compile/render_dom/wrappers/Element/index.ts @@ -16,8 +16,8 @@ import { dimensions } from '../../../../utils/patterns'; import Binding from './Binding'; import InlineComponentWrapper from '../InlineComponent'; import add_to_set from '../../../utils/add_to_set'; -import add_event_handlers from '../shared/add_event_handlers'; -import add_actions from '../shared/add_actions'; +import { add_event_handler } from '../shared/add_event_handlers'; +import { add_action } from '../shared/add_actions'; import create_debugging_comment from '../shared/create_debugging_comment'; import { get_slot_definition } from '../shared/get_slot_definition'; import bind_this from '../shared/bind_this'; @@ -25,6 +25,7 @@ import { is_head } from '../shared/is_head'; import { Identifier } from 'estree'; import EventHandler from './EventHandler'; import { extract_names } from 'periscopic'; +import Action from '../../../nodes/Action'; const events = [ { @@ -380,7 +381,6 @@ export default class ElementWrapper extends Wrapper { this.add_directives_in_order(block); this.add_transitions(block); this.add_animation(block); - this.add_actions(block); this.add_classes(block); this.add_manual_style_scoping(block); @@ -441,6 +441,8 @@ export default class ElementWrapper extends Wrapper { bindings: Binding[]; } + type OrderedAttribute = EventHandler | BindingGroup | Binding | Action; + const bindingGroups = events .map(event => ({ events: event.event_names, @@ -452,29 +454,37 @@ export default class ElementWrapper extends Wrapper { const this_binding = this.bindings.find(b => b.node.name === 'this'); - function getOrder (item: EventHandler | BindingGroup | Binding) { + function getOrder (item: OrderedAttribute) { if (item instanceof EventHandler) { return item.node.start; } else if (item instanceof Binding) { return item.node.start; + } else if (item instanceof Action) { + return item.start; } else { return item.bindings[0].node.start; } } - const ordered: Array = [].concat(bindingGroups, this.event_handlers, this_binding).filter(Boolean); - - ordered.sort((a, b) => getOrder(a) - getOrder(b)); - - ordered.forEach(bindingGroupOrEventHandler => { - if (bindingGroupOrEventHandler instanceof EventHandler) { - add_event_handlers(block, this.var, [bindingGroupOrEventHandler]); - } else if (bindingGroupOrEventHandler instanceof Binding) { - this.add_this_binding(block, bindingGroupOrEventHandler); - } else { - this.add_bindings(block, bindingGroupOrEventHandler); - } - }); + ([ + ...bindingGroups, + ...this.event_handlers, + this_binding, + ...this.node.actions + ] as OrderedAttribute[]) + .filter(Boolean) + .sort((a, b) => getOrder(a) - getOrder(b)) + .forEach(item => { + if (item instanceof EventHandler) { + add_event_handler(block, this.var, item); + } else if (item instanceof Binding) { + this.add_this_binding(block, item); + } else if (item instanceof Action) { + add_action(block, this.var, item); + } else { + this.add_bindings(block, item); + } + }); } add_bindings(block: Block, bindingGroup) { @@ -701,10 +711,6 @@ export default class ElementWrapper extends Wrapper { `); } - add_event_handlers(block: Block) { - add_event_handlers(block, this.var, this.event_handlers); - } - add_transitions( block: Block ) { @@ -866,10 +872,6 @@ export default class ElementWrapper extends Wrapper { `); } - add_actions(block: Block) { - add_actions(block, this.var, this.node.actions); - } - add_classes(block: Block) { const has_spread = this.node.attributes.some(attr => attr.is_spread); this.node.classes.forEach(class_directive => { diff --git a/src/compiler/compile/render_dom/wrappers/shared/add_actions.ts b/src/compiler/compile/render_dom/wrappers/shared/add_actions.ts index e8f1ecb916..3d8c4fbbc0 100644 --- a/src/compiler/compile/render_dom/wrappers/shared/add_actions.ts +++ b/src/compiler/compile/render_dom/wrappers/shared/add_actions.ts @@ -7,42 +7,40 @@ export default function add_actions( target: string, actions: Action[] ) { - actions.forEach(action => { - const { expression } = action; - let snippet; - let dependencies; - - if (expression) { - snippet = expression.manipulate(block); - dependencies = expression.dynamic_dependencies(); - } + actions.forEach(action => add_action(block, target, action)); +} - const id = block.get_unique_name( - `${action.name.replace(/[^a-zA-Z0-9_$]/g, '_')}_action` - ); +export function add_action(block: Block, target: string, action: Action) { + const { expression } = action; + let snippet; + let dependencies; - block.add_variable(id); + if (expression) { + snippet = expression.manipulate(block); + dependencies = expression.dynamic_dependencies(); + } - const fn = block.renderer.reference(action.name); + const id = block.get_unique_name( + `${action.name.replace(/[^a-zA-Z0-9_$]/g, '_')}_action` + ); - block.chunks.mount.push( - b`${id} = ${fn}.call(null, ${target}, ${snippet}) || {};` - ); + block.add_variable(id); + + const fn = block.renderer.reference(action.name); - if (dependencies && dependencies.length > 0) { - let condition = x`@is_function(${id}.update)`; + block.event_listeners.push( + x`@action_destroyer(${id} = ${fn}.call(null, ${target}, ${snippet}))` + ); - if (dependencies.length > 0) { - condition = x`${condition} && ${block.renderer.dirty(dependencies)}`; - } + if (dependencies && dependencies.length > 0) { + let condition = x`${id} && @is_function(${id}.update)`; - block.chunks.update.push( - b`if (${condition}) ${id}.update.call(null, ${snippet});` - ); + if (dependencies.length > 0) { + condition = x`${condition} && ${block.renderer.dirty(dependencies)}`; } - block.chunks.destroy.push( - b`if (${id} && @is_function(${id}.destroy)) ${id}.destroy();` + block.chunks.update.push( + b`if (${condition}) ${id}.update.call(null, ${snippet});` ); - }); + } } diff --git a/src/compiler/compile/render_dom/wrappers/shared/add_event_handlers.ts b/src/compiler/compile/render_dom/wrappers/shared/add_event_handlers.ts index ca4f5a24c7..23a37715cc 100644 --- a/src/compiler/compile/render_dom/wrappers/shared/add_event_handlers.ts +++ b/src/compiler/compile/render_dom/wrappers/shared/add_event_handlers.ts @@ -6,5 +6,13 @@ export default function add_event_handlers( target: string, handlers: EventHandler[] ) { - handlers.forEach(handler => handler.render(block, target)); + handlers.forEach(handler => add_event_handler(block, target, handler)); +} + +export function add_event_handler( + block: Block, + target: string, + handler: EventHandler +) { + handler.render(block, target); } diff --git a/src/runtime/internal/utils.ts b/src/runtime/internal/utils.ts index b844f1dd4c..c94a135869 100644 --- a/src/runtime/internal/utils.ts +++ b/src/runtime/internal/utils.ts @@ -120,4 +120,8 @@ export function set_store_value(store, ret, value = ret) { return ret; } -export const has_prop = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop); \ No newline at end of file +export const has_prop = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop); + +export function action_destroyer(action_result) { + return action_result && is_function(action_result.destroy) ? action_result.destroy : noop; +} \ No newline at end of file diff --git a/test/js/samples/action-custom-event-handler/expected.js b/test/js/samples/action-custom-event-handler/expected.js index 6c3a2a5b0b..da42603895 100644 --- a/test/js/samples/action-custom-event-handler/expected.js +++ b/test/js/samples/action-custom-event-handler/expected.js @@ -1,6 +1,7 @@ /* generated by Svelte vX.Y.Z */ import { SvelteComponent, + action_destroyer, detach, element, init, @@ -13,24 +14,25 @@ import { function create_fragment(ctx) { let button; let foo_action; + let dispose; return { c() { button = element("button"); button.textContent = "foo"; + dispose = action_destroyer(foo_action = foo.call(null, button, /*foo_function*/ ctx[1])); }, m(target, anchor) { insert(target, button, anchor); - foo_action = foo.call(null, button, /*foo_function*/ ctx[1]) || ({}); }, p(ctx, [dirty]) { - if (is_function(foo_action.update) && dirty & /*bar*/ 1) foo_action.update.call(null, /*foo_function*/ ctx[1]); + if (foo_action && is_function(foo_action.update) && dirty & /*bar*/ 1) foo_action.update.call(null, /*foo_function*/ ctx[1]); }, i: noop, o: noop, d(detaching) { if (detaching) detach(button); - if (foo_action && is_function(foo_action.destroy)) foo_action.destroy(); + dispose(); } }; } @@ -40,7 +42,7 @@ function handleFoo(bar) { } function foo(node, callback) { - + } function instance($$self, $$props, $$invalidate) { diff --git a/test/js/samples/action/expected.js b/test/js/samples/action/expected.js index 78fc4855c6..dc3ebb5cf8 100644 --- a/test/js/samples/action/expected.js +++ b/test/js/samples/action/expected.js @@ -1,12 +1,12 @@ /* generated by Svelte vX.Y.Z */ import { SvelteComponent, + action_destroyer, attr, detach, element, init, insert, - is_function, noop, safe_not_equal } from "svelte/internal"; @@ -14,23 +14,24 @@ import { function create_fragment(ctx) { let a; let link_action; + let dispose; return { c() { a = element("a"); a.textContent = "Test"; attr(a, "href", "#"); + dispose = action_destroyer(link_action = link.call(null, a)); }, m(target, anchor) { insert(target, a, anchor); - link_action = link.call(null, a) || ({}); }, p: noop, i: noop, o: noop, d(detaching) { if (detaching) detach(a); - if (link_action && is_function(link_action.destroy)) link_action.destroy(); + dispose(); } }; } diff --git a/test/runtime/samples/apply-directives-in-order-2/_config.js b/test/runtime/samples/apply-directives-in-order-2/_config.js new file mode 100644 index 0000000000..a74ce41cb6 --- /dev/null +++ b/test/runtime/samples/apply-directives-in-order-2/_config.js @@ -0,0 +1,38 @@ +const value = []; +export default { + props: { + value, + }, + + async test({ assert, component, target, window }) { + const inputs = target.querySelectorAll('input'); + + const event = new window.Event('input'); + + for (const input of inputs) { + input.value = 'h'; + await input.dispatchEvent(event); + } + + assert.deepEqual(value, [ + '1', + '2', + '3', + '4', + '5', + '6', + '7', + '8', + '9', + '10', + '11', + '12', + '13', + '14', + '15', + '16', + '17', + '18', + ]); + }, +}; diff --git a/test/runtime/samples/apply-directives-in-order-2/main.svelte b/test/runtime/samples/apply-directives-in-order-2/main.svelte new file mode 100644 index 0000000000..e91c4b6a14 --- /dev/null +++ b/test/runtime/samples/apply-directives-in-order-2/main.svelte @@ -0,0 +1,34 @@ + + + + + + + + From b59673155cc0e9fd300e33115cd02d99093bf43c Mon Sep 17 00:00:00 2001 From: Conduitry Date: Tue, 24 Dec 2019 10:52:10 -0500 Subject: [PATCH 02/79] site: in dev mode, proxy /repl/[id].json requests to real server --- site/src/routes/repl/[id]/index.json.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/site/src/routes/repl/[id]/index.json.js b/site/src/routes/repl/[id]/index.json.js index e34329a0e2..de41a4cecd 100644 --- a/site/src/routes/repl/[id]/index.json.js +++ b/site/src/routes/repl/[id]/index.json.js @@ -73,6 +73,18 @@ export async function get(req, res) { }); } + if (process.env.NODE_ENV === 'development') { + // In dev, proxy requests to load particular REPLs to the real server. + // This avoids needing to connect to the real database server. + req.pipe( + require('https').request({ host: 'svelte.dev', path: req.url }) + ).once('response', res_proxy => { + res_proxy.pipe(res); + res.writeHead(res_proxy.statusCode, res_proxy.headers); + }).once('error', () => res.end()); + return; + } + const [row] = await query(` select g.*, u.uid as owner from gists g left join users u on g.user_id = u.id From 8a596936d2cad9e39ccbbc2bf7e6498cc50d1e64 Mon Sep 17 00:00:00 2001 From: David Kondrad Date: Tue, 24 Dec 2019 12:07:11 -0500 Subject: [PATCH 03/79] dynamic events: validate handler before executing (#4105) --- .../wrappers/Element/EventHandler.ts | 2 +- .../samples/event-handler-dynamic/expected.js | 3 +- .../event-handler-dynamic-hash/_config.js | 56 +++++++++++++++++++ .../event-handler-dynamic-hash/main.svelte | 23 ++++++++ .../event-handler-dynamic-invalid/_config.js | 28 ++++++++++ .../event-handler-dynamic-invalid/main.svelte | 13 +++++ .../_config.js | 16 ++++++ .../main.svelte | 7 +++ .../_config.js | 16 ++++++ .../main.svelte | 11 ++++ .../_config.js | 16 ++++++ .../main.svelte | 13 +++++ .../_config.js | 19 +++++++ .../main.svelte | 20 +++++++ .../event-handler-dynamic-multiple/_config.js | 14 +++++ .../main.svelte | 11 ++++ .../samples/event-handler-dynamic/_config.js | 10 +++- 17 files changed, 274 insertions(+), 4 deletions(-) create mode 100644 test/runtime/samples/event-handler-dynamic-hash/_config.js create mode 100644 test/runtime/samples/event-handler-dynamic-hash/main.svelte create mode 100644 test/runtime/samples/event-handler-dynamic-invalid/_config.js create mode 100644 test/runtime/samples/event-handler-dynamic-invalid/main.svelte create mode 100644 test/runtime/samples/event-handler-dynamic-modifier-once/_config.js create mode 100644 test/runtime/samples/event-handler-dynamic-modifier-once/main.svelte create mode 100644 test/runtime/samples/event-handler-dynamic-modifier-prevent-default/_config.js create mode 100644 test/runtime/samples/event-handler-dynamic-modifier-prevent-default/main.svelte create mode 100644 test/runtime/samples/event-handler-dynamic-modifier-self/_config.js create mode 100644 test/runtime/samples/event-handler-dynamic-modifier-self/main.svelte create mode 100644 test/runtime/samples/event-handler-dynamic-modifier-stop-propagation/_config.js create mode 100644 test/runtime/samples/event-handler-dynamic-modifier-stop-propagation/main.svelte create mode 100644 test/runtime/samples/event-handler-dynamic-multiple/_config.js create mode 100644 test/runtime/samples/event-handler-dynamic-multiple/main.svelte diff --git a/src/compiler/compile/render_dom/wrappers/Element/EventHandler.ts b/src/compiler/compile/render_dom/wrappers/Element/EventHandler.ts index 75fa17db2f..03183ee576 100644 --- a/src/compiler/compile/render_dom/wrappers/Element/EventHandler.ts +++ b/src/compiler/compile/render_dom/wrappers/Element/EventHandler.ts @@ -30,7 +30,7 @@ export default class EventHandlerWrapper { if (this.node.reassigned) { block.maintain_context = true; - return x`function () { ${snippet}.apply(this, arguments); }`; + return x`function () { if (@is_function(${snippet})) ${snippet}.apply(this, arguments); }`; } return snippet; } diff --git a/test/js/samples/event-handler-dynamic/expected.js b/test/js/samples/event-handler-dynamic/expected.js index 34c33151bf..42c6b2951a 100644 --- a/test/js/samples/event-handler-dynamic/expected.js +++ b/test/js/samples/event-handler-dynamic/expected.js @@ -6,6 +6,7 @@ import { element, init, insert, + is_function, listen, noop, run_all, @@ -46,7 +47,7 @@ function create_fragment(ctx) { listen(button0, "click", /*updateHandler1*/ ctx[2]), listen(button1, "click", /*updateHandler2*/ ctx[3]), listen(button2, "click", function () { - /*clickHandler*/ ctx[0].apply(this, arguments); + if (is_function(/*clickHandler*/ ctx[0])) /*clickHandler*/ ctx[0].apply(this, arguments); }) ]; }, diff --git a/test/runtime/samples/event-handler-dynamic-hash/_config.js b/test/runtime/samples/event-handler-dynamic-hash/_config.js new file mode 100644 index 0000000000..e60e561524 --- /dev/null +++ b/test/runtime/samples/event-handler-dynamic-hash/_config.js @@ -0,0 +1,56 @@ +export default { + html: ` +

+ + +

+

0

+ + `, + + async test({ assert, component, target, window }) { + const [updateButton1, updateButton2, button] = target.querySelectorAll( + 'button' + ); + + const event = new window.MouseEvent('click'); + let err = ""; + window.addEventListener('error', (e) => { + e.preventDefault(); + err = e.message; + }); + + await button.dispatchEvent(event); + assert.equal(err, "", err); + assert.htmlEqual(target.innerHTML, ` +

+ + +

+

0

+ + `); + + await updateButton1.dispatchEvent(event); + await button.dispatchEvent(event); + assert.htmlEqual(target.innerHTML, ` +

+ + +

+

1

+ + `); + + await updateButton2.dispatchEvent(event); + await button.dispatchEvent(event); + assert.htmlEqual(target.innerHTML, ` +

+ + +

+

2

+ + `); + }, +}; diff --git a/test/runtime/samples/event-handler-dynamic-hash/main.svelte b/test/runtime/samples/event-handler-dynamic-hash/main.svelte new file mode 100644 index 0000000000..c81af02006 --- /dev/null +++ b/test/runtime/samples/event-handler-dynamic-hash/main.svelte @@ -0,0 +1,23 @@ + + +

+ + +

+ +

{ number }

+ + \ No newline at end of file diff --git a/test/runtime/samples/event-handler-dynamic-invalid/_config.js b/test/runtime/samples/event-handler-dynamic-invalid/_config.js new file mode 100644 index 0000000000..ba1777f945 --- /dev/null +++ b/test/runtime/samples/event-handler-dynamic-invalid/_config.js @@ -0,0 +1,28 @@ +export default { + html: ` + + `, + + async test({ assert, component, target, window }) { + const [buttonUndef, buttonNull, buttonInvalid] = target.querySelectorAll( + 'button' + ); + + const event = new window.MouseEvent('click'); + let err = ""; + window.addEventListener('error', (e) => { + e.preventDefault(); + err = e.message; + }); + + // All three should not throw if proper checking is done in runtime code + await buttonUndef.dispatchEvent(event); + assert.equal(err, "", err); + + await buttonNull.dispatchEvent(event); + assert.equal(err, "", err); + + await buttonInvalid.dispatchEvent(event); + assert.equal(err, "", err); + }, +}; diff --git a/test/runtime/samples/event-handler-dynamic-invalid/main.svelte b/test/runtime/samples/event-handler-dynamic-invalid/main.svelte new file mode 100644 index 0000000000..f4e8c5fdb7 --- /dev/null +++ b/test/runtime/samples/event-handler-dynamic-invalid/main.svelte @@ -0,0 +1,13 @@ + + + + + diff --git a/test/runtime/samples/event-handler-dynamic-modifier-once/_config.js b/test/runtime/samples/event-handler-dynamic-modifier-once/_config.js new file mode 100644 index 0000000000..41daf374c8 --- /dev/null +++ b/test/runtime/samples/event-handler-dynamic-modifier-once/_config.js @@ -0,0 +1,16 @@ +export default { + html: ` + + `, + + async test({ assert, component, target, window }) { + const button = target.querySelector('button'); + const event = new window.MouseEvent('click'); + + await button.dispatchEvent(event); + assert.equal(component.count, 1); + + await button.dispatchEvent(event); + assert.equal(component.count, 1); + } +}; diff --git a/test/runtime/samples/event-handler-dynamic-modifier-once/main.svelte b/test/runtime/samples/event-handler-dynamic-modifier-once/main.svelte new file mode 100644 index 0000000000..d363d708ba --- /dev/null +++ b/test/runtime/samples/event-handler-dynamic-modifier-once/main.svelte @@ -0,0 +1,7 @@ + + + \ No newline at end of file diff --git a/test/runtime/samples/event-handler-dynamic-modifier-prevent-default/_config.js b/test/runtime/samples/event-handler-dynamic-modifier-prevent-default/_config.js new file mode 100644 index 0000000000..4fa032bf37 --- /dev/null +++ b/test/runtime/samples/event-handler-dynamic-modifier-prevent-default/_config.js @@ -0,0 +1,16 @@ +export default { + html: ` + + `, + + async test({ assert, component, target, window }) { + const button = target.querySelector('button'); + const event = new window.MouseEvent('click', { + cancelable: true + }); + + await button.dispatchEvent(event); + + assert.ok(component.default_was_prevented); + } +}; diff --git a/test/runtime/samples/event-handler-dynamic-modifier-prevent-default/main.svelte b/test/runtime/samples/event-handler-dynamic-modifier-prevent-default/main.svelte new file mode 100644 index 0000000000..49d42f3305 --- /dev/null +++ b/test/runtime/samples/event-handler-dynamic-modifier-prevent-default/main.svelte @@ -0,0 +1,11 @@ + + + \ No newline at end of file diff --git a/test/runtime/samples/event-handler-dynamic-modifier-self/_config.js b/test/runtime/samples/event-handler-dynamic-modifier-self/_config.js new file mode 100644 index 0000000000..6d7d29e482 --- /dev/null +++ b/test/runtime/samples/event-handler-dynamic-modifier-self/_config.js @@ -0,0 +1,16 @@ +export default { + html: ` +
+ +
+ `, + + async test({ assert, component, target, window }) { + const button = target.querySelector('button'); + const event = new window.MouseEvent('click'); + + await button.dispatchEvent(event); + + assert.ok(!component.inner_clicked); + }, +}; diff --git a/test/runtime/samples/event-handler-dynamic-modifier-self/main.svelte b/test/runtime/samples/event-handler-dynamic-modifier-self/main.svelte new file mode 100644 index 0000000000..b57d88ec02 --- /dev/null +++ b/test/runtime/samples/event-handler-dynamic-modifier-self/main.svelte @@ -0,0 +1,13 @@ + + +
+ +
diff --git a/test/runtime/samples/event-handler-dynamic-modifier-stop-propagation/_config.js b/test/runtime/samples/event-handler-dynamic-modifier-stop-propagation/_config.js new file mode 100644 index 0000000000..8517429e5c --- /dev/null +++ b/test/runtime/samples/event-handler-dynamic-modifier-stop-propagation/_config.js @@ -0,0 +1,19 @@ +export default { + html: ` +
+ +
+ `, + + async test({ assert, component, target, window }) { + const button = target.querySelector('button'); + const event = new window.MouseEvent('click', { + bubbles: true + }); + + await button.dispatchEvent(event); + + assert.ok(component.inner_clicked); + assert.ok(!component.outer_clicked); + } +}; diff --git a/test/runtime/samples/event-handler-dynamic-modifier-stop-propagation/main.svelte b/test/runtime/samples/event-handler-dynamic-modifier-stop-propagation/main.svelte new file mode 100644 index 0000000000..bad7359927 --- /dev/null +++ b/test/runtime/samples/event-handler-dynamic-modifier-stop-propagation/main.svelte @@ -0,0 +1,20 @@ + + +
+ +
\ No newline at end of file diff --git a/test/runtime/samples/event-handler-dynamic-multiple/_config.js b/test/runtime/samples/event-handler-dynamic-multiple/_config.js new file mode 100644 index 0000000000..cf17c61f60 --- /dev/null +++ b/test/runtime/samples/event-handler-dynamic-multiple/_config.js @@ -0,0 +1,14 @@ +export default { + html: ` + + `, + + async test({ assert, component, target, window }) { + const button = target.querySelector('button'); + const event = new window.MouseEvent('click'); + + await button.dispatchEvent(event); + assert.equal(component.clickHandlerOne, 1); + assert.equal(component.clickHandlerTwo, 1); + } +}; diff --git a/test/runtime/samples/event-handler-dynamic-multiple/main.svelte b/test/runtime/samples/event-handler-dynamic-multiple/main.svelte new file mode 100644 index 0000000000..2dbbe61ea6 --- /dev/null +++ b/test/runtime/samples/event-handler-dynamic-multiple/main.svelte @@ -0,0 +1,11 @@ + + + diff --git a/test/runtime/samples/event-handler-dynamic/_config.js b/test/runtime/samples/event-handler-dynamic/_config.js index 41cfd6e729..e60e561524 100644 --- a/test/runtime/samples/event-handler-dynamic/_config.js +++ b/test/runtime/samples/event-handler-dynamic/_config.js @@ -14,8 +14,14 @@ export default { ); const event = new window.MouseEvent('click'); + let err = ""; + window.addEventListener('error', (e) => { + e.preventDefault(); + err = e.message; + }); await button.dispatchEvent(event); + assert.equal(err, "", err); assert.htmlEqual(target.innerHTML, `

@@ -24,7 +30,7 @@ export default {

0

`); - + await updateButton1.dispatchEvent(event); await button.dispatchEvent(event); assert.htmlEqual(target.innerHTML, ` @@ -35,7 +41,7 @@ export default {

1

`); - + await updateButton2.dispatchEvent(event); await button.dispatchEvent(event); assert.htmlEqual(target.innerHTML, ` From b6081482382b436b827182afcb84e17043139078 Mon Sep 17 00:00:00 2001 From: Conduitry Date: Tue, 24 Dec 2019 12:12:48 -0500 Subject: [PATCH 04/79] -> v3.16.7 --- CHANGELOG.md | 6 ++++++ package-lock.json | 2 +- package.json | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e41ce6f7c4..eba4bbe3e3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Svelte changelog +## 3.16.7 + +* Also apply actions in the order they're given along with other directives ([#2446](https://github.com/sveltejs/svelte/issues/2446), [#4156](https://github.com/sveltejs/svelte/pull/4156)) +* Check whether a dynamic event handler is a function before calling it ([#4090](https://github.com/sveltejs/svelte/issues/4090)) +* Correctly mark event handlers as dynamic when they involve an expression used in a `bind:` elsewhere ([#4155](https://github.com/sveltejs/svelte/pull/4155)) + ## 3.16.6 * Fix CSS specificity bug when encapsulating styles ([#1277](https://github.com/sveltejs/svelte/issues/1277)) diff --git a/package-lock.json b/package-lock.json index 5b7af2a23f..1051ac0afc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "svelte", - "version": "3.16.6", + "version": "3.16.7", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index e64b5248f7..d1fee1428d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "svelte", - "version": "3.16.6", + "version": "3.16.7", "description": "Cybernetically enhanced web apps", "module": "index.mjs", "main": "index", From 5f24e97639a4da513afce7ddae3cea07fcb55b2c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 27 Dec 2019 22:05:14 +0000 Subject: [PATCH 05/79] Bump handlebars from 4.1.2 to 4.5.3 Bumps [handlebars](https://github.com/wycats/handlebars.js) from 4.1.2 to 4.5.3. - [Release notes](https://github.com/wycats/handlebars.js/releases) - [Changelog](https://github.com/wycats/handlebars.js/blob/master/release-notes.md) - [Commits](https://github.com/wycats/handlebars.js/compare/v4.1.2...v4.5.3) Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1051ac0afc..c9b6efdc75 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1496,9 +1496,9 @@ "dev": true }, "handlebars": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.1.2.tgz", - "integrity": "sha512-nvfrjqvt9xQ8Z/w0ijewdD/vvWDTOweBUm96NTr66Wfvo1mJenBLwcYmPs3TIBP5ruzYGD7Hx/DaM9RmhroGPw==", + "version": "4.5.3", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.5.3.tgz", + "integrity": "sha512-3yPecJoJHK/4c6aZhSvxOyG4vJKDshV36VHp0iVCDVh7o9w2vwi3NSnL2MMPj3YdduqaBcu7cGbggJQM0br9xA==", "dev": true, "requires": { "neo-async": "^2.6.0", From 7fb35dd0dc372a2ed3dc5faa8ac4dac07464c0c2 Mon Sep 17 00:00:00 2001 From: Tan Li Hau Date: Sat, 28 Dec 2019 17:50:20 +0800 Subject: [PATCH 06/79] fix safari input jumping --- .../render_dom/wrappers/Element/Attribute.ts | 10 +++ test/js/samples/input-value/expected.js | 77 +++++++++++++++++++ test/js/samples/input-value/input.svelte | 11 +++ 3 files changed, 98 insertions(+) create mode 100644 test/js/samples/input-value/expected.js create mode 100644 test/js/samples/input-value/input.svelte diff --git a/src/compiler/compile/render_dom/wrappers/Element/Attribute.ts b/src/compiler/compile/render_dom/wrappers/Element/Attribute.ts index d796dc2ab3..ecddaaebaa 100644 --- a/src/compiler/compile/render_dom/wrappers/Element/Attribute.ts +++ b/src/compiler/compile/render_dom/wrappers/Element/Attribute.ts @@ -76,6 +76,8 @@ export default class AttributeWrapper { const is_select_value_attribute = name === 'value' && element.node.name === 'select'; + const is_input_value = name === 'value' && element.node.name === 'input'; + const should_cache = is_src || this.node.should_cache() || is_select_value_attribute; // TODO is this necessary? const last = should_cache && block.get_unique_name( @@ -147,6 +149,14 @@ export default class AttributeWrapper { : x`${condition} && (${last} !== (${last} = ${value}))`; } + if (is_input_value) { + const type = element.node.get_static_attribute_value('type'); + + if (type === null || type === "" || type === "text" || type === "email" || type === "password") { + condition = x`${condition} && ${element.var}.${property_name} !== ${should_cache ? last : value}`; + } + } + if (block.has_outros) { condition = x`!#current || ${condition}`; } diff --git a/test/js/samples/input-value/expected.js b/test/js/samples/input-value/expected.js new file mode 100644 index 0000000000..81753441e4 --- /dev/null +++ b/test/js/samples/input-value/expected.js @@ -0,0 +1,77 @@ +/* generated by Svelte vX.Y.Z */ +import { + SvelteComponent, + append, + detach, + element, + init, + insert, + listen, + noop, + safe_not_equal, + set_data, + space, + text +} from "svelte/internal"; + +function create_fragment(ctx) { + let input; + let t0; + let h1; + let t1; + let t2; + let dispose; + + return { + c() { + input = element("input"); + t0 = space(); + h1 = element("h1"); + t1 = text(/*name*/ ctx[0]); + t2 = text("!"); + input.value = /*name*/ ctx[0]; + dispose = listen(input, "input", /*onInput*/ ctx[1]); + }, + m(target, anchor) { + insert(target, input, anchor); + insert(target, t0, anchor); + insert(target, h1, anchor); + append(h1, t1); + append(h1, t2); + }, + p(ctx, [dirty]) { + if (dirty & /*name*/ 1 && input.value !== /*name*/ ctx[0]) { + input.value = /*name*/ ctx[0]; + } + + if (dirty & /*name*/ 1) set_data(t1, /*name*/ ctx[0]); + }, + i: noop, + o: noop, + d(detaching) { + if (detaching) detach(input); + if (detaching) detach(t0); + if (detaching) detach(h1); + dispose(); + } + }; +} + +function instance($$self, $$props, $$invalidate) { + let name = "change me"; + + function onInput(event) { + $$invalidate(0, name = event.target.value); + } + + return [name, onInput]; +} + +class Component extends SvelteComponent { + constructor(options) { + super(); + init(this, options, instance, create_fragment, safe_not_equal, {}); + } +} + +export default Component; \ No newline at end of file diff --git a/test/js/samples/input-value/input.svelte b/test/js/samples/input-value/input.svelte new file mode 100644 index 0000000000..476458a195 --- /dev/null +++ b/test/js/samples/input-value/input.svelte @@ -0,0 +1,11 @@ + + + + +

{name}!

\ No newline at end of file From aa8e470b41da1ccdea315a2654100aa387708397 Mon Sep 17 00:00:00 2001 From: Conduitry Date: Sun, 29 Dec 2019 10:41:40 -0500 Subject: [PATCH 07/79] update changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index eba4bbe3e3..af8c4a155d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Svelte changelog +## Unreleased + +* Prevent text input cursor jumping in Safari with one-way binding ([#3449](https://github.com/sveltejs/svelte/issues/3449)) + ## 3.16.7 * Also apply actions in the order they're given along with other directives ([#2446](https://github.com/sveltejs/svelte/issues/2446), [#4156](https://github.com/sveltejs/svelte/pull/4156)) From dac64a363cdcdd2b1d691eee7050feb3d918d8e0 Mon Sep 17 00:00:00 2001 From: Anthony Le Goas Date: Sun, 29 Dec 2019 16:47:27 +0100 Subject: [PATCH 08/79] site: factor out Contributors component (#4177) --- .../routes/_components/Contributors.svelte | 26 +++++++++++++++++++ site/src/routes/index.svelte | 22 ++-------------- 2 files changed, 28 insertions(+), 20 deletions(-) create mode 100644 site/src/routes/_components/Contributors.svelte diff --git a/site/src/routes/_components/Contributors.svelte b/site/src/routes/_components/Contributors.svelte new file mode 100644 index 0000000000..74eb3fa50f --- /dev/null +++ b/site/src/routes/_components/Contributors.svelte @@ -0,0 +1,26 @@ + + + + +{#each contributors as contributor, i} + + {contributor} + +{/each} diff --git a/site/src/routes/index.svelte b/site/src/routes/index.svelte index edf1e4d36c..73fbffbc6a 100644 --- a/site/src/routes/index.svelte +++ b/site/src/routes/index.svelte @@ -1,9 +1,9 @@ From 3b0c6a1c5601b9f2e4339845b317044aa0a586d9 Mon Sep 17 00:00:00 2001 From: Conduitry Date: Mon, 6 Jan 2020 08:12:00 -0500 Subject: [PATCH 19/79] fix $$invalidate getting confused by an undefined third argument (#4170) --- CHANGELOG.md | 1 + src/runtime/internal/Component.ts | 3 ++- .../_config.js | 6 ++++++ .../main.svelte | 9 +++++++++ 4 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 test/runtime/samples/reactive-values-store-destructured-undefined/_config.js create mode 100644 test/runtime/samples/reactive-values-store-destructured-undefined/main.svelte diff --git a/CHANGELOG.md b/CHANGELOG.md index 054dd17f64..5e5d5df95f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ * Prevent text input cursor jumping in Safari with one-way binding ([#3449](https://github.com/sveltejs/svelte/issues/3449)) * Expose compiler version in dev events ([#4047](https://github.com/sveltejs/svelte/issues/4047)) +* Fix reactive assignments with destructuring and stores where the destructured value should be undefined ([#4170](https://github.com/sveltejs/svelte/issues/4170)) * Do not automatically declare variables in reactive declarations when assigning to a member expression ([#4212](https://github.com/sveltejs/svelte/issues/4212)) ## 3.16.7 diff --git a/src/runtime/internal/Component.ts b/src/runtime/internal/Component.ts index c1d2f80101..10588a0804 100644 --- a/src/runtime/internal/Component.ts +++ b/src/runtime/internal/Component.ts @@ -127,7 +127,8 @@ export function init(component, options, instance, create_fragment, not_equal, p let ready = false; $$.ctx = instance - ? instance(component, prop_values, (i, ret, value = ret) => { + ? instance(component, prop_values, (i, ret, ...rest) => { + const value = rest.length ? rest[0] : ret; if ($$.ctx && not_equal($$.ctx[i], $$.ctx[i] = value)) { if ($$.bound[i]) $$.bound[i](value); if (ready) make_dirty(component, i); diff --git a/test/runtime/samples/reactive-values-store-destructured-undefined/_config.js b/test/runtime/samples/reactive-values-store-destructured-undefined/_config.js new file mode 100644 index 0000000000..5e3f15f5dc --- /dev/null +++ b/test/runtime/samples/reactive-values-store-destructured-undefined/_config.js @@ -0,0 +1,6 @@ +export default { + html: ` +

undefined

+

undefined

+ ` +}; diff --git a/test/runtime/samples/reactive-values-store-destructured-undefined/main.svelte b/test/runtime/samples/reactive-values-store-destructured-undefined/main.svelte new file mode 100644 index 0000000000..152e0e3e2e --- /dev/null +++ b/test/runtime/samples/reactive-values-store-destructured-undefined/main.svelte @@ -0,0 +1,9 @@ + + +

{foo1}

+

{foo2}

From 20dedc6cb8fd3e4d625a1db1f8c7325ad27d5df0 Mon Sep 17 00:00:00 2001 From: Conduitry Date: Sun, 5 Jan 2020 07:45:40 -0500 Subject: [PATCH 20/79] site: copy Who's Using Svelte data from community repo at build time --- .gitignore | 3 + site/package.json | 2 +- site/scripts/update_whos_using.js | 12 + .../routes/_components/WhosUsingSvelte.svelte | 96 ------- site/static/organisations/absoluteweb.svg | 1 - site/static/organisations/bekchy.png | Bin 7978 -> 0 bytes site/static/organisations/beyonk.svg | 1 - site/static/organisations/buydotstar.svg | 12 - site/static/organisations/cashfree.svg | 1 - site/static/organisations/chess.svg | 1 - site/static/organisations/comigo.svg | 1 - site/static/organisations/datawrapper.svg | 1 - site/static/organisations/dbnomics.jpg | Bin 8796 -> 0 bytes site/static/organisations/dbnomics.webp | Bin 4778 -> 0 bytes site/static/organisations/deck.svg | 1 - site/static/organisations/dextra.png | Bin 9283 -> 0 bytes site/static/organisations/entriwise.png | Bin 1844 -> 0 bytes site/static/organisations/entur.svg | 1 - site/static/organisations/from-now-on.png | Bin 2870 -> 0 bytes site/static/organisations/fusioncharts.svg | 18 -- site/static/organisations/godaddy.svg | 1 - site/static/organisations/grainger.svg | 1 - site/static/organisations/healthtree.png | Bin 1484 -> 0 bytes site/static/organisations/iota.svg | 1 - site/static/organisations/itslearning.svg | 1 - site/static/organisations/jacoux.png | Bin 4978 -> 0 bytes site/static/organisations/jingmnt.png | Bin 4102 -> 0 bytes site/static/organisations/mentorcv.png | Bin 6659 -> 0 bytes site/static/organisations/metrovias.svg | 1 - site/static/organisations/mustlab.png | Bin 1664 -> 0 bytes site/static/organisations/nesta.svg | 1 - site/static/organisations/nonkosi.svg | 1 - site/static/organisations/nyt.svg | 1 - site/static/organisations/nzz.svg | 1 - site/static/organisations/oberonspace.svg | 1 - site/static/organisations/ofof.png | Bin 4084 -> 0 bytes .../organisations/open-state-foundation.svg | 1 - site/static/organisations/panascais.svg | 9 - site/static/organisations/pankod.svg | 33 --- site/static/organisations/paperform.svg | 26 -- site/static/organisations/razorpay.svg | 1 - site/static/organisations/socialist-party.svg | 1 - site/static/organisations/softmus.png | Bin 6561 -> 0 bytes site/static/organisations/sqltribe.svg | 106 -------- site/static/organisations/stone.svg | 1 - site/static/organisations/strixcloud.svg | 244 ------------------ site/static/organisations/sucuri.png | Bin 4268 -> 0 bytes site/static/organisations/thunderdome.svg | 1 - site/static/organisations/tokopedia.svg | 4 - site/static/organisations/tsh.svg | 1 - site/static/organisations/webdesq.svg | 1 - site/static/organisations/zevvle.svg | 1 - 52 files changed, 16 insertions(+), 575 deletions(-) create mode 100644 site/scripts/update_whos_using.js delete mode 100644 site/src/routes/_components/WhosUsingSvelte.svelte delete mode 100644 site/static/organisations/absoluteweb.svg delete mode 100644 site/static/organisations/bekchy.png delete mode 100644 site/static/organisations/beyonk.svg delete mode 100644 site/static/organisations/buydotstar.svg delete mode 100644 site/static/organisations/cashfree.svg delete mode 100644 site/static/organisations/chess.svg delete mode 100644 site/static/organisations/comigo.svg delete mode 100644 site/static/organisations/datawrapper.svg delete mode 100644 site/static/organisations/dbnomics.jpg delete mode 100644 site/static/organisations/dbnomics.webp delete mode 100644 site/static/organisations/deck.svg delete mode 100644 site/static/organisations/dextra.png delete mode 100644 site/static/organisations/entriwise.png delete mode 100644 site/static/organisations/entur.svg delete mode 100644 site/static/organisations/from-now-on.png delete mode 100644 site/static/organisations/fusioncharts.svg delete mode 100644 site/static/organisations/godaddy.svg delete mode 100644 site/static/organisations/grainger.svg delete mode 100644 site/static/organisations/healthtree.png delete mode 100644 site/static/organisations/iota.svg delete mode 100644 site/static/organisations/itslearning.svg delete mode 100644 site/static/organisations/jacoux.png delete mode 100644 site/static/organisations/jingmnt.png delete mode 100644 site/static/organisations/mentorcv.png delete mode 100644 site/static/organisations/metrovias.svg delete mode 100644 site/static/organisations/mustlab.png delete mode 100644 site/static/organisations/nesta.svg delete mode 100644 site/static/organisations/nonkosi.svg delete mode 100644 site/static/organisations/nyt.svg delete mode 100644 site/static/organisations/nzz.svg delete mode 100644 site/static/organisations/oberonspace.svg delete mode 100644 site/static/organisations/ofof.png delete mode 100644 site/static/organisations/open-state-foundation.svg delete mode 100644 site/static/organisations/panascais.svg delete mode 100644 site/static/organisations/pankod.svg delete mode 100644 site/static/organisations/paperform.svg delete mode 100644 site/static/organisations/razorpay.svg delete mode 100644 site/static/organisations/socialist-party.svg delete mode 100644 site/static/organisations/softmus.png delete mode 100644 site/static/organisations/sqltribe.svg delete mode 100644 site/static/organisations/stone.svg delete mode 100644 site/static/organisations/strixcloud.svg delete mode 100644 site/static/organisations/sucuri.png delete mode 100644 site/static/organisations/thunderdome.svg delete mode 100644 site/static/organisations/tokopedia.svg delete mode 100644 site/static/organisations/tsh.svg delete mode 100644 site/static/organisations/webdesq.svg delete mode 100644 site/static/organisations/zevvle.svg diff --git a/.gitignore b/.gitignore index b0e6896dbe..7a14244929 100644 --- a/.gitignore +++ b/.gitignore @@ -33,5 +33,8 @@ _output /site/static/svelte-app.json /site/static/contributors.jpg /site/static/workers +/site/static/organisations /site/scripts/svelte-app +/site/scripts/community /site/src/routes/_contributors.js +/site/src/routes/_components/WhosUsingSvelte.svelte diff --git a/site/package.json b/site/package.json index d841808a2a..a94d264217 100644 --- a/site/package.json +++ b/site/package.json @@ -7,7 +7,7 @@ "copy-workers": "rm -rf static/workers && cp -r node_modules/@sveltejs/svelte-repl/workers static", "migrate": "node-pg-migrate -r dotenv/config", "sapper": "npm run copy-workers && sapper build --legacy", - "update": "node scripts/update_template.js && node scripts/get-contributors.js", + "update": "node scripts/update_template.js && node scripts/get-contributors.js && node scripts/update_whos_using.js", "start": "node __sapper__/build", "test": "mocha -r esm test/**", "deploy": "make deploy" diff --git a/site/scripts/update_whos_using.js b/site/scripts/update_whos_using.js new file mode 100644 index 0000000000..131a162359 --- /dev/null +++ b/site/scripts/update_whos_using.js @@ -0,0 +1,12 @@ +const sh = require('shelljs'); + +sh.cd(__dirname + '/../'); + +// fetch community repo +sh.rm('-rf','scripts/community'); +sh.exec('npx degit sveltejs/community scripts/community'); + +// copy over relevant files +sh.cp('scripts/community/whos-using-svelte/WhosUsingSvelte.svelte', 'src/routes/_components/WhosUsingSvelte.svelte'); +sh.rm('-rf', 'static/organisations'); +sh.cp('-r', 'scripts/community/whos-using-svelte/organisations', 'static'); diff --git a/site/src/routes/_components/WhosUsingSvelte.svelte b/site/src/routes/_components/WhosUsingSvelte.svelte deleted file mode 100644 index 5ae17ef7bc..0000000000 --- a/site/src/routes/_components/WhosUsingSvelte.svelte +++ /dev/null @@ -1,96 +0,0 @@ - - - - -
- Absolute Web logo - Bekchy logo - Beyonk logo - buy.* logo - Cashfree logo - Chess.com logo - Comigo logo - Datawrapper logo - DBNomics logo - Deck logo - Dextra logo - Entriwise logo - Entur logo - From-Now-On logo - FusionCharts logo - GoDaddy logo - Grainger logo - HealthTree logo - IOTA logo - itslearning logo - Jacoux logo - Jingmnt logo - Mentor CV logo - Metrovias logo - Mustlab logo - Nesta logo - Nonkosi Telecoms logo - Neue Zürcher Zeitung logo - The New York Times logo - OberonSPACE logo - Ofof logo - Open State Foundation logo - Panascais logo - Pankod logo - Paperform logo - Razorpay logo - Socialist Party logo - Softmus Tecnologia logo - SQL Tribe logo - Stone Payments logo - Strix Cloud logoStrix Cloud - Sucuri logo - The Software House logo - Thunderdome logo - Tokopedia logo - Webdesq logo - Zevvle logo - + your company? -
diff --git a/site/static/organisations/absoluteweb.svg b/site/static/organisations/absoluteweb.svg deleted file mode 100644 index e2aeb9421e..0000000000 --- a/site/static/organisations/absoluteweb.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/site/static/organisations/bekchy.png b/site/static/organisations/bekchy.png deleted file mode 100644 index 011553cb422ba642ab9b4144fbbbe149c137eb6c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7978 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 diff --git a/site/static/organisations/beyonk.svg b/site/static/organisations/beyonk.svg deleted file mode 100644 index 57d15142a8..0000000000 --- a/site/static/organisations/beyonk.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/site/static/organisations/buydotstar.svg b/site/static/organisations/buydotstar.svg deleted file mode 100644 index da0e5c9211..0000000000 --- a/site/static/organisations/buydotstar.svg +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - diff --git a/site/static/organisations/cashfree.svg b/site/static/organisations/cashfree.svg deleted file mode 100644 index d0952dd71c..0000000000 --- a/site/static/organisations/cashfree.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/site/static/organisations/chess.svg b/site/static/organisations/chess.svg deleted file mode 100644 index 752954f6e8..0000000000 --- a/site/static/organisations/chess.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/site/static/organisations/comigo.svg b/site/static/organisations/comigo.svg deleted file mode 100644 index 44622a5195..0000000000 --- a/site/static/organisations/comigo.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/site/static/organisations/datawrapper.svg b/site/static/organisations/datawrapper.svg deleted file mode 100644 index f614df0eee..0000000000 --- a/site/static/organisations/datawrapper.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/site/static/organisations/dbnomics.jpg b/site/static/organisations/dbnomics.jpg deleted file mode 100644 index 3d5991f8692443954ecbe8a86b969c9d65845a3d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8796 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 E02Ik{ \ No newline at end of file diff --git a/site/static/organisations/dextra.png b/site/static/organisations/dextra.png deleted file mode 100644 index 725f9bd51188cd32a50971b52c9f107b665637ba..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9283 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 P{MG|iP={22{|fvc$u?rA diff --git a/site/static/organisations/entriwise.png b/site/static/organisations/entriwise.png deleted file mode 100644 index be305e1300d89adf25310cf545396861a876f34f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1844 zcmV-42g~@0P)Xss2ccJQ*B3^c%>6Ic~b)M;!B3pEw=#?T{bDZdvB3W{q=aeH@aGB?n zBUf*i=945lxsoT000IjNkl;gFZh-YFK3n#Qlg!jYY@c7@)tY9m_1QxYu4dg{YSy5y^)8ANZ z*7xa72M_q;M96O7!nQOWACu|}Ix`I{Tt`9+09(XBpD5*d-*Te-m!$P#!P|AR73SZc z2<@CRLHa(Xq#+`G6Gk^NP)Fv_ktnZxgvCRX3i&Qs+tH|xwRtrG7+WB136w<&b-q-W zD7r2(kw(N879c#g55|EQ!@_|wUX&GWZ(h*LK2KIhO{7vP?U#Us<49=H>OE8|TB?N8 zU_qCFdkOxM=psh>pS)wl(?{Jt7F)Uo!Y_Y27CG(^DMemrr7&YyR4H^yD?|qizWOQ! z3wQM7w4zl_yun2I;-y+>)(u-nt3ttIA5p%<9gI<>1-%#FpD1^43RNq_P#~ZsAXrky z5+W*$s$X8cbM8-r#rtj=l{$BfVo?xr1gcfE0PI*@8BKx(c%%!;vSCX_Ie#6BMft>W z$4E&F(!WH_S!WR}(IoxF227w*7gPo^<>Xzo5(Y~OLLsHRjRb1r$&KgE1X#RLYT7hx z&lfaXz6`Ev85X472dZzc77sOv{AH-$J;PoH0Xm}cU+fvSmoatWHp8o0m!=E0)8sZ< z@Iomek+cQ_hAU}xD?M~D)B`y(m9hfF+1Kw8z1Qsyah zaG;v%j%?VTUtG+tu5XwUZ(cMmQsrVK^bn*A3snQ8So0~&na8eOELf8uxiVt)Mw%wmx@7*o=s@0MQU1J)T| z2Zu}7CKlkS`hvC$+kNuu2#jHYJ4VziT8!;AOTr{v8PcVwSKh(#V0T zIdPSgi7mb7TBsCncOVuAONMPlK=+%reAL^ir4q5#Uw0UAI4?du5oQb^*CH0o3h_p^ zLaMK)Z@JVW)q3LXft(Dz*=GiZZxf57Wt9Spv%y%nome<| zhHa%%+G8QZXZtU7^(VJxbF$quQR!-6##BWDa| z3~Pd33cR2c#K^sR8d3#~s7G!Gj3+#( zfX0&7@&WCre!qKf9Sg9rg9TG5XFeJhsuHyfI!q^4cu#=EVP{#TvC ztPtBOrB&Es85VeGxEWj(atWr9KEk4Z){jcG8;UbRX zhzVA)Q7p-z=>=;|r8M@Hu&i*!+Nt{wC3LEKEogkf+EOVE$Cg2WC9Q`!D2i;Y+^9fv z3zpcyf`RTt+QblUm1s*;@~{&pk!_+;%|L?-))FzEs>SQibg{s_2Tn`Tew*H}AF@3? i%bw%iCRy)v6#IYs3$Y;Q0000 \ No newline at end of file diff --git a/site/static/organisations/from-now-on.png b/site/static/organisations/from-now-on.png deleted file mode 100644 index 7da931dc34f869a574e9e613c1658c11972431fa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2870 zcmY*bdpOe%7aujT@w2%T;mh1}NrW(LV-sSzUy{*9QFB-HbK7cTsj*6tGK*Y8D7nvE zlY1p{nM+<0>4$E^%lrQGzRz<$=Q-zd&Uw!H=RD_7ot^ANAaW282qc2TqVXUQpXRP@ zE-0|8%{Ckkfk2Qg9NOA7mT!3k;fb~eVYsam6XF)rD=TB)Zmgpb8AY70>rU*62|s8! zJIzGzYfKx`awCh$CLGAEys6;Rb;wx%cIfiXy(T~aw`8n+yxle&c+$9+1lOb&{cAaGTbXV~H9jjo ztc))s&3ba|s@0#o{crr7t6NJp03PHi%SQl+@JA+d6vhORh)z{>JA5zp$7y(-IgyE@ zAWZ@!>Gny{3t{M<4iggqjE5r!7hmum+u;@99vhESu}KOXTfJ0Q4Zv7xL!5ZV;&7?x z_&2mKK=+hlD)_yy7}VG5L%dg4=I=utYw>tzEDyKMi-(QwcO^DRAcnd^h+Fw5#^gw$ z;#Z{aQf^Q6Oi#|U8)@Z4zcy`wxSPuSzl7*wS>3UqS(yJo%m#n9zW z$Ve?tw{6mTZMox{Z)N_xtg3*UDC-8NCyI=e5spElm38jvrG2k*YEG^bsHaTR97P#I zJ#(U+8veba4m`ltz?i%C__|TE?Djp=+XZ6dni|qLY^Kn9-1@#|6}*zdnoo{Bm+zNO zdex_{077m$R(Y#j8go&*{Di&vnX9s?+54;iR)4Qz@f=FAS0fx>vAzVYBnoV6ORu=u zFona!ug=C-PEn3vB>JyQE-zh#{1Hf-FUgMw)R2Y&iPoM1l$&rj4_3s2^nt4uVZHNd zdRft8gCTEgJlN<_KNWlKp^lrd5V3}_oGlpRt;;(&DCm^c82HH({;bH{^g27J#HlU2>XUDb86oM_S0 zQcy{*Dsrh6HLS7_9yFkQ-jvYH-5;xzVYM;-+J!X~(5Ou=#&X9Ts_U?!Y^aSxTDxVb zxq6n%0=VI-HW!)ilT+TFR1xKFzFGr27Up`_9mVoiv8Zgnme1rltL4n+1&J=}5Wqd* z^X2ekuH^@QzjGmf-7+fz*?seloz(v7cC2mjJS z2Y-nu!l}Mo;jz{$k?3ftxG3#6EKT7CbQ4NmIh}(k7@?QQo=7PsN+WgT7~utB0!r=d zy>Be+pCjx>?|14Zxwr?DHyOj8(h&aaS~Xz9UEY-GE3>1Dzd|~8T1$|`Ef_5t@GM1k zQYD6QZ)QgO%W#^Mk*FC4wZiw_Xjn3`cdprKI>x%X#3V4mO9otbg2g_gu#lCEMOb@Z zZGTEh^Jh~(~Qfe(U6c%Gns|6 z+DWr_E{kanqK-{6vGXWzv%9YmGwU%vmDV_Ss3LWV8M@2`AS6 z->JhuYoo%)6aaAp#mb<#nz1C^O6vuehYWxHb4L;F(3u>GBpjVp=Da~`_pRJI7s3s7 zXT_ekJ9j+I6%so=gzYinP^VOZk6x@#6~ygalSIt;wI@1*sQ15=k0wZdNn3bm)`Nz` zw~pv*ESo7$1Oi}Pn7@mjIzEYR>{q#x_sKRIc5uh1KS)(9g+iGUad=-RHseW-ewg$a zNi}fCK;%(=d0(~g!PMtcf#Ei1u6HOcjr*|HQ81+=s0R(dUj5Bgb$Kr-v6L;64RS|A zM5oVNCJq<^%=u+@> zuDSS$?-ltsu_;gH*Lvkfpv%!Rbw!nCr`$ zdkoI~LXnvMF-%=<(d8v(Z23+(O40WTT{?7IN$Vm2Rt4VSP^{D5nozpFm3)E274D@2 zYYvu(7s(=5?nDL+B#YZw`fqtNA0K>mKFL9f*NkKSBTJw8K}vQ_$MOZ-9uWl|IHH$8 z=Ao|vBPYC?aF0T!`Si?r|6K7alE&Gmhd=GeI1OjlQ-78^Z4fWh}}6fEvvC+eGoZir>xR z49ezEMk2v4x#dI?Uw+$ZDP+8d>$;h@5`S`j;O~5nySa1agwQd<0;cIZ>jMj!} zdD&X;JbCcx%9IWJ1e~dpKJ+srf)RUxY;R6*|DspKk-nV3mw@?W>>6`fYWE)o;V@3< Ja+@>B{|0NxGx7ic diff --git a/site/static/organisations/fusioncharts.svg b/site/static/organisations/fusioncharts.svg deleted file mode 100644 index 6712115de8..0000000000 --- a/site/static/organisations/fusioncharts.svg +++ /dev/null @@ -1,18 +0,0 @@ - - - - logo colour - Created with Sketch. - - - - - - - - - - - - - \ No newline at end of file diff --git a/site/static/organisations/godaddy.svg b/site/static/organisations/godaddy.svg deleted file mode 100644 index e753ceed7b..0000000000 --- a/site/static/organisations/godaddy.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/site/static/organisations/grainger.svg b/site/static/organisations/grainger.svg deleted file mode 100644 index af10fc52fe..0000000000 --- a/site/static/organisations/grainger.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/site/static/organisations/healthtree.png b/site/static/organisations/healthtree.png deleted file mode 100644 index ec3f219d1c8209c5a1c6e571bf3d22b82bcf7dbb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1484 zcmV;-1vC1IP)?8zU%P3HLPK*?u-+nSHxrcljvZPts7-=qh*I$Y6xJIG^6%x;U{qX4%xAi+-b z{Px@R;<)R^A;C`~!A~2%N*=&W2)a9w;HMnFOLN$eGsa!x_vu~Ie)<0TK+0#+^W0m} zecAQlecPCT+?qYfWn$BU!0yea=D48cv+nxwx$MU<#aor(t0==%-}dF8SNRq^}uaMq0kxj5zc>RQo!Vbg)d@6qJ==|szFHpgFj+LblNUq#Dn zKgnhcyFORYdH(YQt%&zTocr=NJB#h7P9-{O9rjgasLdI#d}_W zgUVgs*tD!!L0i0=P_?$roSTC7j?OcH-zR{uI*L+$B5P<=l>iZ01SFVe`vu*1?)-)P z#z8=FQC{j6ipy87Ub}Yv#(Z*`92BzzbbdQQLEXs7KylNEgI>K!-SUinDX5)ww~;BA zbO-gU>JED6u3Q%zeL-yW_dwl0cI<&GWJ+Q<9BwR99fOi^0oQj5#6chKpdPu%v$K)+za$$h3XSNuldpn>Y$vcpq<;PS^a!6 zeU;xdbY%tgUEleKI{UMyPxes{)bI&Fc%MbxL#6H)%H=hv3YL}LA*gOeKcOi(xAGKJ z_gmjt_oq8(G#+Y1I4B+oV`!zJ0n>%5XP2X%?|gxu4>hPk&!y_H3neGuw}qh7p;jmu z^oOIa*{Nor76pTgFq8|fW*8O)0~jXI=%|2>LC2tD&@t#3)DB=+WcVUtc>H_AStL62 mowlC?0gGXXCqmwnA=F>b$m$GE2OC`g0000 \ No newline at end of file diff --git a/site/static/organisations/itslearning.svg b/site/static/organisations/itslearning.svg deleted file mode 100644 index 1d5fe6fcf4..0000000000 --- a/site/static/organisations/itslearning.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/site/static/organisations/jacoux.png b/site/static/organisations/jacoux.png deleted file mode 100644 index 6d3f52017c86c4d20f35949861dacc2f14d7cb8f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4978 zcmbVQ2UOEbvkxkuND%>})F^5clu$&3&=fE#O{9Ym1B9Lgk`NLIph84Jg=?V~1x1>4 zLJOcs2SJGRb|XRr1VV2CUcB$Vd%pM1_wM`Nch3B0c6MfeJ3F&`_U!-BO%s>^pEw@? z01&u-P5%}Ez;%<;{;+=!hmR!Yk~o43cMEm}kk=tO#ZeCUT(iXi0D|?uKCYMYf)W70 zp^fYMmo12cv&kNK%Lb_rV=$eq>pDbDie1D*!}EhyGxtk-opSa?mf!R^XjLUC?^&8+ z#rNJmhw3S|^1|x8)%);64}ac^ri7g;3I`O4Tmc=|B}Rw2Os<+729e?`+5#c-)rlM1 z9ozdVmgbTJL;PKLiW?*W1rLte0`9W@585vT_*?ql0KP!#+O}~GX}>x3#(p&msHK-D zwBL}Or!93D03AeUPC_90m6Zva_s$&{lLjJ%@HwO7(W;necox0C|B_SvLmQb4(^Qj5 z-6LT@NvS}a1P6$0G}B~+cG3_ zXq2Xn;G*it-d?LkKIJpyphx+v)(ruAb5+UE+~KIE7KP^bhf}aMsowq`9v;V=K;eU| z7fY|*-QD-2x440~b)Q~#rT9ylVTC&0wXGsPJ!sgY;@rruETDXzCNd^J>3DDH7&WLp zPRT{wMUNOeDfO*b_)==btlk6u1L&X zqL3A%&JoqDUJmeG7WH4?+f(ceV4)PKs1D3v$J82ht#+lumc+U0VBI8d-mtQUe}_li zT{0mHQTOUwtw(pXt(X@`fm-XrvB524#W1{?e8b=QrA$7GL$fD66hOXYN5zM&Q5Vv4D1 z>Fb`_>)8v%*;TyD^&J=B$hPAZGkO~vbf*Car%^TikBYyAJUT=AD-GGJD)! z)u1mTHKpoDLf?~>fe{(r%}4alauTIy$x5<(b^g9SS;LF|Ya1;n3>2njPIbFVG~4i5 zo0>^69!tMHDF=2HSQKjQkUn9x)13veTIG2+`*4_DwE1v71FmR+Y+HC=Axo1TvV7Sp znx^gdWp@fgHVN4*sv2&KddkW|SQ=}i>QZyXig{9fo#X8BZvv1_p7ll0P@!B6f6*t{ z=~&(`g~nF3a(oH`$u(QH9$B3S7!FU-RxgET{qol1;eN!j=G}Cx zficm@47A?A8{ch-3bEc*;L)6fGn)lF^RJiMVC@&DI;(HbCBGD@t0I+dKpG>qN6GnZ zIdN}vayEN@lrYTGYidTRXB+~;<}aO^bnKGj`TxCGkCHgpLb!0Rxs})ufdpZK$x4jKg z%erPTRj4IVH)9yr9jFIyA7ukR78^En%RKDfs_%xDTy5!0y|{DNK6isEI>`?-3^{XS z9@yYqe}880i=|FCI8klpqLGS;L{4(-dQ;VoR~%*$HZLE6fYw1*-Zom#5{)0??Ieb& zg|_c6V^`8mK4sV2;mJ|M3&EX`r?}k4xSH1ov)gbLQ{2q{nEJz2@2}78^xu>gf6_{0 zWm}fAu5OD3ullVibZjF7i?<*NI`%%*^Q8?1Qj8JnFE*PbQEE`W%V(E#i^$rUzG}JT zy^)obpFb;QhqtRPH6_!VX!O`Xw^NO0JESSr>gU6Y&e34Sx3#{&f+UPhf*#F_H57~x z7~@sj33TIo-Rc#)xAPtA%r0tYo|FP7PePV={W6DbeEU}r4-*}T&l&Vpi&ct$>g1r? zv$#*MK~Cab2Roh_`S`% z)sV^OUkW`xDf|w3!;~)Fd(BO#>mqG$53qy(gvmK@V8~#REY1Id{`24Ke^-VmmTG8W@hKXeaN&pYP22Z%7TqnCV~5%1l;ycXYV*eOMADh<6goItuEBkTaIwx4L>oGZa|`z<#3 zqzfLWvHDZ4GJ3we2or%;)qih=Pah_?%V#ahc$o|+p4am4FL8v6^8!s1F*(7r_Fl~y zthxMrHYJKRO={ti*QCBPUmqWOTquL$wb`*wiuu%NT}&*=D`C4ONRuDsRcoE-ArG;O z(2_HsDrCt_-3)mxR}rxAp(lu{dK_Vxb;L#2iQeX{ByvMiUNjDBIcV8 z*ObF=tWR5CXtC0Kp=Y_-y+x+Fs^3-uP?}at4noR|`}m>iey^;N%Dab0mc6$nv1ZC9 zeGhic1Lj!Gc0oYh2-JE{lt*60beZ}I+VJ+HkS}P40D@PQvoAFm$Z*$aBLgRRUM5*z z&3jHT=-FWK_?up-o<3N~gnfkBrh#k_li_Ae>7mRt1y@l&rvudRI=_th_-VYD1d94D)H- zD?QMrGVbm8P{UByJEr(?S=v(rS*b2@6k}^-l`8A`6w#vPDd4=ub+WX?@FYcz|Ar8b zzt`jRvPuavM5Q5ypcXE_0yI}rivMcSv~$PdC8I_6WAlec)n5Qrrftc<0ZyKM(ma0&PNV|??7uI zu517*M9uvhTJQ(oY>gClM5l5o^!MjX5!v(!ovxffeELFeqg*N~*5s%1YCELjv-51L zq*%?E*P`c?U+0RD><_XJVpVP&xFLp7&YYj~U80Ut`JzzQe6Pyr>U6CQN}Z4Xz`%Ma6EJv^z2+ZNX)1hxV!r z*tg2#-xjnyqvV#pX`)w*{Z5>0AH`s-4vu7xU^G|Hs^+B~x7P8Tken6g_c{)3rF3|f3_{#s5Y-3uxFvhCrCf9Oar^ z$_%laKdO5v80nL>=_Vf)-w|q*80LN%NN(et34dJfVEMtfh?)L#2UAHy&~10sM$NPz z!g3-AnOBfuVUP`Wyc{w4J zFnwBE(grl?AW?);ZY*aJtb6m~GIe}6Y<8of2{&rptdZ>sL!Du$Cq1v-)ggoWU1zqN zqaE`b;P+t-?W(e$$`hpKHz)u?&b`8q8TZRITBfbpP*y-}^o_u%(R(Q$X|1r$r+Ei9 z7L#tyGK;17q??MMP@w37-EWQCdz~X2)2l{n!TH7MN;OdHu+EIx7U)=tJvCMPbZg_x zsbO}XBL&B>e68l(YXS0Vmulm(vc=-&Z&oDScU*|}3>9@8IkqXC>sfpdL&%ZH7P2*N z6TUwA;6`nGwXfRQvZNZtow#WtJh*JD^x4+r8?V!*%+6#how5aWvw-}~1FAl_ zftJix?xq*Aqti~lp$y~W{PpDufJ0jI}jI_4LP9o{kODsLI z(P8+jokh6h-P@Vn%!t`8{HRx^?Rq~HL^GzszK}u~z>&0L6N1qs2Ci#0Q+-~R%&;81 zB%qr?>2w(4oRL`8QvSh0#l0X}H5JxGdd~6`i0ZvM>e^hx>MGDW(cu*aNsTVxm(cAE zi+VO|=Hoa^s{C=Jkeqva>oMmlag`R+rG`bN%(^AdLkrI}Z85ouYw(Lc`uMLK5et)5hV6 zl(H_4fKtl(R^KEGQ5jsi9S1N~vn}dyWkKfgfI4SrN9g(gKMy>TV;(S03kC7!<7;F&xziC9)^bDgr!`<|&(B61Gq?bMONXQZ ze@}lq`W0}OSLdd1ugm%~F#urCVGj!%yp6GuhBF4GfN;S$Ar*)yAI>im06$6=po%bt_5I`<^d)a&H-M|>Mmd%Z9Yw+1_uCz z#3MjNls6iuLDT~Ofvdr3|LTT-L4Ua5y|lpBQ3yArhK2#r!_@+V@dha=DqKw$2R_SYK!TOdS)4<``C zKLg>oY3N~*2s{S+D`VPv2s8nq3HhJh|1^~UjE<95PJ$tSm5HPLRcIudQ(Y{ljNwyX Rn||$q>jozJc~|b-{|{cWxdH$H diff --git a/site/static/organisations/jingmnt.png b/site/static/organisations/jingmnt.png deleted file mode 100644 index 326f5f0bbfbae55c0c106afeece156fd553dd00d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4102 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 N1XI;ksZ=%({U5&K8vg(Q diff --git a/site/static/organisations/mentorcv.png b/site/static/organisations/mentorcv.png deleted file mode 100644 index 17cf95a9accb90f53ec3a0df0727fd5d10ff6f4e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6659 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 Y+m7vygCOwTM-D(;Ra>Q0>21jW0gtD(cmMzZ diff --git a/site/static/organisations/metrovias.svg b/site/static/organisations/metrovias.svg deleted file mode 100644 index a81394de59..0000000000 --- a/site/static/organisations/metrovias.svg +++ /dev/null @@ -1 +0,0 @@ -Asset 1 \ No newline at end of file diff --git a/site/static/organisations/mustlab.png b/site/static/organisations/mustlab.png deleted file mode 100644 index 4f3a29488bc6df256d9670bd0ed1c180584d5561..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1664 zcmb`H`#;l*1I9m7W-dF-CHG71kjtF15jrkmLKwL;UWG+$_MN_NCx*XgffNw(v4{)Y3sp6B&`etmv<3j8r1Pz4dIznLzZ9Ko0b#4oD6;Y-$K$ z-vSn!0pHVdUUqUyit+@E>|Q_MVkM^vgMqzfOSUaay&CgVHW^>sf%wmgCblf4^@iVih?Ch=gx`$ ztYW_v`F!!gCq0Xt4FI>XrB~|zq6A*&*kL7&dTK49ac)!5KoJ3B_~{9QyqucI>L=tw z_s-fo8>yr^*cfUxDu+?`0+-{j4-h$`G5DJVPZBdR{-&s4&8_qM&3g^8YW6V~RmXeM zCE4R1_>q0<+jZ>_{l_LEqee|KLOJub+2|BranA431w?~`af1Wz+o(*oaF#_H^m69z zg>gGyBJHs{w=$oti;ItYn7`5PT?*PFm4K|`|MP#i?MFwI35AoFWVdI(^ajeWx#zTK z|MwyCVjdbci{I!qABjf zE;dGPop0LR$7GDS?Gv6>weJjV3XGPWxwSN8D1Ee{OZ6@Y*JG7m&B_lQA;y^&e-o4PNZI?(kCjfcD3>h zjSXVnQ4h5y*Xk)o8@Q;@1(vVhcM3~O+r48NhV}v&u-Uu_1W5V)baSz=O0j2b&e5Q{ zLY1}BP-L@Mdy-2NZlr|i?l@Yj*J8ob{5cJov!(u=ZhD19snD~-$415^^G_a9$DrAD z8$K8+we*1T&sH3h(L05q(OrnjVTU7C2FkKG-`00jr~(-|m@k7em3`+aUFqWBnR)h{ zF4Ft~8|q+T<9f|K;ji{0CUO$VznA#HdBFd(W7QFocb1>O0bqb9#k@4=c8Gh+IKh|a z=UE#6aJ$^twNrt1|F}m+;KoYd>q=86c8d0~hkx`^NBe$YZb7HUOuLWQT~HnVINiBu z+fAujAY%ua&{!XmDsC}BP3$fpCinSZrQe3T`&dt$M$N^4w#nBbzw+HD~ ztx3HjlH$z}%?Q*;c-Wge0eR>Wc&NF))6U8JlQ%K=>k3$xSJP{se2O$q7kr>4KbKA> zq4Hc-mK=c{9agsrLhTX~?|vX?K;_ \ No newline at end of file diff --git a/site/static/organisations/nonkosi.svg b/site/static/organisations/nonkosi.svg deleted file mode 100644 index 8639c0ce38..0000000000 --- a/site/static/organisations/nonkosi.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/site/static/organisations/nyt.svg b/site/static/organisations/nyt.svg deleted file mode 100644 index 8735e53059..0000000000 --- a/site/static/organisations/nyt.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/site/static/organisations/nzz.svg b/site/static/organisations/nzz.svg deleted file mode 100644 index 70f9486263..0000000000 --- a/site/static/organisations/nzz.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/site/static/organisations/oberonspace.svg b/site/static/organisations/oberonspace.svg deleted file mode 100644 index 73fd68f8b5..0000000000 --- a/site/static/organisations/oberonspace.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/site/static/organisations/ofof.png b/site/static/organisations/ofof.png deleted file mode 100644 index 5ecde9b0fd433016608ffd37430932dc3ca35e76..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4084 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 eZvB|Yk782J-fmXdil|@zvu \ No newline at end of file diff --git a/site/static/organisations/panascais.svg b/site/static/organisations/panascais.svg deleted file mode 100644 index cb9e4f3afe..0000000000 --- a/site/static/organisations/panascais.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/site/static/organisations/pankod.svg b/site/static/organisations/pankod.svg deleted file mode 100644 index 34578a7739..0000000000 --- a/site/static/organisations/pankod.svg +++ /dev/null @@ -1,33 +0,0 @@ - - - - Dark - Created with Sketch. - - - - - - - - \ No newline at end of file diff --git a/site/static/organisations/paperform.svg b/site/static/organisations/paperform.svg deleted file mode 100644 index 3ee2540112..0000000000 --- a/site/static/organisations/paperform.svg +++ /dev/null @@ -1,26 +0,0 @@ - - - - Logo--gradient--shadow - Created with Sketch. - - - - - - - - - - - - - - \ No newline at end of file diff --git a/site/static/organisations/razorpay.svg b/site/static/organisations/razorpay.svg deleted file mode 100644 index 829adb319e..0000000000 --- a/site/static/organisations/razorpay.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/site/static/organisations/socialist-party.svg b/site/static/organisations/socialist-party.svg deleted file mode 100644 index 9dde31a5c0..0000000000 --- a/site/static/organisations/socialist-party.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/site/static/organisations/softmus.png b/site/static/organisations/softmus.png deleted file mode 100644 index 6d0c8af60a028ccbae40a2d1528afa93d75e4114..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6561 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 -image/svg+xml \ No newline at end of file diff --git a/site/static/organisations/stone.svg b/site/static/organisations/stone.svg deleted file mode 100644 index 0401dbb292..0000000000 --- a/site/static/organisations/stone.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/site/static/organisations/strixcloud.svg b/site/static/organisations/strixcloud.svg deleted file mode 100644 index 49fe96b061..0000000000 --- a/site/static/organisations/strixcloud.svg +++ /dev/null @@ -1,244 +0,0 @@ - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/site/static/organisations/sucuri.png b/site/static/organisations/sucuri.png deleted file mode 100644 index a30b161139587e96b0dd9e21ff4475ac0920f8ca..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4268 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 \ No newline at end of file diff --git a/site/static/organisations/tokopedia.svg b/site/static/organisations/tokopedia.svg deleted file mode 100644 index d284f05d7b..0000000000 --- a/site/static/organisations/tokopedia.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/site/static/organisations/tsh.svg b/site/static/organisations/tsh.svg deleted file mode 100644 index 0b0388b500..0000000000 --- a/site/static/organisations/tsh.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/site/static/organisations/webdesq.svg b/site/static/organisations/webdesq.svg deleted file mode 100644 index c9f0012de0..0000000000 --- a/site/static/organisations/webdesq.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/site/static/organisations/zevvle.svg b/site/static/organisations/zevvle.svg deleted file mode 100644 index 45a26c7a7c..0000000000 --- a/site/static/organisations/zevvle.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file From 00e39c767a7b7428a1d9e79ad899d29ddb802fb7 Mon Sep 17 00:00:00 2001 From: Josh Duff Date: Mon, 6 Jan 2020 16:59:31 -0600 Subject: [PATCH 21/79] site: Explain how each blocks work a bit more (#4118) --- site/content/docs/02-template-syntax.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/site/content/docs/02-template-syntax.md b/site/content/docs/02-template-syntax.md index b069c8abc0..1496d18ffc 100644 --- a/site/content/docs/02-template-syntax.md +++ b/site/content/docs/02-template-syntax.md @@ -205,6 +205,8 @@ Iterating over lists of values can be done with an each block. ``` +You can use each blocks to iterate over any array or array-like value — that is, any object with a `length` property. + --- An each block can also specify an *index*, equivalent to the second argument in an `array.map(...)` callback: From 45933f97003325e24f358b514c382a066391192a Mon Sep 17 00:00:00 2001 From: trbrc Date: Tue, 7 Jan 2020 21:07:07 +0100 Subject: [PATCH 22/79] site: Clearer documentation of store contract (#4216) --- site/content/docs/01-component-format.md | 31 ++++++++++-------------- site/content/docs/03-run-time.md | 6 ++++- 2 files changed, 18 insertions(+), 19 deletions(-) diff --git a/site/content/docs/01-component-format.md b/site/content/docs/01-component-format.md index 3d349af51d..e72ae0165b 100644 --- a/site/content/docs/01-component-format.md +++ b/site/content/docs/01-component-format.md @@ -147,24 +147,7 @@ If a statement consists entirely of an assignment to an undeclared variable, Sve --- -A *store* is any object that allows reactive access to a value via a simple *store contract*. - -The [`svelte/store` module](docs#svelte_store) contains minimal store implementations which fulfil this contract. You can use these as the basis for your own stores, or you can implement your stores from scratch. - -A store must contain a `.subscribe` method, which must accept as its argument a subscription function. This subscription function must be immediately and synchronously called with the store's current value upon calling `.subscribe`. All of a store's active subscription functions must later be synchronously called whenever the store's value changes. The `.subscribe` method must also return an unsubscription function. Calling an unsubscription function must stop its subscription, and its corresponding subscription function must not be called again by the store. - -A store may optionally contain a `.set` method, which must accept as its argument a new value for the store, and which synchronously calls all of the store's active subscription functions. Such a store is called a *writable store*. - -```js -const unsubscribe = store.subscribe(value => { - console.log(value); -}); // logs `value` - -// later... -unsubscribe(); -``` - ---- +A *store* is an object that allows reactive access to a value via a simple *store contract*. The [`svelte/store` module](docs#svelte_store) contains minimal store implementations which fulfil this contract. Any time you have a reference to a store, you can access its value inside a component by prefixing it with the `$` character. This causes Svelte to declare the prefixed variable, and set up a store subscription that will be unsubscribed when appropriate. @@ -189,6 +172,18 @@ Local variables (that do not represent store values) must *not* have a `$` prefi ``` +##### Store contract + +```js +store = { subscribe: (subscription: (value: any) => void) => () => void, set?: (value: any) => void } +``` + +You can create your own stores without relying on [`svelte/store`](docs#svelte_store), by implementing the *store contract*: + +1. A store must contain a `.subscribe` method, which must accept as its argument a subscription function. This subscription function must be immediately and synchronously called with the store's current value upon calling `.subscribe`. All of a store's active subscription functions must later be synchronously called whenever the store's value changes. +2. The `.subscribe` method must return an unsubscribe function. Calling an unsubscribe function must stop its subscription, and its corresponding subscription function must not be called again by the store. +3. A store may *optionally* contain a `.set` method, which must accept as its argument a new value for the store, and which synchronously calls all of the store's active subscription functions. Such a store is called a *writable store*. + ### <script context="module"> diff --git a/site/content/docs/03-run-time.md b/site/content/docs/03-run-time.md index 5bcbe8764c..e1509cf4d1 100644 --- a/site/content/docs/03-run-time.md +++ b/site/content/docs/03-run-time.md @@ -214,7 +214,11 @@ Events dispatched from child components can be listened to in their parent. Any ### `svelte/store` -The `svelte/store` module exports functions for creating [stores](docs#4_Prefix_stores_with_$_to_access_their_values). +The `svelte/store` module exports functions for creating [readable](docs#readable), [writable](docs#writable) and [derived](docs#derived) stores. + +Keep in mind that you don't *have* to use these functions to enjoy the [reactive `$store` syntax](docs#4_Prefix_stores_with_$_to_access_their_values) in your components. Any object that correctly implements `.subscribe`, unsubscribe, and (optionally) `.set` is a valid store, and will work both with the special syntax, and with Svelte's built-in [`derived` stores](docs#derived). + +This makes it possible to wrap almost any other reactive state handling library for use in Svelte. Read more about the [store contract](docs#Store_contract) to see what a correct implementation looks like. #### `writable` From 252ec8cecaafd0fdbd92aadc69420b82891ca8b1 Mon Sep 17 00:00:00 2001 From: Conduitry Date: Tue, 7 Jan 2020 16:37:14 -0500 Subject: [PATCH 23/79] site: missing space --- site/content/docs/02-template-syntax.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/site/content/docs/02-template-syntax.md b/site/content/docs/02-template-syntax.md index 1496d18ffc..0a4ca2ee1a 100644 --- a/site/content/docs/02-template-syntax.md +++ b/site/content/docs/02-template-syntax.md @@ -1018,7 +1018,7 @@ DOMRect { ​top: number, width: number, x: number, - y:number + y: number } ``` From 14154fce364a773575c1633769e88aa73e345902 Mon Sep 17 00:00:00 2001 From: Conduitry Date: Tue, 7 Jan 2020 17:26:57 -0500 Subject: [PATCH 24/79] site: document Observable interop (#2571) --- site/content/docs/01-component-format.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/site/content/docs/01-component-format.md b/site/content/docs/01-component-format.md index e72ae0165b..d540a998c8 100644 --- a/site/content/docs/01-component-format.md +++ b/site/content/docs/01-component-format.md @@ -184,6 +184,8 @@ You can create your own stores without relying on [`svelte/store`](docs#svelte_s 2. The `.subscribe` method must return an unsubscribe function. Calling an unsubscribe function must stop its subscription, and its corresponding subscription function must not be called again by the store. 3. A store may *optionally* contain a `.set` method, which must accept as its argument a new value for the store, and which synchronously calls all of the store's active subscription functions. Such a store is called a *writable store*. +For interoperability with RxJS Observables, the `.subscribe` method is also allowed to return an object with an `.unsubscribe` method, rather than return the unsubscription function directly. Note however that unless `.subscribe` synchronously calls the subscription (which is not required by the Observable spec), Svelte will see the value of the store as `undefined` until it does. + ### <script context="module"> From b9368d5de487c97c24de82226e054469ecd1b01a Mon Sep 17 00:00:00 2001 From: burningTyger Date: Wed, 8 Jan 2020 08:42:04 +0100 Subject: [PATCH 25/79] remove quotes from code suggestion --- src/compiler/compile/Component.ts | 4 ++-- .../samples/unreferenced-variables/warnings.json | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/compiler/compile/Component.ts b/src/compiler/compile/Component.ts index baa327f4a6..9822529ece 100644 --- a/src/compiler/compile/Component.ts +++ b/src/compiler/compile/Component.ts @@ -472,7 +472,7 @@ export default class Component { if (variable.writable && !(variable.referenced || variable.referenced_from_script || variable.subscribable)) { this.warn(declarator, { code: `unused-export-let`, - message: `${this.name.name} has unused export property '${name}'. If it is for external reference only, please consider using \`export const '${name}'\`` + message: `${this.name.name} has unused export property '${name}'. If it is for external reference only, please consider using \`export const ${name}\`` }); } }); @@ -495,7 +495,7 @@ export default class Component { if (variable.writable && !(variable.referenced || variable.referenced_from_script || variable.subscribable)) { this.warn(specifier, { code: `unused-export-let`, - message: `${this.name.name} has unused export property '${specifier.exported.name}'. If it is for external reference only, please consider using \`export const '${specifier.exported.name}'\`` + message: `${this.name.name} has unused export property '${specifier.exported.name}'. If it is for external reference only, please consider using \`export const ${specifier.exported.name}\`` }); } } diff --git a/test/validator/samples/unreferenced-variables/warnings.json b/test/validator/samples/unreferenced-variables/warnings.json index 7d9e0111bf..dfac58ebdb 100644 --- a/test/validator/samples/unreferenced-variables/warnings.json +++ b/test/validator/samples/unreferenced-variables/warnings.json @@ -6,7 +6,7 @@ "column": 12, "line": 8 }, - "message": "Component has unused export property 'd'. If it is for external reference only, please consider using `export const 'd'`", + "message": "Component has unused export property 'd'. If it is for external reference only, please consider using `export const d`", "pos": 102, "start": { "character": 102, @@ -21,7 +21,7 @@ "column": 15, "line": 8 }, - "message": "Component has unused export property 'e'. If it is for external reference only, please consider using `export const 'e'`", + "message": "Component has unused export property 'e'. If it is for external reference only, please consider using `export const e`", "pos": 105, "start": { "character": 105, @@ -36,7 +36,7 @@ "column": 18, "line": 9 }, - "message": "Component has unused export property 'g'. If it is for external reference only, please consider using `export const 'g'`", + "message": "Component has unused export property 'g'. If it is for external reference only, please consider using `export const g`", "pos": 125, "start": { "character": 125, @@ -51,7 +51,7 @@ "column": 18, "line": 10 }, - "message": "Component has unused export property 'h'. If it is for external reference only, please consider using `export const 'h'`", + "message": "Component has unused export property 'h'. If it is for external reference only, please consider using `export const h`", "pos": 145, "start": { "character": 145, @@ -66,7 +66,7 @@ "column": 25, "line": 12 }, - "message": "Component has unused export property 'j'. If it is for external reference only, please consider using `export const 'j'`", + "message": "Component has unused export property 'j'. If it is for external reference only, please consider using `export const j`", "pos": 187, "start": { "character": 187, From 3d9655a2a186d18c366149d218cf67c75b722433 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kevin=20=C3=85berg=20Kultalahti?= Date: Wed, 8 Jan 2020 23:19:19 +0100 Subject: [PATCH 26/79] site: add documentation for global keyframes (#4232) --- site/content/docs/01-component-format.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/site/content/docs/01-component-format.md b/site/content/docs/01-component-format.md index d540a998c8..e541292e13 100644 --- a/site/content/docs/01-component-format.md +++ b/site/content/docs/01-component-format.md @@ -253,3 +253,15 @@ To apply styles to a selector globally, use the `:global(...)` modifier. } ``` + +--- + +If you want to make @keyframes that are accessible globally, you need to prepend your keyframe names with `-global-`. + +The `-global-` part will be removed when compiled, and the keyframe then be referenced using just `my-animation-name` elsewhere in your code. + +```html + +``` From a422d2aba5661d9f9ca54db8a1e7b11692d4cde4 Mon Sep 17 00:00:00 2001 From: Tan Li Hau Date: Sat, 11 Jan 2020 22:01:40 +0800 Subject: [PATCH 27/79] fix actions having no access to parent nodes (#4252) --- CHANGELOG.md | 1 + src/compiler/compile/render_dom/Block.ts | 4 ++-- .../action-custom-event-handler/expected.js | 4 ++-- test/js/samples/action/expected.js | 2 +- test/js/samples/bind-online/expected.js | 4 ++-- test/js/samples/bind-open/expected.js | 3 +-- .../bindings-readonly-order/expected.js | 10 ++++----- .../capture-inject-dev-only/expected.js | 2 +- .../samples/component-static-var/expected.js | 2 +- .../expected.js | 2 +- .../samples/dont-invalidate-this/expected.js | 2 +- .../samples/event-handler-dynamic/expected.js | 16 +++++++------- .../event-handler-no-passive/expected.js | 2 +- test/js/samples/event-modifiers/expected.js | 14 ++++++------ test/js/samples/input-files/expected.js | 2 +- .../input-no-initial-value/expected.js | 10 ++++----- test/js/samples/input-range/expected.js | 8 +++---- test/js/samples/input-value/expected.js | 2 +- .../input-without-blowback-guard/expected.js | 2 +- .../expected.js | 2 +- .../expected.js | 2 +- .../expected.js | 2 +- .../expected.js | 2 +- test/js/samples/media-bindings/expected.js | 22 +++++++++---------- test/js/samples/video-bindings/expected.js | 8 +++---- .../samples/window-binding-online/expected.js | 4 ++-- .../samples/window-binding-scroll/expected.js | 10 ++++----- .../_config.js | 8 +++++++ .../main.svelte | 8 +++++++ 29 files changed, 88 insertions(+), 72 deletions(-) create mode 100644 test/runtime/samples/action-receives-element-mounted/_config.js create mode 100644 test/runtime/samples/action-receives-element-mounted/main.svelte diff --git a/CHANGELOG.md b/CHANGELOG.md index 5e5d5df95f..f6af419913 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ * Prevent text input cursor jumping in Safari with one-way binding ([#3449](https://github.com/sveltejs/svelte/issues/3449)) * Expose compiler version in dev events ([#4047](https://github.com/sveltejs/svelte/issues/4047)) +* Don't run actions before their element is in the document ([#4166](https://github.com/sveltejs/svelte/issues/4166)) * Fix reactive assignments with destructuring and stores where the destructured value should be undefined ([#4170](https://github.com/sveltejs/svelte/issues/4170)) * Do not automatically declare variables in reactive declarations when assigning to a member expression ([#4212](https://github.com/sveltejs/svelte/issues/4212)) diff --git a/src/compiler/compile/render_dom/Block.ts b/src/compiler/compile/render_dom/Block.ts index c8fa884721..68d28024fe 100644 --- a/src/compiler/compile/render_dom/Block.ts +++ b/src/compiler/compile/render_dom/Block.ts @@ -450,7 +450,7 @@ export default class Block { this.add_variable(dispose); if (this.event_listeners.length === 1) { - this.chunks.hydrate.push( + this.chunks.mount.push( b`${dispose} = ${this.event_listeners[0]};` ); @@ -458,7 +458,7 @@ export default class Block { b`${dispose}();` ); } else { - this.chunks.hydrate.push(b` + this.chunks.mount.push(b` ${dispose} = [ ${this.event_listeners} ]; diff --git a/test/js/samples/action-custom-event-handler/expected.js b/test/js/samples/action-custom-event-handler/expected.js index da42603895..968b5965d5 100644 --- a/test/js/samples/action-custom-event-handler/expected.js +++ b/test/js/samples/action-custom-event-handler/expected.js @@ -20,10 +20,10 @@ function create_fragment(ctx) { c() { button = element("button"); button.textContent = "foo"; - dispose = action_destroyer(foo_action = foo.call(null, button, /*foo_function*/ ctx[1])); }, m(target, anchor) { insert(target, button, anchor); + dispose = action_destroyer(foo_action = foo.call(null, button, /*foo_function*/ ctx[1])); }, p(ctx, [dirty]) { if (foo_action && is_function(foo_action.update) && dirty & /*bar*/ 1) foo_action.update.call(null, /*foo_function*/ ctx[1]); @@ -42,7 +42,7 @@ function handleFoo(bar) { } function foo(node, callback) { - + } function instance($$self, $$props, $$invalidate) { diff --git a/test/js/samples/action/expected.js b/test/js/samples/action/expected.js index dc3ebb5cf8..22d9cd939c 100644 --- a/test/js/samples/action/expected.js +++ b/test/js/samples/action/expected.js @@ -21,10 +21,10 @@ function create_fragment(ctx) { a = element("a"); a.textContent = "Test"; attr(a, "href", "#"); - dispose = action_destroyer(link_action = link.call(null, a)); }, m(target, anchor) { insert(target, a, anchor); + dispose = action_destroyer(link_action = link.call(null, a)); }, p: noop, i: noop, diff --git a/test/js/samples/bind-online/expected.js b/test/js/samples/bind-online/expected.js index 8285646481..e129e66d71 100644 --- a/test/js/samples/bind-online/expected.js +++ b/test/js/samples/bind-online/expected.js @@ -14,13 +14,13 @@ function create_fragment(ctx) { add_render_callback(/*onlinestatuschanged*/ ctx[1]); return { - c() { + c: noop, + m(target, anchor) { dispose = [ listen(window, "online", /*onlinestatuschanged*/ ctx[1]), listen(window, "offline", /*onlinestatuschanged*/ ctx[1]) ]; }, - m: noop, p: noop, i: noop, o: noop, diff --git a/test/js/samples/bind-open/expected.js b/test/js/samples/bind-open/expected.js index d4f148cac9..7d66145f0a 100644 --- a/test/js/samples/bind-open/expected.js +++ b/test/js/samples/bind-open/expected.js @@ -20,12 +20,11 @@ function create_fragment(ctx) { details.innerHTML = `summarycontent `; - - dispose = listen(details, "toggle", /*details_toggle_handler*/ ctx[1]); }, m(target, anchor) { insert(target, details, anchor); details.open = /*open*/ ctx[0]; + dispose = listen(details, "toggle", /*details_toggle_handler*/ ctx[1]); }, p(ctx, [dirty]) { if (dirty & /*open*/ 1) { diff --git a/test/js/samples/bindings-readonly-order/expected.js b/test/js/samples/bindings-readonly-order/expected.js index cf30686662..db0e7cb007 100644 --- a/test/js/samples/bindings-readonly-order/expected.js +++ b/test/js/samples/bindings-readonly-order/expected.js @@ -26,16 +26,16 @@ function create_fragment(ctx) { input1 = element("input"); attr(input0, "type", "file"); attr(input1, "type", "file"); - - dispose = [ - listen(input0, "change", /*input0_change_handler*/ ctx[1]), - listen(input1, "change", /*input1_change_handler*/ ctx[2]) - ]; }, m(target, anchor) { insert(target, input0, anchor); insert(target, t, anchor); insert(target, input1, anchor); + + dispose = [ + listen(input0, "change", /*input0_change_handler*/ ctx[1]), + listen(input1, "change", /*input1_change_handler*/ ctx[2]) + ]; }, p: noop, i: noop, diff --git a/test/js/samples/capture-inject-dev-only/expected.js b/test/js/samples/capture-inject-dev-only/expected.js index 6c639d9207..a314b0cff3 100644 --- a/test/js/samples/capture-inject-dev-only/expected.js +++ b/test/js/samples/capture-inject-dev-only/expected.js @@ -28,7 +28,6 @@ function create_fragment(ctx) { t0 = text(/*foo*/ ctx[0]); t1 = space(); input = element("input"); - dispose = listen(input, "input", /*input_input_handler*/ ctx[1]); }, m(target, anchor) { insert(target, p, anchor); @@ -36,6 +35,7 @@ function create_fragment(ctx) { insert(target, t1, anchor); insert(target, input, anchor); set_input_value(input, /*foo*/ ctx[0]); + dispose = listen(input, "input", /*input_input_handler*/ ctx[1]); }, p(ctx, [dirty]) { if (dirty & /*foo*/ 1) set_data(t0, /*foo*/ ctx[0]); diff --git a/test/js/samples/component-static-var/expected.js b/test/js/samples/component-static-var/expected.js index e01402b6d4..a65d9186a7 100644 --- a/test/js/samples/component-static-var/expected.js +++ b/test/js/samples/component-static-var/expected.js @@ -35,7 +35,6 @@ function create_fragment(ctx) { create_component(bar.$$.fragment); t1 = space(); input = element("input"); - dispose = listen(input, "input", /*input_input_handler*/ ctx[1]); }, m(target, anchor) { mount_component(foo, target, anchor); @@ -45,6 +44,7 @@ function create_fragment(ctx) { insert(target, input, anchor); set_input_value(input, /*z*/ ctx[0]); current = true; + dispose = listen(input, "input", /*input_input_handler*/ ctx[1]); }, p(ctx, [dirty]) { const bar_changes = {}; diff --git a/test/js/samples/component-store-reassign-invalidate/expected.js b/test/js/samples/component-store-reassign-invalidate/expected.js index 02a74cf22e..771b20dec4 100644 --- a/test/js/samples/component-store-reassign-invalidate/expected.js +++ b/test/js/samples/component-store-reassign-invalidate/expected.js @@ -31,13 +31,13 @@ function create_fragment(ctx) { t1 = space(); button = element("button"); button.textContent = "reset"; - dispose = listen(button, "click", /*click_handler*/ ctx[2]); }, m(target, anchor) { insert(target, h1, anchor); append(h1, t0); insert(target, t1, anchor); insert(target, button, anchor); + dispose = listen(button, "click", /*click_handler*/ ctx[2]); }, p(ctx, [dirty]) { if (dirty & /*$foo*/ 2) set_data(t0, /*$foo*/ ctx[1]); diff --git a/test/js/samples/dont-invalidate-this/expected.js b/test/js/samples/dont-invalidate-this/expected.js index 98f638dfcf..f5f6d07812 100644 --- a/test/js/samples/dont-invalidate-this/expected.js +++ b/test/js/samples/dont-invalidate-this/expected.js @@ -17,10 +17,10 @@ function create_fragment(ctx) { return { c() { input = element("input"); - dispose = listen(input, "input", make_uppercase); }, m(target, anchor) { insert(target, input, anchor); + dispose = listen(input, "input", make_uppercase); }, p: noop, i: noop, diff --git a/test/js/samples/event-handler-dynamic/expected.js b/test/js/samples/event-handler-dynamic/expected.js index 42c6b2951a..16b4a3f626 100644 --- a/test/js/samples/event-handler-dynamic/expected.js +++ b/test/js/samples/event-handler-dynamic/expected.js @@ -42,14 +42,6 @@ function create_fragment(ctx) { t5 = space(); button2 = element("button"); button2.textContent = "click"; - - dispose = [ - listen(button0, "click", /*updateHandler1*/ ctx[2]), - listen(button1, "click", /*updateHandler2*/ ctx[3]), - listen(button2, "click", function () { - if (is_function(/*clickHandler*/ ctx[0])) /*clickHandler*/ ctx[0].apply(this, arguments); - }) - ]; }, m(target, anchor) { insert(target, p0, anchor); @@ -61,6 +53,14 @@ function create_fragment(ctx) { append(p1, t4); insert(target, t5, anchor); insert(target, button2, anchor); + + dispose = [ + listen(button0, "click", /*updateHandler1*/ ctx[2]), + listen(button1, "click", /*updateHandler2*/ ctx[3]), + listen(button2, "click", function () { + if (is_function(/*clickHandler*/ ctx[0])) /*clickHandler*/ ctx[0].apply(this, arguments); + }) + ]; }, p(new_ctx, [dirty]) { ctx = new_ctx; diff --git a/test/js/samples/event-handler-no-passive/expected.js b/test/js/samples/event-handler-no-passive/expected.js index 6f04e67808..c519fac668 100644 --- a/test/js/samples/event-handler-no-passive/expected.js +++ b/test/js/samples/event-handler-no-passive/expected.js @@ -20,10 +20,10 @@ function create_fragment(ctx) { a = element("a"); a.textContent = "this should not navigate to example.com"; attr(a, "href", "https://example.com"); - dispose = listen(a, "touchstart", touchstart_handler); }, m(target, anchor) { insert(target, a, anchor); + dispose = listen(a, "touchstart", touchstart_handler); }, p: noop, i: noop, diff --git a/test/js/samples/event-modifiers/expected.js b/test/js/samples/event-modifiers/expected.js index 3f324bb76d..252034a431 100644 --- a/test/js/samples/event-modifiers/expected.js +++ b/test/js/samples/event-modifiers/expected.js @@ -35,13 +35,6 @@ function create_fragment(ctx) { t3 = space(); button2 = element("button"); button2.textContent = "or me!"; - - dispose = [ - listen(button0, "click", stop_propagation(prevent_default(handleClick))), - listen(button1, "click", handleClick, { once: true, capture: true }), - listen(button2, "click", handleClick, true), - listen(div, "touchstart", handleTouchstart, { passive: true }) - ]; }, m(target, anchor) { insert(target, div, anchor); @@ -50,6 +43,13 @@ function create_fragment(ctx) { append(div, button1); append(div, t3); append(div, button2); + + dispose = [ + listen(button0, "click", stop_propagation(prevent_default(handleClick))), + listen(button1, "click", handleClick, { once: true, capture: true }), + listen(button2, "click", handleClick, true), + listen(div, "touchstart", handleTouchstart, { passive: true }) + ]; }, p: noop, i: noop, diff --git a/test/js/samples/input-files/expected.js b/test/js/samples/input-files/expected.js index c3e46f0c79..2a2254fbd7 100644 --- a/test/js/samples/input-files/expected.js +++ b/test/js/samples/input-files/expected.js @@ -20,10 +20,10 @@ function create_fragment(ctx) { input = element("input"); attr(input, "type", "file"); input.multiple = true; - dispose = listen(input, "change", /*input_change_handler*/ ctx[1]); }, m(target, anchor) { insert(target, input, anchor); + dispose = listen(input, "change", /*input_change_handler*/ ctx[1]); }, p: noop, i: noop, diff --git a/test/js/samples/input-no-initial-value/expected.js b/test/js/samples/input-no-initial-value/expected.js index 8ff2b2798b..d588f0bf73 100644 --- a/test/js/samples/input-no-initial-value/expected.js +++ b/test/js/samples/input-no-initial-value/expected.js @@ -31,11 +31,6 @@ function create_fragment(ctx) { button.textContent = "Store"; attr(input, "type", "text"); input.required = true; - - dispose = [ - listen(input, "input", /*input_input_handler*/ ctx[2]), - listen(form, "submit", /*handleSubmit*/ ctx[1]) - ]; }, m(target, anchor) { insert(target, form, anchor); @@ -43,6 +38,11 @@ function create_fragment(ctx) { set_input_value(input, /*test*/ ctx[0]); append(form, t0); append(form, button); + + dispose = [ + listen(input, "input", /*input_input_handler*/ ctx[2]), + listen(form, "submit", /*handleSubmit*/ ctx[1]) + ]; }, p(ctx, [dirty]) { if (dirty & /*test*/ 1 && input.value !== /*test*/ ctx[0]) { diff --git a/test/js/samples/input-range/expected.js b/test/js/samples/input-range/expected.js index 5a074d9754..12dfd3e90e 100644 --- a/test/js/samples/input-range/expected.js +++ b/test/js/samples/input-range/expected.js @@ -22,16 +22,16 @@ function create_fragment(ctx) { c() { input = element("input"); attr(input, "type", "range"); + }, + m(target, anchor) { + insert(target, input, anchor); + set_input_value(input, /*value*/ ctx[0]); dispose = [ listen(input, "change", /*input_change_input_handler*/ ctx[1]), listen(input, "input", /*input_change_input_handler*/ ctx[1]) ]; }, - m(target, anchor) { - insert(target, input, anchor); - set_input_value(input, /*value*/ ctx[0]); - }, p(ctx, [dirty]) { if (dirty & /*value*/ 1) { set_input_value(input, /*value*/ ctx[0]); diff --git a/test/js/samples/input-value/expected.js b/test/js/samples/input-value/expected.js index 81753441e4..21c7bfc83b 100644 --- a/test/js/samples/input-value/expected.js +++ b/test/js/samples/input-value/expected.js @@ -30,7 +30,6 @@ function create_fragment(ctx) { t1 = text(/*name*/ ctx[0]); t2 = text("!"); input.value = /*name*/ ctx[0]; - dispose = listen(input, "input", /*onInput*/ ctx[1]); }, m(target, anchor) { insert(target, input, anchor); @@ -38,6 +37,7 @@ function create_fragment(ctx) { insert(target, h1, anchor); append(h1, t1); append(h1, t2); + dispose = listen(input, "input", /*onInput*/ ctx[1]); }, p(ctx, [dirty]) { if (dirty & /*name*/ 1 && input.value !== /*name*/ ctx[0]) { diff --git a/test/js/samples/input-without-blowback-guard/expected.js b/test/js/samples/input-without-blowback-guard/expected.js index 344976ade6..fefe867e14 100644 --- a/test/js/samples/input-without-blowback-guard/expected.js +++ b/test/js/samples/input-without-blowback-guard/expected.js @@ -19,11 +19,11 @@ function create_fragment(ctx) { c() { input = element("input"); attr(input, "type", "checkbox"); - dispose = listen(input, "change", /*input_change_handler*/ ctx[1]); }, m(target, anchor) { insert(target, input, anchor); input.checked = /*foo*/ ctx[0]; + dispose = listen(input, "change", /*input_change_handler*/ ctx[1]); }, p(ctx, [dirty]) { if (dirty & /*foo*/ 1) { diff --git a/test/js/samples/instrumentation-script-if-no-block/expected.js b/test/js/samples/instrumentation-script-if-no-block/expected.js index 4127a6d7d6..7634481a2d 100644 --- a/test/js/samples/instrumentation-script-if-no-block/expected.js +++ b/test/js/samples/instrumentation-script-if-no-block/expected.js @@ -30,7 +30,6 @@ function create_fragment(ctx) { p = element("p"); t2 = text("x: "); t3 = text(/*x*/ ctx[0]); - dispose = listen(button, "click", /*foo*/ ctx[1]); }, m(target, anchor) { insert(target, button, anchor); @@ -38,6 +37,7 @@ function create_fragment(ctx) { insert(target, p, anchor); append(p, t2); append(p, t3); + dispose = listen(button, "click", /*foo*/ ctx[1]); }, p(ctx, [dirty]) { if (dirty & /*x*/ 1) set_data(t3, /*x*/ ctx[0]); diff --git a/test/js/samples/instrumentation-script-x-equals-x/expected.js b/test/js/samples/instrumentation-script-x-equals-x/expected.js index 0d4493baf3..c154608cd5 100644 --- a/test/js/samples/instrumentation-script-x-equals-x/expected.js +++ b/test/js/samples/instrumentation-script-x-equals-x/expected.js @@ -31,7 +31,6 @@ function create_fragment(ctx) { p = element("p"); t2 = text("number of things: "); t3 = text(t3_value); - dispose = listen(button, "click", /*foo*/ ctx[1]); }, m(target, anchor) { insert(target, button, anchor); @@ -39,6 +38,7 @@ function create_fragment(ctx) { insert(target, p, anchor); append(p, t2); append(p, t3); + dispose = listen(button, "click", /*foo*/ ctx[1]); }, p(ctx, [dirty]) { if (dirty & /*things*/ 1 && t3_value !== (t3_value = /*things*/ ctx[0].length + "")) set_data(t3, t3_value); diff --git a/test/js/samples/instrumentation-template-if-no-block/expected.js b/test/js/samples/instrumentation-template-if-no-block/expected.js index 0bd627eb87..77780baa99 100644 --- a/test/js/samples/instrumentation-template-if-no-block/expected.js +++ b/test/js/samples/instrumentation-template-if-no-block/expected.js @@ -30,7 +30,6 @@ function create_fragment(ctx) { p = element("p"); t2 = text("x: "); t3 = text(/*x*/ ctx[0]); - dispose = listen(button, "click", /*click_handler*/ ctx[1]); }, m(target, anchor) { insert(target, button, anchor); @@ -38,6 +37,7 @@ function create_fragment(ctx) { insert(target, p, anchor); append(p, t2); append(p, t3); + dispose = listen(button, "click", /*click_handler*/ ctx[1]); }, p(ctx, [dirty]) { if (dirty & /*x*/ 1) set_data(t3, /*x*/ ctx[0]); diff --git a/test/js/samples/instrumentation-template-x-equals-x/expected.js b/test/js/samples/instrumentation-template-x-equals-x/expected.js index e049a6d39b..4fe45616c7 100644 --- a/test/js/samples/instrumentation-template-x-equals-x/expected.js +++ b/test/js/samples/instrumentation-template-x-equals-x/expected.js @@ -31,7 +31,6 @@ function create_fragment(ctx) { p = element("p"); t2 = text("number of things: "); t3 = text(t3_value); - dispose = listen(button, "click", /*click_handler*/ ctx[1]); }, m(target, anchor) { insert(target, button, anchor); @@ -39,6 +38,7 @@ function create_fragment(ctx) { insert(target, p, anchor); append(p, t2); append(p, t3); + dispose = listen(button, "click", /*click_handler*/ ctx[1]); }, p(ctx, [dirty]) { if (dirty & /*things*/ 1 && t3_value !== (t3_value = /*things*/ ctx[0].length + "")) set_data(t3, t3_value); diff --git a/test/js/samples/media-bindings/expected.js b/test/js/samples/media-bindings/expected.js index b5548a3efe..52fef36792 100644 --- a/test/js/samples/media-bindings/expected.js +++ b/test/js/samples/media-bindings/expected.js @@ -41,6 +41,17 @@ function create_fragment(ctx) { if (/*duration*/ ctx[4] === void 0) add_render_callback(() => /*audio_durationchange_handler*/ ctx[13].call(audio)); if (/*seeking*/ ctx[8] === void 0) add_render_callback(() => /*audio_seeking_seeked_handler*/ ctx[17].call(audio)); if (/*ended*/ ctx[9] === void 0) add_render_callback(() => /*audio_ended_handler*/ ctx[18].call(audio)); + }, + m(target, anchor) { + insert(target, audio, anchor); + + if (!isNaN(/*volume*/ ctx[6])) { + audio.volume = /*volume*/ ctx[6]; + } + + if (!isNaN(/*playbackRate*/ ctx[7])) { + audio.playbackRate = /*playbackRate*/ ctx[7]; + } dispose = [ listen(audio, "progress", /*audio_progress_handler*/ ctx[10]), @@ -56,17 +67,6 @@ function create_fragment(ctx) { listen(audio, "ended", /*audio_ended_handler*/ ctx[18]) ]; }, - m(target, anchor) { - insert(target, audio, anchor); - - if (!isNaN(/*volume*/ ctx[6])) { - audio.volume = /*volume*/ ctx[6]; - } - - if (!isNaN(/*playbackRate*/ ctx[7])) { - audio.playbackRate = /*playbackRate*/ ctx[7]; - } - }, p(ctx, [dirty]) { if (!audio_updating && dirty & /*currentTime*/ 8 && !isNaN(/*currentTime*/ ctx[3])) { audio.currentTime = /*currentTime*/ ctx[3]; diff --git a/test/js/samples/video-bindings/expected.js b/test/js/samples/video-bindings/expected.js index 5b734a70a6..c8cd1d84ce 100644 --- a/test/js/samples/video-bindings/expected.js +++ b/test/js/samples/video-bindings/expected.js @@ -37,16 +37,16 @@ function create_fragment(ctx) { video = element("video"); if (/*videoHeight*/ ctx[1] === void 0 || /*videoWidth*/ ctx[2] === void 0) add_render_callback(() => /*video_resize_handler*/ ctx[5].call(video)); add_render_callback(() => /*video_elementresize_handler*/ ctx[6].call(video)); + }, + m(target, anchor) { + insert(target, video, anchor); + video_resize_listener = add_resize_listener(video, /*video_elementresize_handler*/ ctx[6].bind(video)); dispose = [ listen(video, "timeupdate", video_timeupdate_handler), listen(video, "resize", /*video_resize_handler*/ ctx[5]) ]; }, - m(target, anchor) { - insert(target, video, anchor); - video_resize_listener = add_resize_listener(video, /*video_elementresize_handler*/ ctx[6].bind(video)); - }, p(ctx, [dirty]) { if (!video_updating && dirty & /*currentTime*/ 1 && !isNaN(/*currentTime*/ ctx[0])) { video.currentTime = /*currentTime*/ ctx[0]; diff --git a/test/js/samples/window-binding-online/expected.js b/test/js/samples/window-binding-online/expected.js index 8285646481..e129e66d71 100644 --- a/test/js/samples/window-binding-online/expected.js +++ b/test/js/samples/window-binding-online/expected.js @@ -14,13 +14,13 @@ function create_fragment(ctx) { add_render_callback(/*onlinestatuschanged*/ ctx[1]); return { - c() { + c: noop, + m(target, anchor) { dispose = [ listen(window, "online", /*onlinestatuschanged*/ ctx[1]), listen(window, "offline", /*onlinestatuschanged*/ ctx[1]) ]; }, - m: noop, p: noop, i: noop, o: noop, diff --git a/test/js/samples/window-binding-scroll/expected.js b/test/js/samples/window-binding-scroll/expected.js index f79212e25e..70c39eedd2 100644 --- a/test/js/samples/window-binding-scroll/expected.js +++ b/test/js/samples/window-binding-scroll/expected.js @@ -33,6 +33,11 @@ function create_fragment(ctx) { p = element("p"); t0 = text("scrolled to "); t1 = text(/*y*/ ctx[0]); + }, + m(target, anchor) { + insert(target, p, anchor); + append(p, t0); + append(p, t1); dispose = listen(window, "scroll", () => { scrolling = true; @@ -41,11 +46,6 @@ function create_fragment(ctx) { /*onwindowscroll*/ ctx[1](); }); }, - m(target, anchor) { - insert(target, p, anchor); - append(p, t0); - append(p, t1); - }, p(ctx, [dirty]) { if (dirty & /*y*/ 1 && !scrolling) { scrolling = true; diff --git a/test/runtime/samples/action-receives-element-mounted/_config.js b/test/runtime/samples/action-receives-element-mounted/_config.js new file mode 100644 index 0000000000..0806d0fa90 --- /dev/null +++ b/test/runtime/samples/action-receives-element-mounted/_config.js @@ -0,0 +1,8 @@ +const result = {}; + +export default { + props: { result }, + async test({ assert, component, target, window }) { + assert.notEqual(result.parentElement, null); + } +}; diff --git a/test/runtime/samples/action-receives-element-mounted/main.svelte b/test/runtime/samples/action-receives-element-mounted/main.svelte new file mode 100644 index 0000000000..a53ce81de0 --- /dev/null +++ b/test/runtime/samples/action-receives-element-mounted/main.svelte @@ -0,0 +1,8 @@ + + +

Hello!

\ No newline at end of file From 7c3e34c00bb585b05104c13a03d3606427cb0457 Mon Sep 17 00:00:00 2001 From: Tan Li Hau Date: Mon, 13 Jan 2020 04:42:45 +0800 Subject: [PATCH 28/79] fix hydrating each else (#4253) --- CHANGELOG.md | 1 + .../compile/render_dom/wrappers/EachBlock.ts | 13 +++++++++++++ test/hydration/samples/each-else/_after.html | 4 ++++ test/hydration/samples/each-else/_before.html | 4 ++++ test/hydration/samples/each-else/main.svelte | 15 +++++++++++++++ 5 files changed, 37 insertions(+) create mode 100644 test/hydration/samples/each-else/_after.html create mode 100644 test/hydration/samples/each-else/_before.html create mode 100644 test/hydration/samples/each-else/main.svelte diff --git a/CHANGELOG.md b/CHANGELOG.md index f6af419913..25c0aa2093 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ * Expose compiler version in dev events ([#4047](https://github.com/sveltejs/svelte/issues/4047)) * Don't run actions before their element is in the document ([#4166](https://github.com/sveltejs/svelte/issues/4166)) * Fix reactive assignments with destructuring and stores where the destructured value should be undefined ([#4170](https://github.com/sveltejs/svelte/issues/4170)) +* Fix hydrating `{:else}` in `{#each}` ([#4202](https://github.com/sveltejs/svelte/issues/4202)) * Do not automatically declare variables in reactive declarations when assigning to a member expression ([#4212](https://github.com/sveltejs/svelte/issues/4212)) ## 3.16.7 diff --git a/src/compiler/compile/render_dom/wrappers/EachBlock.ts b/src/compiler/compile/render_dom/wrappers/EachBlock.ts index 5b13b486e6..4928b5a38c 100644 --- a/src/compiler/compile/render_dom/wrappers/EachBlock.ts +++ b/src/compiler/compile/render_dom/wrappers/EachBlock.ts @@ -264,10 +264,23 @@ export default class EachBlockWrapper extends Wrapper { block.chunks.init.push(b` if (!${this.vars.data_length}) { ${each_block_else} = ${this.else.block.name}(#ctx); + } + `); + + block.chunks.create.push(b` + if (${each_block_else}) { ${each_block_else}.c(); } `); + if (this.renderer.options.hydratable) { + block.chunks.claim.push(b` + if (${each_block_else}) { + ${each_block_else}.l(${parent_nodes}); + } + `); + } + block.chunks.mount.push(b` if (${each_block_else}) { ${each_block_else}.m(${initial_mount_node}, ${initial_anchor_node}); diff --git a/test/hydration/samples/each-else/_after.html b/test/hydration/samples/each-else/_after.html new file mode 100644 index 0000000000..7920500ec3 --- /dev/null +++ b/test/hydration/samples/each-else/_after.html @@ -0,0 +1,4 @@ +

Hello, world

+

+ weird +

\ No newline at end of file diff --git a/test/hydration/samples/each-else/_before.html b/test/hydration/samples/each-else/_before.html new file mode 100644 index 0000000000..7920500ec3 --- /dev/null +++ b/test/hydration/samples/each-else/_before.html @@ -0,0 +1,4 @@ +

Hello, world

+

+ weird +

\ No newline at end of file diff --git a/test/hydration/samples/each-else/main.svelte b/test/hydration/samples/each-else/main.svelte new file mode 100644 index 0000000000..64d3a37c58 --- /dev/null +++ b/test/hydration/samples/each-else/main.svelte @@ -0,0 +1,15 @@ + + +

Hello, {name}

+{#each array as elem} +

+ item +

+{:else} +

+ weird +

+{/each} From ef56a70acbe484bf1be9787ae63ae5102ee275ea Mon Sep 17 00:00:00 2001 From: Tan Li Hau Date: Tue, 14 Jan 2020 00:13:54 +0800 Subject: [PATCH 29/79] SSR should only render one (#4250) --- CHANGELOG.md | 1 + src/compiler/compile/render_ssr/handlers/Title.ts | 6 ++++++ src/runtime/internal/ssr.ts | 5 +++-- .../samples/head-multiple-title/A.svelte | 3 +++ .../samples/head-multiple-title/B.svelte | 3 +++ .../samples/head-multiple-title/_expected-head.html | 1 + .../samples/head-multiple-title/_expected.html | 0 .../samples/head-multiple-title/data.json | 3 +++ .../samples/head-multiple-title/main.svelte | 10 ++++++++++ 9 files changed, 30 insertions(+), 2 deletions(-) create mode 100644 test/server-side-rendering/samples/head-multiple-title/A.svelte create mode 100644 test/server-side-rendering/samples/head-multiple-title/B.svelte create mode 100644 test/server-side-rendering/samples/head-multiple-title/_expected-head.html create mode 100644 test/server-side-rendering/samples/head-multiple-title/_expected.html create mode 100644 test/server-side-rendering/samples/head-multiple-title/data.json create mode 100644 test/server-side-rendering/samples/head-multiple-title/main.svelte diff --git a/CHANGELOG.md b/CHANGELOG.md index 25c0aa2093..8d69c6194b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ * Fix reactive assignments with destructuring and stores where the destructured value should be undefined ([#4170](https://github.com/sveltejs/svelte/issues/4170)) * Fix hydrating `{:else}` in `{#each}` ([#4202](https://github.com/sveltejs/svelte/issues/4202)) * Do not automatically declare variables in reactive declarations when assigning to a member expression ([#4212](https://github.com/sveltejs/svelte/issues/4212)) +* Only render one `<title>` in SSR mode when multiple components provide one ([#4250](https://github.com/sveltejs/svelte/pull/4250)) ## 3.16.7 diff --git a/src/compiler/compile/render_ssr/handlers/Title.ts b/src/compiler/compile/render_ssr/handlers/Title.ts index 62d49d461a..f1f458ed5b 100644 --- a/src/compiler/compile/render_ssr/handlers/Title.ts +++ b/src/compiler/compile/render_ssr/handlers/Title.ts @@ -1,10 +1,16 @@ import Renderer, { RenderOptions } from '../Renderer'; import Title from '../../nodes/Title'; +import { x } from 'code-red'; export default function(node: Title, renderer: Renderer, options: RenderOptions) { + renderer.push(); + renderer.add_string(`<title>`); renderer.render(node.children, options); renderer.add_string(``); + const result = renderer.pop(); + + renderer.add_expression(x`($$result.title = ${result}, "")`); } diff --git a/src/runtime/internal/ssr.ts b/src/runtime/internal/ssr.ts index 274006f243..b032284d52 100644 --- a/src/runtime/internal/ssr.ts +++ b/src/runtime/internal/ssr.ts @@ -103,12 +103,13 @@ export function create_ssr_component(fn) { on_destroy = []; const result: { + title: string; head: string; css: Set<{ map: null; code: string; }>; - } = { head: '', css: new Set() }; + } = { title: '', head: '', css: new Set() }; const html = $$render(result, props, {}, options); @@ -120,7 +121,7 @@ export function create_ssr_component(fn) { code: Array.from(result.css).map(css => css.code).join('\n'), map: null // TODO }, - head: result.head + head: result.title + result.head }; }, diff --git a/test/server-side-rendering/samples/head-multiple-title/A.svelte b/test/server-side-rendering/samples/head-multiple-title/A.svelte new file mode 100644 index 0000000000..b139b4ff77 --- /dev/null +++ b/test/server-side-rendering/samples/head-multiple-title/A.svelte @@ -0,0 +1,3 @@ + + A + diff --git a/test/server-side-rendering/samples/head-multiple-title/B.svelte b/test/server-side-rendering/samples/head-multiple-title/B.svelte new file mode 100644 index 0000000000..4a29ecb04c --- /dev/null +++ b/test/server-side-rendering/samples/head-multiple-title/B.svelte @@ -0,0 +1,3 @@ + + B + diff --git a/test/server-side-rendering/samples/head-multiple-title/_expected-head.html b/test/server-side-rendering/samples/head-multiple-title/_expected-head.html new file mode 100644 index 0000000000..af5c5feba4 --- /dev/null +++ b/test/server-side-rendering/samples/head-multiple-title/_expected-head.html @@ -0,0 +1 @@ +B \ No newline at end of file diff --git a/test/server-side-rendering/samples/head-multiple-title/_expected.html b/test/server-side-rendering/samples/head-multiple-title/_expected.html new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/server-side-rendering/samples/head-multiple-title/data.json b/test/server-side-rendering/samples/head-multiple-title/data.json new file mode 100644 index 0000000000..eab238e816 --- /dev/null +++ b/test/server-side-rendering/samples/head-multiple-title/data.json @@ -0,0 +1,3 @@ +{ + "adjective": "custom" +} \ No newline at end of file diff --git a/test/server-side-rendering/samples/head-multiple-title/main.svelte b/test/server-side-rendering/samples/head-multiple-title/main.svelte new file mode 100644 index 0000000000..fb9a70b923 --- /dev/null +++ b/test/server-side-rendering/samples/head-multiple-title/main.svelte @@ -0,0 +1,10 @@ + + + + Main + + + From e3d66869df5b75b81da6183c5d68cde53b2439aa Mon Sep 17 00:00:00 2001 From: Jesse Skinner Date: Mon, 13 Jan 2020 11:24:34 -0500 Subject: [PATCH 30/79] fix stringifying of attributes in presence of spread in SSR (#4247) --- src/runtime/internal/ssr.ts | 4 +--- .../spread-attributes-white-space/_expected.html | 8 ++++++++ .../spread-attributes-white-space/main.svelte | 12 ++++++++++++ 3 files changed, 21 insertions(+), 3 deletions(-) create mode 100644 test/server-side-rendering/samples/spread-attributes-white-space/_expected.html create mode 100644 test/server-side-rendering/samples/spread-attributes-white-space/main.svelte diff --git a/src/runtime/internal/ssr.ts b/src/runtime/internal/ssr.ts index b032284d52..646a81d817 100644 --- a/src/runtime/internal/ssr.ts +++ b/src/runtime/internal/ssr.ts @@ -25,9 +25,7 @@ export function spread(args, classes_to_add) { else if (boolean_attributes.has(name.toLowerCase())) { if (value) str += " " + name; } else if (value != null) { - str += " " + name + "=" + JSON.stringify(String(value) - .replace(/"/g, '"') - .replace(/'/g, ''')); + str += ` ${name}="${String(value).replace(/"/g, '"').replace(/'/g, ''')}"`; } }); diff --git a/test/server-side-rendering/samples/spread-attributes-white-space/_expected.html b/test/server-side-rendering/samples/spread-attributes-white-space/_expected.html new file mode 100644 index 0000000000..a73bb17e8c --- /dev/null +++ b/test/server-side-rendering/samples/spread-attributes-white-space/_expected.html @@ -0,0 +1,8 @@ + + + \ No newline at end of file diff --git a/test/server-side-rendering/samples/spread-attributes-white-space/main.svelte b/test/server-side-rendering/samples/spread-attributes-white-space/main.svelte new file mode 100644 index 0000000000..6919d9ea54 --- /dev/null +++ b/test/server-side-rendering/samples/spread-attributes-white-space/main.svelte @@ -0,0 +1,12 @@ + + + + + From d7d7ce1e6c4ab0166eb5f40e5f2dad6a49dd0fe3 Mon Sep 17 00:00:00 2001 From: Conduitry Date: Mon, 13 Jan 2020 11:25:48 -0500 Subject: [PATCH 31/79] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8d69c6194b..a2db4470d1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ * Fix reactive assignments with destructuring and stores where the destructured value should be undefined ([#4170](https://github.com/sveltejs/svelte/issues/4170)) * Fix hydrating `{:else}` in `{#each}` ([#4202](https://github.com/sveltejs/svelte/issues/4202)) * Do not automatically declare variables in reactive declarations when assigning to a member expression ([#4212](https://github.com/sveltejs/svelte/issues/4212)) +* Fix stringifying of attributes in SSR mode when there are spread attributes ([#4240](https://github.com/sveltejs/svelte/issues/4240)) * Only render one `` in SSR mode when multiple components provide one ([#4250](https://github.com/sveltejs/svelte/pull/4250)) ## 3.16.7 From b3582c7fb24572a6dfd58e2009925158a9a37233 Mon Sep 17 00:00:00 2001 From: Tan Li Hau <tanhauhau@users.noreply.github.com> Date: Tue, 14 Jan 2020 00:55:55 +0800 Subject: [PATCH 32/79] fix hydrating <head> (#4082) --- CHANGELOG.md | 1 + src/compiler/compile/css/Stylesheet.ts | 10 +-------- src/compiler/compile/nodes/Head.ts | 6 ++++++ .../compile/render_dom/wrappers/Head.ts | 17 +++++++++++++-- src/compiler/compile/render_ssr/Renderer.ts | 1 + .../compile/render_ssr/handlers/Element.ts | 4 ++++ .../compile/render_ssr/handlers/Head.ts | 7 ++++++- .../compile/render_ssr/handlers/Title.ts | 2 +- src/compiler/compile/utils/hash.ts | 8 +++++++ src/runtime/internal/dom.ts | 4 ++++ test/helpers.js | 1 + test/hydration/index.js | 21 +++++++++++++++++++ .../head-meta-hydrate-duplicate/_after.html | 1 + .../_after_head.html | 4 ++++ .../head-meta-hydrate-duplicate/_before.html | 1 + .../_before_head.html | 4 ++++ .../head-meta-hydrate-duplicate/_config.js | 5 +++++ .../head-meta-hydrate-duplicate/main.svelte | 8 +++++++ .../_expected-head.html | 4 ++++ .../_expected.html | 3 +++ .../head-meta-hydrate-duplicate/main.svelte | 8 +++++++ .../head-multiple-title/_expected-head.html | 2 +- .../samples/head-title/_expected-head.html | 2 +- 23 files changed, 109 insertions(+), 15 deletions(-) create mode 100644 src/compiler/compile/utils/hash.ts create mode 100644 test/hydration/samples/head-meta-hydrate-duplicate/_after.html create mode 100644 test/hydration/samples/head-meta-hydrate-duplicate/_after_head.html create mode 100644 test/hydration/samples/head-meta-hydrate-duplicate/_before.html create mode 100644 test/hydration/samples/head-meta-hydrate-duplicate/_before_head.html create mode 100644 test/hydration/samples/head-meta-hydrate-duplicate/_config.js create mode 100644 test/hydration/samples/head-meta-hydrate-duplicate/main.svelte create mode 100644 test/server-side-rendering/samples/head-meta-hydrate-duplicate/_expected-head.html create mode 100644 test/server-side-rendering/samples/head-meta-hydrate-duplicate/_expected.html create mode 100644 test/server-side-rendering/samples/head-meta-hydrate-duplicate/main.svelte diff --git a/CHANGELOG.md b/CHANGELOG.md index a2db4470d1..4bacc5c26b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## Unreleased +* Remove old `<head>` elements during hydration so they aren't duplicated ([#1607](https://github.com/sveltejs/svelte/issues/1607)) * Prevent text input cursor jumping in Safari with one-way binding ([#3449](https://github.com/sveltejs/svelte/issues/3449)) * Expose compiler version in dev events ([#4047](https://github.com/sveltejs/svelte/issues/4047)) * Don't run actions before their element is in the document ([#4166](https://github.com/sveltejs/svelte/issues/4166)) diff --git a/src/compiler/compile/css/Stylesheet.ts b/src/compiler/compile/css/Stylesheet.ts index 998a879687..246dab0f12 100644 --- a/src/compiler/compile/css/Stylesheet.ts +++ b/src/compiler/compile/css/Stylesheet.ts @@ -5,6 +5,7 @@ import Element from '../nodes/Element'; import { Ast, TemplateNode } from '../../interfaces'; import Component from '../Component'; import { CssNode } from './interfaces'; +import hash from "../utils/hash"; function remove_css_prefix(name: string): string { return name.replace(/^-((webkit)|(moz)|(o)|(ms))-/, ''); @@ -37,15 +38,6 @@ function minify_declarations( return c; } -// https://github.com/darkskyapp/string-hash/blob/master/index.js -function hash(str: string): string { - let hash = 5381; - let i = str.length; - - while (i--) hash = ((hash << 5) - hash) ^ str.charCodeAt(i); - return (hash >>> 0).toString(36); -} - class Rule { selectors: Selector[]; declarations: Declaration[]; diff --git a/src/compiler/compile/nodes/Head.ts b/src/compiler/compile/nodes/Head.ts index 2c08dcd595..53e76d7a4d 100644 --- a/src/compiler/compile/nodes/Head.ts +++ b/src/compiler/compile/nodes/Head.ts @@ -1,9 +1,11 @@ import Node from './shared/Node'; import map_children from './shared/map_children'; +import hash from '../utils/hash'; export default class Head extends Node { type: 'Head'; children: any[]; // TODO + id: string; constructor(component, parent, scope, info) { super(component, parent, scope, info); @@ -18,5 +20,9 @@ export default class Head extends Node { this.children = map_children(component, parent, scope, info.children.filter(child => { return (child.type !== 'Text' || /\S/.test(child.data)); })); + + if (this.children.length > 0) { + this.id = `svelte-${hash(this.component.source.slice(this.start, this.end))}`; + } } } diff --git a/src/compiler/compile/render_dom/wrappers/Head.ts b/src/compiler/compile/render_dom/wrappers/Head.ts index 188c26931a..e0b723d6dd 100644 --- a/src/compiler/compile/render_dom/wrappers/Head.ts +++ b/src/compiler/compile/render_dom/wrappers/Head.ts @@ -3,11 +3,12 @@ import Renderer from '../Renderer'; import Block from '../Block'; import Head from '../../nodes/Head'; import FragmentWrapper from './Fragment'; -import { x } from 'code-red'; +import { x, b } from 'code-red'; import { Identifier } from 'estree'; export default class HeadWrapper extends Wrapper { fragment: FragmentWrapper; + node: Head; constructor( renderer: Renderer, @@ -32,6 +33,18 @@ export default class HeadWrapper extends Wrapper { } render(block: Block, _parent_node: Identifier, _parent_nodes: Identifier) { - this.fragment.render(block, x`@_document.head` as unknown as Identifier, x`#nodes` as unknown as Identifier); + let nodes; + if (this.renderer.options.hydratable && this.fragment.nodes.length) { + nodes = block.get_unique_name('head_nodes'); + block.chunks.claim.push(b`const ${nodes} = @query_selector_all('[data-svelte="${this.node.id}"]', @_document.head);`); + } + + this.fragment.render(block, x`@_document.head` as unknown as Identifier, nodes); + + if (nodes && this.renderer.options.hydratable) { + block.chunks.claim.push( + b`${nodes}.forEach(@detach);` + ); + } } } diff --git a/src/compiler/compile/render_ssr/Renderer.ts b/src/compiler/compile/render_ssr/Renderer.ts index 00a7ee2fb5..fb9216327c 100644 --- a/src/compiler/compile/render_ssr/Renderer.ts +++ b/src/compiler/compile/render_ssr/Renderer.ts @@ -41,6 +41,7 @@ const handlers: Record<string, Handler> = { export interface RenderOptions extends CompileOptions{ locate: (c: number) => { line: number; column: number }; + head_id?: string; } export default class Renderer { diff --git a/src/compiler/compile/render_ssr/handlers/Element.ts b/src/compiler/compile/render_ssr/handlers/Element.ts index 81b8801686..4c1eca8a9d 100644 --- a/src/compiler/compile/render_ssr/handlers/Element.ts +++ b/src/compiler/compile/render_ssr/handlers/Element.ts @@ -124,6 +124,10 @@ export default function(node: Element, renderer: Renderer, options: RenderOption } }); + if (options.head_id) { + renderer.add_string(` data-svelte="${options.head_id}"`); + } + renderer.add_string('>'); if (node_contents !== undefined) { diff --git a/src/compiler/compile/render_ssr/handlers/Head.ts b/src/compiler/compile/render_ssr/handlers/Head.ts index d457942922..456e5c279b 100644 --- a/src/compiler/compile/render_ssr/handlers/Head.ts +++ b/src/compiler/compile/render_ssr/handlers/Head.ts @@ -3,8 +3,13 @@ import Head from '../../nodes/Head'; import { x } from 'code-red'; export default function(node: Head, renderer: Renderer, options: RenderOptions) { + const head_options = { + ...options, + head_id: node.id + }; + renderer.push(); - renderer.render(node.children, options); + renderer.render(node.children, head_options); const result = renderer.pop(); renderer.add_expression(x`($$result.head += ${result}, "")`); diff --git a/src/compiler/compile/render_ssr/handlers/Title.ts b/src/compiler/compile/render_ssr/handlers/Title.ts index f1f458ed5b..e93ae13d66 100644 --- a/src/compiler/compile/render_ssr/handlers/Title.ts +++ b/src/compiler/compile/render_ssr/handlers/Title.ts @@ -5,7 +5,7 @@ import { x } from 'code-red'; export default function(node: Title, renderer: Renderer, options: RenderOptions) { renderer.push(); - renderer.add_string(`<title>`); + renderer.add_string(`<title data-svelte="${options.head_id}">`); renderer.render(node.children, options); diff --git a/src/compiler/compile/utils/hash.ts b/src/compiler/compile/utils/hash.ts new file mode 100644 index 0000000000..7ac892611b --- /dev/null +++ b/src/compiler/compile/utils/hash.ts @@ -0,0 +1,8 @@ +// https://github.com/darkskyapp/string-hash/blob/master/index.js +export default function hash(str: string): string { + let hash = 5381; + let i = str.length; + + while (i--) hash = ((hash << 5) - hash) ^ str.charCodeAt(i); + return (hash >>> 0).toString(36); +} \ No newline at end of file diff --git a/src/runtime/internal/dom.ts b/src/runtime/internal/dom.ts index c641315bc3..f9e89f41b9 100644 --- a/src/runtime/internal/dom.ts +++ b/src/runtime/internal/dom.ts @@ -273,6 +273,10 @@ export function custom_event<T=any>(type: string, detail?: T) { return e; } +export function query_selector_all(selector: string, parent: HTMLElement = document.body) { + return Array.from(parent.querySelectorAll(selector)); +} + export class HtmlTag { e: HTMLElement; n: ChildNode[]; diff --git a/test/helpers.js b/test/helpers.js index 2a03e0f436..5e9428243b 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -68,6 +68,7 @@ window.scrollTo = function(pageXOffset, pageYOffset) { export function env() { window.document.title = ''; + window.document.head.innerHTML = ''; window.document.body.innerHTML = '<main></main>'; return window; diff --git a/test/hydration/index.js b/test/hydration/index.js index a0bfd6de4b..f57a0cdc1a 100644 --- a/test/hydration/index.js +++ b/test/hydration/index.js @@ -67,8 +67,16 @@ describe('hydration', () => { } const target = window.document.body; + const head = window.document.head; + target.innerHTML = fs.readFileSync(`${cwd}/_before.html`, 'utf-8'); + let before_head; + try { + before_head = fs.readFileSync(`${cwd}/_before_head.html`, 'utf-8'); + head.innerHTML = before_head; + } catch (err) {} + const snapshot = config.snapshot ? config.snapshot(target) : {}; const component = new SvelteComponent({ @@ -88,6 +96,19 @@ describe('hydration', () => { } } + if (before_head) { + try { + assert.htmlEqual(head.innerHTML, fs.readFileSync(`${cwd}/_after_head.html`, 'utf-8')); + } catch (error) { + if (shouldUpdateExpected()) { + fs.writeFileSync(`${cwd}/_after_head.html`, head.innerHTML); + console.log(`Updated ${cwd}/_after_head.html.`); + } else { + throw error; + } + } + } + if (config.test) { config.test(assert, target, snapshot, component, window); } else { diff --git a/test/hydration/samples/head-meta-hydrate-duplicate/_after.html b/test/hydration/samples/head-meta-hydrate-duplicate/_after.html new file mode 100644 index 0000000000..3e5b375f0a --- /dev/null +++ b/test/hydration/samples/head-meta-hydrate-duplicate/_after.html @@ -0,0 +1 @@ +<div>Just a dummy page.</div> \ No newline at end of file diff --git a/test/hydration/samples/head-meta-hydrate-duplicate/_after_head.html b/test/hydration/samples/head-meta-hydrate-duplicate/_after_head.html new file mode 100644 index 0000000000..10cf2c8b9a --- /dev/null +++ b/test/hydration/samples/head-meta-hydrate-duplicate/_after_head.html @@ -0,0 +1,4 @@ +<title>Some Title + + + \ No newline at end of file diff --git a/test/hydration/samples/head-meta-hydrate-duplicate/_before.html b/test/hydration/samples/head-meta-hydrate-duplicate/_before.html new file mode 100644 index 0000000000..3e5b375f0a --- /dev/null +++ b/test/hydration/samples/head-meta-hydrate-duplicate/_before.html @@ -0,0 +1 @@ +
Just a dummy page.
\ No newline at end of file diff --git a/test/hydration/samples/head-meta-hydrate-duplicate/_before_head.html b/test/hydration/samples/head-meta-hydrate-duplicate/_before_head.html new file mode 100644 index 0000000000..d2f218fb8d --- /dev/null +++ b/test/hydration/samples/head-meta-hydrate-duplicate/_before_head.html @@ -0,0 +1,4 @@ +Some Title + + + \ No newline at end of file diff --git a/test/hydration/samples/head-meta-hydrate-duplicate/_config.js b/test/hydration/samples/head-meta-hydrate-duplicate/_config.js new file mode 100644 index 0000000000..482efd564d --- /dev/null +++ b/test/hydration/samples/head-meta-hydrate-duplicate/_config.js @@ -0,0 +1,5 @@ +export default { + test(assert, target, snapshot, component, window) { + assert.equal(window.document.querySelectorAll('meta').length, 2); + } +}; diff --git a/test/hydration/samples/head-meta-hydrate-duplicate/main.svelte b/test/hydration/samples/head-meta-hydrate-duplicate/main.svelte new file mode 100644 index 0000000000..1a8b125dd2 --- /dev/null +++ b/test/hydration/samples/head-meta-hydrate-duplicate/main.svelte @@ -0,0 +1,8 @@ + + Some Title + + + + + +
Just a dummy page.
\ No newline at end of file diff --git a/test/server-side-rendering/samples/head-meta-hydrate-duplicate/_expected-head.html b/test/server-side-rendering/samples/head-meta-hydrate-duplicate/_expected-head.html new file mode 100644 index 0000000000..d2f218fb8d --- /dev/null +++ b/test/server-side-rendering/samples/head-meta-hydrate-duplicate/_expected-head.html @@ -0,0 +1,4 @@ +Some Title + + + \ No newline at end of file diff --git a/test/server-side-rendering/samples/head-meta-hydrate-duplicate/_expected.html b/test/server-side-rendering/samples/head-meta-hydrate-duplicate/_expected.html new file mode 100644 index 0000000000..a469e618fa --- /dev/null +++ b/test/server-side-rendering/samples/head-meta-hydrate-duplicate/_expected.html @@ -0,0 +1,3 @@ + + +
Just a dummy page.
\ No newline at end of file diff --git a/test/server-side-rendering/samples/head-meta-hydrate-duplicate/main.svelte b/test/server-side-rendering/samples/head-meta-hydrate-duplicate/main.svelte new file mode 100644 index 0000000000..1a8b125dd2 --- /dev/null +++ b/test/server-side-rendering/samples/head-meta-hydrate-duplicate/main.svelte @@ -0,0 +1,8 @@ + + Some Title + + + + + +
Just a dummy page.
\ No newline at end of file diff --git a/test/server-side-rendering/samples/head-multiple-title/_expected-head.html b/test/server-side-rendering/samples/head-multiple-title/_expected-head.html index af5c5feba4..7147550839 100644 --- a/test/server-side-rendering/samples/head-multiple-title/_expected-head.html +++ b/test/server-side-rendering/samples/head-multiple-title/_expected-head.html @@ -1 +1 @@ -B \ No newline at end of file +B \ No newline at end of file diff --git a/test/server-side-rendering/samples/head-title/_expected-head.html b/test/server-side-rendering/samples/head-title/_expected-head.html index 7d696352f9..6e73e671e6 100644 --- a/test/server-side-rendering/samples/head-title/_expected-head.html +++ b/test/server-side-rendering/samples/head-title/_expected-head.html @@ -1 +1 @@ -a custom title \ No newline at end of file +a custom title \ No newline at end of file From c97e8f81db1f77a623716c9bedaa382def1d653c Mon Sep 17 00:00:00 2001 From: Conduitry Date: Mon, 13 Jan 2020 11:59:06 -0500 Subject: [PATCH 33/79] -> v3.17.0 --- CHANGELOG.md | 2 +- package-lock.json | 2 +- package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4bacc5c26b..32012876a3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Svelte changelog -## Unreleased +## 3.17.0 * Remove old `` elements during hydration so they aren't duplicated ([#1607](https://github.com/sveltejs/svelte/issues/1607)) * Prevent text input cursor jumping in Safari with one-way binding ([#3449](https://github.com/sveltejs/svelte/issues/3449)) diff --git a/package-lock.json b/package-lock.json index 6dc707c8d5..9ee0b53af6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "svelte", - "version": "3.16.7", + "version": "3.17.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 9c249f499f..2c5edf9437 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "svelte", - "version": "3.16.7", + "version": "3.17.0", "description": "Cybernetically enhanced web apps", "module": "index.mjs", "main": "index", From 7494509dfd67011f0cb73aa8b77c729b3dab46f5 Mon Sep 17 00:00:00 2001 From: Conduitry Date: Tue, 14 Jan 2020 12:11:52 -0500 Subject: [PATCH 34/79] only attach SSR markers when hydratable: true (#4260) --- CHANGELOG.md | 4 +++ site/content/docs/03-run-time.md | 2 +- site/content/docs/04-compile-time.md | 2 +- .../compile/render_ssr/handlers/Element.ts | 2 +- .../compile/render_ssr/handlers/Title.ts | 6 +++- test/helpers.js | 6 ++++ test/runtime/index.js | 7 ++-- test/server-side-rendering/index.js | 34 ++++++++++++------- .../head-meta-hydrate-duplicate/_config.js | 5 +++ .../head-multiple-title/_expected-head.html | 2 +- .../samples/head-title/_expected-head.html | 2 +- 11 files changed, 48 insertions(+), 24 deletions(-) create mode 100644 test/server-side-rendering/samples/head-meta-hydrate-duplicate/_config.js diff --git a/CHANGELOG.md b/CHANGELOG.md index 32012876a3..480c145a95 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Svelte changelog +## Unreleased + +* Only attach SSR mode markers to a component's `` elements when compiling with `hydratable: true` ([#4258](https://github.com/sveltejs/svelte/issues/4258)) + ## 3.17.0 * Remove old `` elements during hydration so they aren't duplicated ([#1607](https://github.com/sveltejs/svelte/issues/1607)) diff --git a/site/content/docs/03-run-time.md b/site/content/docs/03-run-time.md index e1509cf4d1..c75ec694d9 100644 --- a/site/content/docs/03-run-time.md +++ b/site/content/docs/03-run-time.md @@ -887,7 +887,7 @@ Existing children of `target` are left where they are. --- -The `hydrate` option instructs Svelte to upgrade existing DOM (usually from server-side rendering) rather than creating new elements. It will only work if the component was compiled with the [`hydratable: true` option](docs#svelte_compile). +The `hydrate` option instructs Svelte to upgrade existing DOM (usually from server-side rendering) rather than creating new elements. It will only work if the component was compiled with the [`hydratable: true` option](docs#svelte_compile). Hydration of `` elements only works properly if the server-side rendering code was also compiled with `hydratable: true`, which adds a marker to each element in the `` so that the component knows which elements it's responsible for removing during hydration. Whereas children of `target` are normally left alone, `hydrate: true` will cause any children to be removed. For that reason, the `anchor` option cannot be used alongside `hydrate: true`. diff --git a/site/content/docs/04-compile-time.md b/site/content/docs/04-compile-time.md index e9126ccf13..f753b2fcfe 100644 --- a/site/content/docs/04-compile-time.md +++ b/site/content/docs/04-compile-time.md @@ -68,7 +68,7 @@ The following options can be passed to the compiler. None are required: | `generate` | `"dom"` | If `"dom"`, Svelte emits a JavaScript class for mounting to the DOM. If `"ssr"`, Svelte emits an object with a `render` method suitable for server-side rendering. If `false`, no JavaScript or CSS is returned; just metadata. | `dev` | `false` | If `true`, causes extra code to be added to components that will perform runtime checks and provide debugging information during development. | `immutable` | `false` | If `true`, tells the compiler that you promise not to mutate any objects. This allows it to be less conservative about checking whether values have changed. -| `hydratable` | `false` | If `true`, enables the `hydrate: true` runtime option, which allows a component to upgrade existing DOM rather than creating new DOM from scratch. +| `hydratable` | `false` | If `true` when generating DOM code, enables the `hydrate: true` runtime option, which allows a component to upgrade existing DOM rather than creating new DOM from scratch. When generating SSR code, this adds markers to `` elements so that hydration knows which to replace. | `legacy` | `false` | If `true`, generates code that will work in IE9 and IE10, which don't support things like `element.dataset`. | `accessors` | `false` | If `true`, getters and setters will be created for the component's props. If `false`, they will only be created for readonly exported values (i.e. those declared with `const`, `class` and `function`). If compiling with `customElement: true` this option defaults to `true`. | `customElement` | `false` | If `true`, tells the compiler to generate a custom element constructor instead of a regular Svelte component. diff --git a/src/compiler/compile/render_ssr/handlers/Element.ts b/src/compiler/compile/render_ssr/handlers/Element.ts index 4c1eca8a9d..e0982a0415 100644 --- a/src/compiler/compile/render_ssr/handlers/Element.ts +++ b/src/compiler/compile/render_ssr/handlers/Element.ts @@ -124,7 +124,7 @@ export default function(node: Element, renderer: Renderer, options: RenderOption } }); - if (options.head_id) { + if (options.hydratable && options.head_id) { renderer.add_string(` data-svelte="${options.head_id}"`); } diff --git a/src/compiler/compile/render_ssr/handlers/Title.ts b/src/compiler/compile/render_ssr/handlers/Title.ts index e93ae13d66..a3f271ab1b 100644 --- a/src/compiler/compile/render_ssr/handlers/Title.ts +++ b/src/compiler/compile/render_ssr/handlers/Title.ts @@ -5,7 +5,11 @@ import { x } from 'code-red'; export default function(node: Title, renderer: Renderer, options: RenderOptions) { renderer.push(); - renderer.add_string(``); + renderer.add_string('<title'); + if (options.hydratable && options.head_id) { + renderer.add_string(` data-svelte="${options.head_id}"`); + } + renderer.add_string('>'); renderer.render(node.children, options); diff --git a/test/helpers.js b/test/helpers.js index 5e9428243b..a764d43f96 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -45,6 +45,12 @@ export function tryToReadFile(file) { } } +export function cleanRequireCache() { + Object.keys(require.cache) + .filter(x => x.endsWith('.svelte')) + .forEach(file => delete require.cache[file]); +} + const virtualConsole = new jsdom.VirtualConsole(); virtualConsole.sendTo(console); diff --git a/test/runtime/index.js b/test/runtime/index.js index df02cabcb4..f070eb8185 100644 --- a/test/runtime/index.js +++ b/test/runtime/index.js @@ -10,6 +10,7 @@ import { showOutput, loadConfig, loadSvelte, + cleanRequireCache, env, setupHtmlEqual, mkdirp @@ -79,11 +80,7 @@ describe("runtime", () => { compileOptions.immutable = config.immutable; compileOptions.accessors = 'accessors' in config ? config.accessors : true; - Object.keys(require.cache) - .filter(x => x.endsWith('.svelte')) - .forEach(file => { - delete require.cache[file]; - }); + cleanRequireCache(); let mod; let SvelteComponent; diff --git a/test/server-side-rendering/index.js b/test/server-side-rendering/index.js index a56a4ddaed..ee1319845d 100644 --- a/test/server-side-rendering/index.js +++ b/test/server-side-rendering/index.js @@ -9,6 +9,7 @@ import { loadSvelte, setupHtmlEqual, tryToLoadJson, + cleanRequireCache, shouldUpdateExpected, mkdirp } from "../helpers.js"; @@ -27,11 +28,6 @@ let compile = null; describe("ssr", () => { before(() => { - require("../../register")({ - extensions: ['.svelte', '.html'], - sveltePath - }); - compile = loadSvelte(true).compile; return setupHtmlEqual(); @@ -40,9 +36,11 @@ describe("ssr", () => { fs.readdirSync(`${__dirname}/samples`).forEach(dir => { if (dir[0] === ".") return; + const config = loadConfig(`${__dirname}/samples/${dir}/_config.js`); + // add .solo to a sample directory name to only run that test, or // .show to always show the output. or both - const solo = /\.solo/.test(dir); + const solo = config.solo || /\.solo/.test(dir); const show = /\.show/.test(dir); if (solo && process.env.CI) { @@ -51,6 +49,18 @@ describe("ssr", () => { (solo ? it.only : it)(dir, () => { dir = path.resolve(`${__dirname}/samples`, dir); + + cleanRequireCache(); + + const compileOptions = { + sveltePath, + ...config.compileOptions, + generate: 'ssr', + format: 'cjs' + }; + + require("../../register")(compileOptions); + try { const Component = require(`${dir}/main.svelte`).default; @@ -133,18 +143,16 @@ describe("ssr", () => { (config.skip ? it.skip : solo ? it.only : it)(dir, () => { const cwd = path.resolve("test/runtime/samples", dir); - Object.keys(require.cache) - .filter(x => x.endsWith('.svelte')) - .forEach(file => { - delete require.cache[file]; - }); + cleanRequireCache(); delete global.window; - const compileOptions = Object.assign({ sveltePath }, config.compileOptions, { + const compileOptions = { + sveltePath, + ...config.compileOptions, generate: 'ssr', format: 'cjs' - }); + }; require("../../register")(compileOptions); diff --git a/test/server-side-rendering/samples/head-meta-hydrate-duplicate/_config.js b/test/server-side-rendering/samples/head-meta-hydrate-duplicate/_config.js new file mode 100644 index 0000000000..ae9b250f86 --- /dev/null +++ b/test/server-side-rendering/samples/head-meta-hydrate-duplicate/_config.js @@ -0,0 +1,5 @@ +export default { + compileOptions: { + hydratable: true + } +}; diff --git a/test/server-side-rendering/samples/head-multiple-title/_expected-head.html b/test/server-side-rendering/samples/head-multiple-title/_expected-head.html index 7147550839..af5c5feba4 100644 --- a/test/server-side-rendering/samples/head-multiple-title/_expected-head.html +++ b/test/server-side-rendering/samples/head-multiple-title/_expected-head.html @@ -1 +1 @@ -<title data-svelte="svelte-1csszk6">B \ No newline at end of file +B \ No newline at end of file diff --git a/test/server-side-rendering/samples/head-title/_expected-head.html b/test/server-side-rendering/samples/head-title/_expected-head.html index 6e73e671e6..7d696352f9 100644 --- a/test/server-side-rendering/samples/head-title/_expected-head.html +++ b/test/server-side-rendering/samples/head-title/_expected-head.html @@ -1 +1 @@ -a custom title \ No newline at end of file +a custom title \ No newline at end of file From 4e812a95e9abce3d68c53b33ad86fb91bbbe4773 Mon Sep 17 00:00:00 2001 From: Conduitry Date: Tue, 14 Jan 2020 12:16:52 -0500 Subject: [PATCH 35/79] -> v3.17.1 --- .vscode/settings.json | 1 + CHANGELOG.md | 2 +- package.json | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) create mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000000..1fe67481c7 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1 @@ +{"files.insertFinalNewline":false} diff --git a/CHANGELOG.md b/CHANGELOG.md index 480c145a95..dce6d47858 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Svelte changelog -## Unreleased +## 3.17.1 * Only attach SSR mode markers to a component's `` elements when compiling with `hydratable: true` ([#4258](https://github.com/sveltejs/svelte/issues/4258)) diff --git a/package.json b/package.json index 2c5edf9437..c7ac32f3ae 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "svelte", - "version": "3.17.0", + "version": "3.17.1", "description": "Cybernetically enhanced web apps", "module": "index.mjs", "main": "index", From bfff7a9d0e67804e7a0db04ed4fb4b9a6078d0ec Mon Sep 17 00:00:00 2001 From: Conduitry Date: Tue, 14 Jan 2020 16:03:20 -0500 Subject: [PATCH 36/79] oops --- .vscode/settings.json | 1 - 1 file changed, 1 deletion(-) delete mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 1fe67481c7..0000000000 --- a/.vscode/settings.json +++ /dev/null @@ -1 +0,0 @@ -{"files.insertFinalNewline":false} From 8b9b2c266e55c7a3e589a32cecf8f208e430c10a Mon Sep 17 00:00:00 2001 From: Tan Li Hau Date: Thu, 16 Jan 2020 22:25:12 +0800 Subject: [PATCH 37/79] fix allow let scoped to root element (#4266) --- CHANGELOG.md | 4 +++ src/compiler/compile/nodes/Element.ts | 31 +++++++++---------- .../samples/component-slot-let-g/A.svelte | 5 +++ .../samples/component-slot-let-g/_config.js | 22 +++++++++++++ .../samples/component-slot-let-g/main.svelte | 17 ++++++++++ 5 files changed, 63 insertions(+), 16 deletions(-) create mode 100644 test/runtime/samples/component-slot-let-g/A.svelte create mode 100644 test/runtime/samples/component-slot-let-g/_config.js create mode 100644 test/runtime/samples/component-slot-let-g/main.svelte diff --git a/CHANGELOG.md b/CHANGELOG.md index dce6d47858..1f93815185 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Svelte changelog +## Unreleased + +* Allow access to `let:` variables in sibling attributes on slot root ([#4173](https://github.com/sveltejs/svelte/issues/4173)) + ## 3.17.1 * Only attach SSR mode markers to a component's `` elements when compiling with `hydratable: true` ([#4258](https://github.com/sveltejs/svelte/issues/4258)) diff --git a/src/compiler/compile/nodes/Element.ts b/src/compiler/compile/nodes/Element.ts index a3b8dc7286..e8108858c5 100644 --- a/src/compiler/compile/nodes/Element.ts +++ b/src/compiler/compile/nodes/Element.ts @@ -151,6 +151,11 @@ export default class Element extends Node { } } + const has_let = info.attributes.some(node => node.type === 'Let'); + if (has_let) { + scope = scope.child(); + } + // Binding relies on Attribute, defer its evaluation const order = ['Binding']; // everything else is -1 info.attributes.sort((a, b) => order.indexOf(a.type) - order.indexOf(b.type)); @@ -181,9 +186,16 @@ export default class Element extends Node { this.handlers.push(new EventHandler(component, this, scope, node)); break; - case 'Let': - this.lets.push(new Let(component, this, scope, node)); + case 'Let': { + const l = new Let(component, this, scope, node); + this.lets.push(l); + const dependencies = new Set([l.name.name]); + + l.names.forEach(name => { + scope.add(name, dependencies, this); + }); break; + } case 'Transition': { @@ -202,20 +214,7 @@ export default class Element extends Node { } }); - if (this.lets.length > 0) { - this.scope = scope.child(); - - this.lets.forEach(l => { - const dependencies = new Set([l.name.name]); - - l.names.forEach(name => { - this.scope.add(name, dependencies, this); - }); - }); - } else { - this.scope = scope; - } - + this.scope = scope; this.children = map_children(component, this, this.scope, info.children); this.validate(); diff --git a/test/runtime/samples/component-slot-let-g/A.svelte b/test/runtime/samples/component-slot-let-g/A.svelte new file mode 100644 index 0000000000..4f4ac95014 --- /dev/null +++ b/test/runtime/samples/component-slot-let-g/A.svelte @@ -0,0 +1,5 @@ + + + \ No newline at end of file diff --git a/test/runtime/samples/component-slot-let-g/_config.js b/test/runtime/samples/component-slot-let-g/_config.js new file mode 100644 index 0000000000..aaa9895ea8 --- /dev/null +++ b/test/runtime/samples/component-slot-let-g/_config.js @@ -0,0 +1,22 @@ +export default { + html: ` + 1 + 0 + `, + async test({ assert, target, component, window }) { + component.x = 2; + + assert.htmlEqual(target.innerHTML, ` + 2 + 0 + `); + + const span = target.querySelector('span'); + await span.dispatchEvent(new window.MouseEvent('click')); + + assert.htmlEqual(target.innerHTML, ` + 2 + 2 + `); + } +}; diff --git a/test/runtime/samples/component-slot-let-g/main.svelte b/test/runtime/samples/component-slot-let-g/main.svelte new file mode 100644 index 0000000000..e7d4890e6b --- /dev/null +++ b/test/runtime/samples/component-slot-let-g/main.svelte @@ -0,0 +1,17 @@ + + +
+ y = reflected} + slot="foo" + let:reflected + class={reflected} + > + {reflected} + + +{ y } \ No newline at end of file From 2fd593f9d55d242cfcd4a6aafa09ce919d05ba7c Mon Sep 17 00:00:00 2001 From: John Muhl Date: Thu, 16 Jan 2020 20:27:43 -0600 Subject: [PATCH 38/79] Add more globals --- src/compiler/utils/names.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/compiler/utils/names.ts b/src/compiler/utils/names.ts index 88d4d4a319..02cc12e087 100644 --- a/src/compiler/utils/names.ts +++ b/src/compiler/utils/names.ts @@ -5,6 +5,8 @@ export const globals = new Set([ 'alert', 'Array', 'Boolean', + 'clearInterval', + 'clearTimeout', 'confirm', 'console', 'Date', @@ -16,6 +18,9 @@ export const globals = new Set([ 'Error', 'EvalError', 'Event', + 'fetch', + 'global', + 'globalThis', 'history', 'Infinity', 'InternalError', @@ -41,11 +46,14 @@ export const globals = new Set([ 'RegExp', 'sessionStorage', 'Set', + 'setInterval', + 'setTimeout', 'String', 'SyntaxError', 'TypeError', 'undefined', 'URIError', + 'URL', 'window' ]); From 1438994bd4f51633ba5c869c26d16be2e8224213 Mon Sep 17 00:00:00 2001 From: Conduitry Date: Thu, 16 Jan 2020 22:13:41 -0500 Subject: [PATCH 39/79] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1f93815185..f833dfae2a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## Unreleased * Allow access to `let:` variables in sibling attributes on slot root ([#4173](https://github.com/sveltejs/svelte/issues/4173)) +* Add some more known globals ([#4276](https://github.com/sveltejs/svelte/pull/4276)) ## 3.17.1 From 527ddea289196f3dc4c8ca5e0d001b9c7e5ce2a0 Mon Sep 17 00:00:00 2001 From: Tan Li Hau Date: Fri, 17 Jan 2020 08:07:48 +0800 Subject: [PATCH 40/79] disallow binding variables declared in await and catch --- src/compiler/compile/nodes/Binding.ts | 7 +++++++ src/compiler/compile/nodes/shared/TemplateScope.ts | 5 +++++ test/validator/samples/binding-await-catch/errors.json | 9 +++++++++ test/validator/samples/binding-await-catch/input.svelte | 7 +++++++ test/validator/samples/binding-await-then-2/errors.json | 9 +++++++++ test/validator/samples/binding-await-then-2/input.svelte | 7 +++++++ test/validator/samples/binding-await-then/errors.json | 9 +++++++++ test/validator/samples/binding-await-then/input.svelte | 6 ++++++ 8 files changed, 59 insertions(+) create mode 100644 test/validator/samples/binding-await-catch/errors.json create mode 100644 test/validator/samples/binding-await-catch/input.svelte create mode 100644 test/validator/samples/binding-await-then-2/errors.json create mode 100644 test/validator/samples/binding-await-then-2/input.svelte create mode 100644 test/validator/samples/binding-await-then/errors.json create mode 100644 test/validator/samples/binding-await-then/input.svelte diff --git a/src/compiler/compile/nodes/Binding.ts b/src/compiler/compile/nodes/Binding.ts index 28e6af5aa1..7d6fad0a81 100644 --- a/src/compiler/compile/nodes/Binding.ts +++ b/src/compiler/compile/nodes/Binding.ts @@ -50,6 +50,13 @@ export default class Binding extends Node { message: 'Cannot bind to a variable declared with the let: directive' }); } else if (this.is_contextual) { + if (scope.is_await(name)) { + component.error(this, { + code: 'invalid-binding', + message: 'Cannot bind to a variable declared with {#await ... then} or {:catch} blocks' + }); + } + scope.dependencies_for_name.get(name).forEach(name => { const variable = component.var_lookup.get(name); if (variable) { diff --git a/src/compiler/compile/nodes/shared/TemplateScope.ts b/src/compiler/compile/nodes/shared/TemplateScope.ts index 5f30d0c883..4e087eedf5 100644 --- a/src/compiler/compile/nodes/shared/TemplateScope.ts +++ b/src/compiler/compile/nodes/shared/TemplateScope.ts @@ -42,4 +42,9 @@ export default class TemplateScope { const owner = this.get_owner(name); return owner && (owner.type === 'Element' || owner.type === 'InlineComponent'); } + + is_await(name: string) { + const owner = this.get_owner(name); + return owner && (owner.type === 'ThenBlock' || owner.type === 'CatchBlock'); + } } diff --git a/test/validator/samples/binding-await-catch/errors.json b/test/validator/samples/binding-await-catch/errors.json new file mode 100644 index 0000000000..00141686f3 --- /dev/null +++ b/test/validator/samples/binding-await-catch/errors.json @@ -0,0 +1,9 @@ +[ + { + "code": "invalid-binding", + "message": "Cannot bind to a variable declared with {#await ... then} or {:catch} blocks", + "pos": 79, + "start": { "line": 6, "column": 9, "character": 79 }, + "end": { "line": 6, "column": 27, "character": 97 } + } +] diff --git a/test/validator/samples/binding-await-catch/input.svelte b/test/validator/samples/binding-await-catch/input.svelte new file mode 100644 index 0000000000..b640f6305b --- /dev/null +++ b/test/validator/samples/binding-await-catch/input.svelte @@ -0,0 +1,7 @@ + +{#await promise} +{:catch error} + +{/await} diff --git a/test/validator/samples/binding-await-then-2/errors.json b/test/validator/samples/binding-await-then-2/errors.json new file mode 100644 index 0000000000..e734ed4717 --- /dev/null +++ b/test/validator/samples/binding-await-then-2/errors.json @@ -0,0 +1,9 @@ +[ + { + "code": "invalid-binding", + "message": "Cannot bind to a variable declared with {#await ... then} or {:catch} blocks", + "pos": 78, + "start": { "line": 6, "column": 9, "character": 78 }, + "end": { "line": 6, "column": 19, "character": 88 } + } +] diff --git a/test/validator/samples/binding-await-then-2/input.svelte b/test/validator/samples/binding-await-then-2/input.svelte new file mode 100644 index 0000000000..e8c56c8e0b --- /dev/null +++ b/test/validator/samples/binding-await-then-2/input.svelte @@ -0,0 +1,7 @@ + +{#await promise} +{:then value} + +{/await} diff --git a/test/validator/samples/binding-await-then/errors.json b/test/validator/samples/binding-await-then/errors.json new file mode 100644 index 0000000000..a611e7731f --- /dev/null +++ b/test/validator/samples/binding-await-then/errors.json @@ -0,0 +1,9 @@ +[ + { + "code": "invalid-binding", + "message": "Cannot bind to a variable declared with {#await ... then} or {:catch} blocks", + "pos": 75, + "start": { "line": 5, "column": 9, "character": 75 }, + "end": { "line": 5, "column": 19, "character": 85 } + } +] diff --git a/test/validator/samples/binding-await-then/input.svelte b/test/validator/samples/binding-await-then/input.svelte new file mode 100644 index 0000000000..bc55ef97e4 --- /dev/null +++ b/test/validator/samples/binding-await-then/input.svelte @@ -0,0 +1,6 @@ + +{#await promise then value} + +{/await} From bda254e250e737a1dd7acf6c732d656ce52034a1 Mon Sep 17 00:00:00 2001 From: Conduitry Date: Thu, 16 Jan 2020 22:17:25 -0500 Subject: [PATCH 41/79] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f833dfae2a..bc6cf36109 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## Unreleased +* Disallow two-way binding to a variable declared by an `{#await}` block ([#4012](https://github.com/sveltejs/svelte/issues/4012)) * Allow access to `let:` variables in sibling attributes on slot root ([#4173](https://github.com/sveltejs/svelte/issues/4173)) * Add some more known globals ([#4276](https://github.com/sveltejs/svelte/pull/4276)) From b39282a9188027903fdb99cdf762b640f11c6cc1 Mon Sep 17 00:00:00 2001 From: Conduitry Date: Fri, 17 Jan 2020 07:22:40 -0500 Subject: [PATCH 42/79] apply event modifiers to events (#4279) --- CHANGELOG.md | 1 + .../compile/render_dom/wrappers/Body.ts | 25 ++++++++----------- .../wrappers/Element/EventHandler.ts | 3 ++- .../wrappers/shared/add_event_handlers.ts | 5 ++-- .../_config.js | 11 ++++++++ .../main.svelte | 5 ++++ 6 files changed, 33 insertions(+), 17 deletions(-) create mode 100644 test/runtime/samples/event-handler-modifier-body-once/_config.js create mode 100644 test/runtime/samples/event-handler-modifier-body-once/main.svelte diff --git a/CHANGELOG.md b/CHANGELOG.md index bc6cf36109..9b2c8f5b07 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ * Disallow two-way binding to a variable declared by an `{#await}` block ([#4012](https://github.com/sveltejs/svelte/issues/4012)) * Allow access to `let:` variables in sibling attributes on slot root ([#4173](https://github.com/sveltejs/svelte/issues/4173)) * Add some more known globals ([#4276](https://github.com/sveltejs/svelte/pull/4276)) +* Correctly apply event modifiers to `` events ([#4278](https://github.com/sveltejs/svelte/issues/4278)) ## 3.17.1 diff --git a/src/compiler/compile/render_dom/wrappers/Body.ts b/src/compiler/compile/render_dom/wrappers/Body.ts index e16ebc25bd..d80ef6c4a0 100644 --- a/src/compiler/compile/render_dom/wrappers/Body.ts +++ b/src/compiler/compile/render_dom/wrappers/Body.ts @@ -1,26 +1,23 @@ import Block from '../Block'; import Wrapper from './shared/Wrapper'; -import { b } from 'code-red'; +import { x } from 'code-red'; import Body from '../../nodes/Body'; import { Identifier } from 'estree'; import EventHandler from './Element/EventHandler'; +import add_event_handlers from './shared/add_event_handlers'; +import { TemplateNode } from '../../../interfaces'; +import Renderer from '../Renderer'; export default class BodyWrapper extends Wrapper { node: Body; + handlers: EventHandler[]; - render(block: Block, _parent_node: Identifier, _parent_nodes: Identifier) { - this.node.handlers - .map(handler => new EventHandler(handler, this)) - .forEach(handler => { - const snippet = handler.get_snippet(block); - - block.chunks.init.push(b` - @_document.body.addEventListener("${handler.node.name}", ${snippet}); - `); + constructor(renderer: Renderer, block: Block, parent: Wrapper, node: TemplateNode) { + super(renderer, block, parent, node); + this.handlers = this.node.handlers.map(handler => new EventHandler(handler, this)); + } - block.chunks.destroy.push(b` - @_document.body.removeEventListener("${handler.node.name}", ${snippet}); - `); - }); + render(block: Block, _parent_node: Identifier, _parent_nodes: Identifier) { + add_event_handlers(block, x`@_document.body`, this.handlers); } } diff --git a/src/compiler/compile/render_dom/wrappers/Element/EventHandler.ts b/src/compiler/compile/render_dom/wrappers/Element/EventHandler.ts index 03183ee576..157e186ea6 100644 --- a/src/compiler/compile/render_dom/wrappers/Element/EventHandler.ts +++ b/src/compiler/compile/render_dom/wrappers/Element/EventHandler.ts @@ -2,6 +2,7 @@ import EventHandler from '../../../nodes/EventHandler'; import Wrapper from '../shared/Wrapper'; import Block from '../../Block'; import { b, x, p } from 'code-red'; +import { Expression } from 'estree'; const TRUE = x`true`; const FALSE = x`false`; @@ -35,7 +36,7 @@ export default class EventHandlerWrapper { return snippet; } - render(block: Block, target: string) { + render(block: Block, target: string | Expression) { let snippet = this.get_snippet(block); if (this.node.modifiers.has('preventDefault')) snippet = x`@prevent_default(${snippet})`; diff --git a/src/compiler/compile/render_dom/wrappers/shared/add_event_handlers.ts b/src/compiler/compile/render_dom/wrappers/shared/add_event_handlers.ts index 23a37715cc..99b8080b17 100644 --- a/src/compiler/compile/render_dom/wrappers/shared/add_event_handlers.ts +++ b/src/compiler/compile/render_dom/wrappers/shared/add_event_handlers.ts @@ -1,9 +1,10 @@ import Block from '../../Block'; import EventHandler from '../Element/EventHandler'; +import { Expression } from 'estree'; export default function add_event_handlers( block: Block, - target: string, + target: string | Expression, handlers: EventHandler[] ) { handlers.forEach(handler => add_event_handler(block, target, handler)); @@ -11,7 +12,7 @@ export default function add_event_handlers( export function add_event_handler( block: Block, - target: string, + target: string | Expression, handler: EventHandler ) { handler.render(block, target); diff --git a/test/runtime/samples/event-handler-modifier-body-once/_config.js b/test/runtime/samples/event-handler-modifier-body-once/_config.js new file mode 100644 index 0000000000..4127034010 --- /dev/null +++ b/test/runtime/samples/event-handler-modifier-body-once/_config.js @@ -0,0 +1,11 @@ +export default { + async test({ assert, component, window }) { + const event = new window.MouseEvent('click'); + + await window.document.body.dispatchEvent(event); + assert.equal(component.count, 1); + + await window.document.body.dispatchEvent(event); + assert.equal(component.count, 1); + } +}; diff --git a/test/runtime/samples/event-handler-modifier-body-once/main.svelte b/test/runtime/samples/event-handler-modifier-body-once/main.svelte new file mode 100644 index 0000000000..423a75d1f0 --- /dev/null +++ b/test/runtime/samples/event-handler-modifier-body-once/main.svelte @@ -0,0 +1,5 @@ + + + \ No newline at end of file From 2f81365e44f585c28295cb3937910eef00a35b0e Mon Sep 17 00:00:00 2001 From: Conduitry Date: Sat, 18 Jan 2020 07:10:13 -0500 Subject: [PATCH 43/79] fix awaited expressions that need parentheses (#4283) --- CHANGELOG.md | 1 + package-lock.json | 8 ++++---- package.json | 2 +- test/js/samples/debug-empty/expected.js | 2 +- test/js/samples/debug-foo-bar-baz-things/expected.js | 2 +- test/js/samples/debug-foo/expected.js | 2 +- .../samples/dev-warning-missing-data-computed/expected.js | 2 +- 7 files changed, 10 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9b2c8f5b07..5264f35504 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ * Disallow two-way binding to a variable declared by an `{#await}` block ([#4012](https://github.com/sveltejs/svelte/issues/4012)) * Allow access to `let:` variables in sibling attributes on slot root ([#4173](https://github.com/sveltejs/svelte/issues/4173)) +* Fix code generation for `await`ed expressions that need parentheses ([#4267](https://github.com/sveltejs/svelte/issues/4267)) * Add some more known globals ([#4276](https://github.com/sveltejs/svelte/pull/4276)) * Correctly apply event modifiers to `` events ([#4278](https://github.com/sveltejs/svelte/issues/4278)) diff --git a/package-lock.json b/package-lock.json index 9ee0b53af6..4d902d5c48 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "svelte", - "version": "3.17.0", + "version": "3.17.1", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -597,9 +597,9 @@ "dev": true }, "code-red": { - "version": "0.0.28", - "resolved": "https://registry.npmjs.org/code-red/-/code-red-0.0.28.tgz", - "integrity": "sha512-k9L7Sp85HNt3f/CvfrZKXoZOaO0tWOJCw2kU5GKc/c5pDj52OgBa0J+krMRmYtnGzS2dk4Xrn0EjjsJaM51hWQ==", + "version": "0.0.30", + "resolved": "https://registry.npmjs.org/code-red/-/code-red-0.0.30.tgz", + "integrity": "sha512-nsScy3A59tbV5uzndcedIEGHmdWNEByJrC7DUyb0Wh7qZcoPfAlcYsr0ZINkAEhZofSI26F1mi+lRO0/6EV2/g==", "dev": true, "requires": { "acorn": "^7.1.0", diff --git a/package.json b/package.json index c7ac32f3ae..671a7e5025 100644 --- a/package.json +++ b/package.json @@ -70,7 +70,7 @@ "acorn": "^7.1.0", "agadoo": "^1.1.0", "c8": "^5.0.1", - "code-red": "0.0.28", + "code-red": "0.0.30", "codecov": "^3.5.0", "css-tree": "1.0.0-alpha22", "eslint": "^6.3.0", diff --git a/test/js/samples/debug-empty/expected.js b/test/js/samples/debug-empty/expected.js index 5821faadf1..358363c661 100644 --- a/test/js/samples/debug-empty/expected.js +++ b/test/js/samples/debug-empty/expected.js @@ -103,7 +103,7 @@ class Component extends SvelteComponentDev { }); const { ctx } = this.$$; - const props = options.props || ({}); + const props = options.props || {}; if (/*name*/ ctx[0] === undefined && !("name" in props)) { console.warn(" was created without expected prop 'name'"); diff --git a/test/js/samples/debug-foo-bar-baz-things/expected.js b/test/js/samples/debug-foo-bar-baz-things/expected.js index a1d6dba3b3..fc65c59eda 100644 --- a/test/js/samples/debug-foo-bar-baz-things/expected.js +++ b/test/js/samples/debug-foo-bar-baz-things/expected.js @@ -210,7 +210,7 @@ class Component extends SvelteComponentDev { }); const { ctx } = this.$$; - const props = options.props || ({}); + const props = options.props || {}; if (/*things*/ ctx[0] === undefined && !("things" in props)) { console.warn(" was created without expected prop 'things'"); diff --git a/test/js/samples/debug-foo/expected.js b/test/js/samples/debug-foo/expected.js index af79667cc2..710d6b2232 100644 --- a/test/js/samples/debug-foo/expected.js +++ b/test/js/samples/debug-foo/expected.js @@ -198,7 +198,7 @@ class Component extends SvelteComponentDev { }); const { ctx } = this.$$; - const props = options.props || ({}); + const props = options.props || {}; if (/*things*/ ctx[0] === undefined && !("things" in props)) { console.warn(" was created without expected prop 'things'"); diff --git a/test/js/samples/dev-warning-missing-data-computed/expected.js b/test/js/samples/dev-warning-missing-data-computed/expected.js index beb794a50c..cc16de67e6 100644 --- a/test/js/samples/dev-warning-missing-data-computed/expected.js +++ b/test/js/samples/dev-warning-missing-data-computed/expected.js @@ -107,7 +107,7 @@ class Component extends SvelteComponentDev { }); const { ctx } = this.$$; - const props = options.props || ({}); + const props = options.props || {}; if (/*foo*/ ctx[0] === undefined && !("foo" in props)) { console.warn(" was created without expected prop 'foo'"); From e4460e38ba58d5209514f0fa93dc61b6bb1ebb54 Mon Sep 17 00:00:00 2001 From: Conduitry Date: Sun, 19 Jan 2020 13:36:22 -0500 Subject: [PATCH 44/79] fix '~=' and class selectors with arbitrary whitespace (#4286) --- CHANGELOG.md | 1 + src/compiler/compile/css/Selector.ts | 6 +++--- .../expected.css | 1 + .../input.svelte | 13 +++++++++++++ 4 files changed, 18 insertions(+), 3 deletions(-) create mode 100644 test/css/samples/attribute-selector-word-arbitrary-whitespace/expected.css create mode 100644 test/css/samples/attribute-selector-word-arbitrary-whitespace/input.svelte diff --git a/CHANGELOG.md b/CHANGELOG.md index 5264f35504..5b0bb4751d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ * Disallow two-way binding to a variable declared by an `{#await}` block ([#4012](https://github.com/sveltejs/svelte/issues/4012)) * Allow access to `let:` variables in sibling attributes on slot root ([#4173](https://github.com/sveltejs/svelte/issues/4173)) +* Fix `~=` and class selector matching against values separated by any whitespace characters ([#4242](https://github.com/sveltejs/svelte/issues/4242)) * Fix code generation for `await`ed expressions that need parentheses ([#4267](https://github.com/sveltejs/svelte/issues/4267)) * Add some more known globals ([#4276](https://github.com/sveltejs/svelte/pull/4276)) * Correctly apply event modifiers to `` events ([#4278](https://github.com/sveltejs/svelte/issues/4278)) diff --git a/src/compiler/compile/css/Selector.ts b/src/compiler/compile/css/Selector.ts index eecb0cd975..39bbc2e8d1 100644 --- a/src/compiler/compile/css/Selector.ts +++ b/src/compiler/compile/css/Selector.ts @@ -171,7 +171,7 @@ function apply_selector(blocks: Block[], node: Element, stack: Element[], to_enc if (ancestor_block.global) { continue; } - + for (const stack_node of stack) { if (block_might_apply_to_node(ancestor_block, stack_node) !== BlockAppliesToNode.NotPossible) { to_encapsulate.push({ node: stack_node, block: ancestor_block }); @@ -256,7 +256,7 @@ function test_attribute(operator, expected_value, case_insensitive, value) { } switch (operator) { case '=': return value === expected_value; - case '~=': return ` ${value} `.includes(` ${expected_value} `); + case '~=': return value.split(/\s/).includes(expected_value); case '|=': return `${value}-`.startsWith(`${expected_value}-`); case '^=': return value.startsWith(expected_value); case '$=': return value.endsWith(expected_value); @@ -295,7 +295,7 @@ function attribute_matches(node: CssNode, name: string, expected_value: string, // impossible to find out all combinations if (current_possible_values.has(UNKNOWN)) return true; - + if (prev_values.length > 0) { const start_with_space = []; const remaining = []; diff --git a/test/css/samples/attribute-selector-word-arbitrary-whitespace/expected.css b/test/css/samples/attribute-selector-word-arbitrary-whitespace/expected.css new file mode 100644 index 0000000000..c1c0f3fdf6 --- /dev/null +++ b/test/css/samples/attribute-selector-word-arbitrary-whitespace/expected.css @@ -0,0 +1 @@ +.foo.svelte-xyz{color:red}[class~="bar"].svelte-xyz{background:blue} \ No newline at end of file diff --git a/test/css/samples/attribute-selector-word-arbitrary-whitespace/input.svelte b/test/css/samples/attribute-selector-word-arbitrary-whitespace/input.svelte new file mode 100644 index 0000000000..758aa27e0b --- /dev/null +++ b/test/css/samples/attribute-selector-word-arbitrary-whitespace/input.svelte @@ -0,0 +1,13 @@ +
+ + From 33c3a02ee4b9ac3ee9d9dbec1c7328db0d49d6c0 Mon Sep 17 00:00:00 2001 From: Conduitry Date: Mon, 20 Jan 2020 10:31:31 -0500 Subject: [PATCH 45/79] failing test --- test/hydration/samples/element-attribute-removed/_before.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/hydration/samples/element-attribute-removed/_before.html b/test/hydration/samples/element-attribute-removed/_before.html index c6a8a8c95d..80c0591a4d 100644 --- a/test/hydration/samples/element-attribute-removed/_before.html +++ b/test/hydration/samples/element-attribute-removed/_before.html @@ -1 +1 @@ -
\ No newline at end of file +
\ No newline at end of file From 91e0d1b720e209833f11e894b956ea361ef8878a Mon Sep 17 00:00:00 2001 From: Conduitry Date: Mon, 20 Jan 2020 10:34:29 -0500 Subject: [PATCH 46/79] fix removing attributes during hydration (#1733) --- src/runtime/internal/dom.ts | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/runtime/internal/dom.ts b/src/runtime/internal/dom.ts index f9e89f41b9..5a165136ce 100644 --- a/src/runtime/internal/dom.ts +++ b/src/runtime/internal/dom.ts @@ -152,11 +152,16 @@ export function claim_element(nodes, name, attributes, svg) { for (let i = 0; i < nodes.length; i += 1) { const node = nodes[i]; if (node.nodeName === name) { - for (let j = 0; j < node.attributes.length; j += 1) { + let j = 0; + while (j < node.attributes.length) { const attribute = node.attributes[j]; - if (!attributes[attribute.name]) node.removeAttribute(attribute.name); + if (attributes[attribute.name]) { + j++; + } else { + node.removeAttribute(attribute.name); + } } - return nodes.splice(i, 1)[0]; // TODO strip unwanted attributes + return nodes.splice(i, 1)[0]; } } From b0415a269bb4918048508b97399f97a71f6499fe Mon Sep 17 00:00:00 2001 From: Conduitry Date: Mon, 20 Jan 2020 10:35:13 -0500 Subject: [PATCH 47/79] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5b0bb4751d..d9ec5900b4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## Unreleased +* Fix removing attributes during hydration ([#1733](https://github.com/sveltejs/svelte/issues/1733)) * Disallow two-way binding to a variable declared by an `{#await}` block ([#4012](https://github.com/sveltejs/svelte/issues/4012)) * Allow access to `let:` variables in sibling attributes on slot root ([#4173](https://github.com/sveltejs/svelte/issues/4173)) * Fix `~=` and class selector matching against values separated by any whitespace characters ([#4242](https://github.com/sveltejs/svelte/issues/4242)) From f12340acf02e6c8e7dc23cafe0469eb72d278fc8 Mon Sep 17 00:00:00 2001 From: Conduitry Date: Mon, 20 Jan 2020 21:17:24 -0500 Subject: [PATCH 48/79] preserve js comments where possible (#4293) --- CHANGELOG.md | 1 + package-lock.json | 6 +++--- package.json | 2 +- src/compiler/parse/acorn.ts | 9 ++++----- .../js/samples/action-custom-event-handler/expected.js | 2 +- .../samples/collapses-text-around-comments/expected.js | 2 +- test/js/samples/css-media-query/expected.js | 2 +- test/js/samples/event-modifiers/expected.js | 4 ++-- test/js/samples/ssr-no-oncreate-etc/expected.js | 2 +- test/parser/samples/script-comment-only/output.json | 10 +++++++++- .../script-comment-trailing-multiline/output.json | 10 +++++++++- .../parser/samples/script-comment-trailing/output.json | 10 +++++++++- 12 files changed, 42 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d9ec5900b4..59fa25682e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ * Allow access to `let:` variables in sibling attributes on slot root ([#4173](https://github.com/sveltejs/svelte/issues/4173)) * Fix `~=` and class selector matching against values separated by any whitespace characters ([#4242](https://github.com/sveltejs/svelte/issues/4242)) * Fix code generation for `await`ed expressions that need parentheses ([#4267](https://github.com/sveltejs/svelte/issues/4267)) +* Preserve JavaScript comments from the original component source where possible ([#4268](https://github.com/sveltejs/svelte/issues/4268)) * Add some more known globals ([#4276](https://github.com/sveltejs/svelte/pull/4276)) * Correctly apply event modifiers to `` events ([#4278](https://github.com/sveltejs/svelte/issues/4278)) diff --git a/package-lock.json b/package-lock.json index 4d902d5c48..90f5a331ed 100644 --- a/package-lock.json +++ b/package-lock.json @@ -597,9 +597,9 @@ "dev": true }, "code-red": { - "version": "0.0.30", - "resolved": "https://registry.npmjs.org/code-red/-/code-red-0.0.30.tgz", - "integrity": "sha512-nsScy3A59tbV5uzndcedIEGHmdWNEByJrC7DUyb0Wh7qZcoPfAlcYsr0ZINkAEhZofSI26F1mi+lRO0/6EV2/g==", + "version": "0.0.31", + "resolved": "https://registry.npmjs.org/code-red/-/code-red-0.0.31.tgz", + "integrity": "sha512-7Gf3vm8pDbs+H/hKsaqOZe0xKlE9Neah12GCfs7qun3fBUaOXwexAMjn0Eo9cvJJvhRMaL0jgPiY9ZGLTWoe8A==", "dev": true, "requires": { "acorn": "^7.1.0", diff --git a/package.json b/package.json index 671a7e5025..6a66276c2d 100644 --- a/package.json +++ b/package.json @@ -70,7 +70,7 @@ "acorn": "^7.1.0", "agadoo": "^1.1.0", "c8": "^5.0.1", - "code-red": "0.0.30", + "code-red": "0.0.31", "codecov": "^3.5.0", "css-tree": "1.0.0-alpha22", "eslint": "^6.3.0", diff --git a/src/compiler/parse/acorn.ts b/src/compiler/parse/acorn.ts index 30ab3c398c..d14721cdab 100644 --- a/src/compiler/parse/acorn.ts +++ b/src/compiler/parse/acorn.ts @@ -1,14 +1,13 @@ -import * as acorn from 'acorn'; +import { Node } from 'acorn'; +import * as code_red from 'code-red'; -const Parser = acorn.Parser; - -export const parse = (source: string) => Parser.parse(source, { +export const parse = (source: string): Node => code_red.parse(source, { sourceType: 'module', ecmaVersion: 11, locations: true }); -export const parse_expression_at = (source: string, index: number) => Parser.parseExpressionAt(source, index, { +export const parse_expression_at = (source: string, index: number): Node => code_red.parseExpressionAt(source, index, { ecmaVersion: 11, locations: true }); \ No newline at end of file diff --git a/test/js/samples/action-custom-event-handler/expected.js b/test/js/samples/action-custom-event-handler/expected.js index 968b5965d5..ead6d90e06 100644 --- a/test/js/samples/action-custom-event-handler/expected.js +++ b/test/js/samples/action-custom-event-handler/expected.js @@ -43,7 +43,7 @@ function handleFoo(bar) { function foo(node, callback) { -} +} // code goes here function instance($$self, $$props, $$invalidate) { let { bar } = $$props; diff --git a/test/js/samples/collapses-text-around-comments/expected.js b/test/js/samples/collapses-text-around-comments/expected.js index 8c0e9d5373..6fef0f9490 100644 --- a/test/js/samples/collapses-text-around-comments/expected.js +++ b/test/js/samples/collapses-text-around-comments/expected.js @@ -63,4 +63,4 @@ class Component extends SvelteComponent { } } -export default Component; +export default Component; \ No newline at end of file diff --git a/test/js/samples/css-media-query/expected.js b/test/js/samples/css-media-query/expected.js index 0566c22ddd..f477670059 100644 --- a/test/js/samples/css-media-query/expected.js +++ b/test/js/samples/css-media-query/expected.js @@ -46,4 +46,4 @@ class Component extends SvelteComponent { } } -export default Component; +export default Component; \ No newline at end of file diff --git a/test/js/samples/event-modifiers/expected.js b/test/js/samples/event-modifiers/expected.js index 252034a431..c12c3523a0 100644 --- a/test/js/samples/event-modifiers/expected.js +++ b/test/js/samples/event-modifiers/expected.js @@ -63,11 +63,11 @@ function create_fragment(ctx) { function handleTouchstart() { -} +} // ... function handleClick() { -} +} // ... class Component extends SvelteComponent { constructor(options) { diff --git a/test/js/samples/ssr-no-oncreate-etc/expected.js b/test/js/samples/ssr-no-oncreate-etc/expected.js index 276587eeca..803f06a882 100644 --- a/test/js/samples/ssr-no-oncreate-etc/expected.js +++ b/test/js/samples/ssr-no-oncreate-etc/expected.js @@ -13,7 +13,7 @@ function foo() { function swipe(node, callback) { -} +} // TODO implement const Component = create_ssr_component(($$result, $$props, $$bindings, $$slots) => { onMount(() => { diff --git a/test/parser/samples/script-comment-only/output.json b/test/parser/samples/script-comment-only/output.json index 3441d8a7bb..e090b30ae6 100644 --- a/test/parser/samples/script-comment-only/output.json +++ b/test/parser/samples/script-comment-only/output.json @@ -41,7 +41,15 @@ } }, "body": [], - "sourceType": "module" + "sourceType": "module", + "trailingComments": [ + { + "type": "Line", + "value": " TODO write some code", + "start": 10, + "end": 33 + } + ] } } } \ No newline at end of file diff --git a/test/parser/samples/script-comment-trailing-multiline/output.json b/test/parser/samples/script-comment-trailing-multiline/output.json index 3c02b1fbde..be83eeea8b 100644 --- a/test/parser/samples/script-comment-trailing-multiline/output.json +++ b/test/parser/samples/script-comment-trailing-multiline/output.json @@ -134,7 +134,15 @@ "kind": "let" } ], - "sourceType": "module" + "sourceType": "module", + "trailingComments": [ + { + "type": "Block", + "value": "\n\ttrailing multiline comment\n", + "start": 32, + "end": 67 + } + ] } } } \ No newline at end of file diff --git a/test/parser/samples/script-comment-trailing/output.json b/test/parser/samples/script-comment-trailing/output.json index beca001042..a2bc00bc00 100644 --- a/test/parser/samples/script-comment-trailing/output.json +++ b/test/parser/samples/script-comment-trailing/output.json @@ -134,7 +134,15 @@ "kind": "let" } ], - "sourceType": "module" + "sourceType": "module", + "trailingComments": [ + { + "type": "Line", + "value": " trailing line comment", + "start": 32, + "end": 56 + } + ] } } } \ No newline at end of file From e93c9913623ba43d8424191fe33f8bebb36e7dea Mon Sep 17 00:00:00 2001 From: Conduitry Date: Mon, 20 Jan 2020 21:18:15 -0500 Subject: [PATCH 49/79] -> v3.17.2 --- CHANGELOG.md | 2 +- package-lock.json | 2 +- package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 59fa25682e..92e61719d0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Svelte changelog -## Unreleased +## 3.17.2 * Fix removing attributes during hydration ([#1733](https://github.com/sveltejs/svelte/issues/1733)) * Disallow two-way binding to a variable declared by an `{#await}` block ([#4012](https://github.com/sveltejs/svelte/issues/4012)) diff --git a/package-lock.json b/package-lock.json index 90f5a331ed..ca225baa1b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "svelte", - "version": "3.17.1", + "version": "3.17.2", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 6a66276c2d..0910dca8c0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "svelte", - "version": "3.17.1", + "version": "3.17.2", "description": "Cybernetically enhanced web apps", "module": "index.mjs", "main": "index", From e4daaccd06cfe8fe1f4885fcb10942132153b521 Mon Sep 17 00:00:00 2001 From: Tan Li Hau Date: Wed, 22 Jan 2020 19:32:24 +0800 Subject: [PATCH 50/79] fix nested block not reactive (#4294) --- CHANGELOG.md | 4 +++ src/compiler/compile/render_dom/Block.ts | 3 ++ .../component-slot-nested-if/Display.svelte | 2 ++ .../component-slot-nested-if/Input.svelte | 6 ++++ .../component-slot-nested-if/_config.js | 30 +++++++++++++++++++ .../component-slot-nested-if/main.svelte | 10 +++++++ 6 files changed, 55 insertions(+) create mode 100644 test/runtime/samples/component-slot-nested-if/Display.svelte create mode 100644 test/runtime/samples/component-slot-nested-if/Input.svelte create mode 100644 test/runtime/samples/component-slot-nested-if/_config.js create mode 100644 test/runtime/samples/component-slot-nested-if/main.svelte diff --git a/CHANGELOG.md b/CHANGELOG.md index 92e61719d0..60153dcaba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Svelte changelog +## Unreleased + +* Fix updating a `` inside an `{#if}` or other block ([#4292](https://github.com/sveltejs/svelte/issues/4292)) + ## 3.17.2 * Fix removing attributes during hydration ([#1733](https://github.com/sveltejs/svelte/issues/1733)) diff --git a/src/compiler/compile/render_dom/Block.ts b/src/compiler/compile/render_dom/Block.ts index 68d28024fe..62bdc5bdd9 100644 --- a/src/compiler/compile/render_dom/Block.ts +++ b/src/compiler/compile/render_dom/Block.ts @@ -160,6 +160,9 @@ export default class Block { }); this.has_update_method = true; + if (this.parent) { + this.parent.add_dependencies(dependencies); + } } add_element( diff --git a/test/runtime/samples/component-slot-nested-if/Display.svelte b/test/runtime/samples/component-slot-nested-if/Display.svelte new file mode 100644 index 0000000000..d9034e4be2 --- /dev/null +++ b/test/runtime/samples/component-slot-nested-if/Display.svelte @@ -0,0 +1,2 @@ +Display: + \ No newline at end of file diff --git a/test/runtime/samples/component-slot-nested-if/Input.svelte b/test/runtime/samples/component-slot-nested-if/Input.svelte new file mode 100644 index 0000000000..fd8f22db00 --- /dev/null +++ b/test/runtime/samples/component-slot-nested-if/Input.svelte @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/test/runtime/samples/component-slot-nested-if/_config.js b/test/runtime/samples/component-slot-nested-if/_config.js new file mode 100644 index 0000000000..89dfd006cc --- /dev/null +++ b/test/runtime/samples/component-slot-nested-if/_config.js @@ -0,0 +1,30 @@ +export default { + html: ` + + `, + async test({ assert, target, snapshot, component, window }) { + const input = target.querySelector('input'); + + input.value = 'a'; + await input.dispatchEvent(new window.Event('input')); + + assert.htmlEqual( + target.innerHTML, + ` + + Display: a + ` + ); + + input.value = 'abc'; + await input.dispatchEvent(new window.Event('input')); + + assert.htmlEqual( + target.innerHTML, + ` + + Display: abc + ` + ); + }, +}; diff --git a/test/runtime/samples/component-slot-nested-if/main.svelte b/test/runtime/samples/component-slot-nested-if/main.svelte new file mode 100644 index 0000000000..727927b157 --- /dev/null +++ b/test/runtime/samples/component-slot-nested-if/main.svelte @@ -0,0 +1,10 @@ + + + + {#if foo} + {foo} + {/if} + From 5107ad38b6ce0e388cb2eb99361c5000c4b6de91 Mon Sep 17 00:00:00 2001 From: Conduitry Date: Wed, 22 Jan 2020 09:19:32 -0500 Subject: [PATCH 51/79] fix deriving from RxJS observables (#4300) --- CHANGELOG.md | 1 + src/runtime/internal/utils.ts | 4 ++-- src/runtime/store/index.ts | 5 +++-- test/store/index.js | 25 +++++++++++++++---------- 4 files changed, 21 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 60153dcaba..388fe61397 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## Unreleased * Fix updating a `` inside an `{#if}` or other block ([#4292](https://github.com/sveltejs/svelte/issues/4292)) +* Fix using RxJS observables in `derived` stores ([#4298](https://github.com/sveltejs/svelte/issues/4298)) ## 3.17.2 diff --git a/src/runtime/internal/utils.ts b/src/runtime/internal/utils.ts index c94a135869..c7722e1a07 100644 --- a/src/runtime/internal/utils.ts +++ b/src/runtime/internal/utils.ts @@ -48,8 +48,8 @@ export function validate_store(store, name) { } } -export function subscribe(store, callback) { - const unsub = store.subscribe(callback); +export function subscribe(store, ...callbacks) { + const unsub = store.subscribe(...callbacks); return unsub.unsubscribe ? () => unsub.unsubscribe() : unsub; } diff --git a/src/runtime/store/index.ts b/src/runtime/store/index.ts index 64a63d4179..2bbfdfcd60 100644 --- a/src/runtime/store/index.ts +++ b/src/runtime/store/index.ts @@ -1,4 +1,4 @@ -import { run_all, noop, safe_not_equal, is_function, get_store_value } from 'svelte/internal'; +import { run_all, subscribe, noop, safe_not_equal, is_function, get_store_value } from 'svelte/internal'; /** Callback to inform of a value updates. */ type Subscriber = (value: T) => void; @@ -173,7 +173,8 @@ export function derived(stores: Stores, fn: Function, initial_value?: T): Rea } }; - const unsubscribers = stores_array.map((store, i) => store.subscribe( + const unsubscribers = stores_array.map((store, i) => subscribe( + store, (value) => { values[i] = value; pending &= ~(1 << i); diff --git a/test/store/index.js b/test/store/index.js index a39fab86e6..2af4a6f35d 100644 --- a/test/store/index.js +++ b/test/store/index.js @@ -116,6 +116,15 @@ describe('store', () => { }); }); + const fake_observable = { + subscribe(fn) { + fn(42); + return { + unsubscribe: () => {} + }; + } + }; + describe('derived', () => { it('maps a single store', () => { const a = writable(1); @@ -346,6 +355,11 @@ describe('store', () => { b.set(2); assert.deepEqual(get(c), 'two 2'); }); + + it('works with RxJS-style observables', () => { + const d = derived(fake_observable, _ => _); + assert.equal(get(d), 42); + }); }); describe('get', () => { @@ -355,16 +369,7 @@ describe('store', () => { }); it('works with RxJS-style observables', () => { - const observable = { - subscribe(fn) { - fn(42); - return { - unsubscribe: () => {} - }; - } - }; - - assert.equal(get(observable), 42); + assert.equal(get(fake_observable), 42); }); }); }); From 1a343b165c577429e968cea48607cccabf714b9b Mon Sep 17 00:00:00 2001 From: Conduitry Date: Wed, 22 Jan 2020 11:05:31 -0500 Subject: [PATCH 52/79] disallow duplicate each keys in dev mode (#4303) --- CHANGELOG.md | 1 + .../compile/render_dom/wrappers/EachBlock.ts | 2 ++ src/runtime/internal/keyed_each.ts | 14 +++++++++----- .../samples/keyed-each-dev-unique/_config.js | 7 +++++++ .../samples/keyed-each-dev-unique/main.svelte | 7 +++++++ 5 files changed, 26 insertions(+), 5 deletions(-) create mode 100644 test/runtime/samples/keyed-each-dev-unique/_config.js create mode 100644 test/runtime/samples/keyed-each-dev-unique/main.svelte diff --git a/CHANGELOG.md b/CHANGELOG.md index 388fe61397..5838dcac80 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ * Fix updating a `` inside an `{#if}` or other block ([#4292](https://github.com/sveltejs/svelte/issues/4292)) * Fix using RxJS observables in `derived` stores ([#4298](https://github.com/sveltejs/svelte/issues/4298)) +* Add dev mode check to disallow duplicate keys in a keyed `{#each}` ([#4301](https://github.com/sveltejs/svelte/issues/4301)) ## 3.17.2 diff --git a/src/compiler/compile/render_dom/wrappers/EachBlock.ts b/src/compiler/compile/render_dom/wrappers/EachBlock.ts index 4928b5a38c..639a8831bd 100644 --- a/src/compiler/compile/render_dom/wrappers/EachBlock.ts +++ b/src/compiler/compile/render_dom/wrappers/EachBlock.ts @@ -374,6 +374,7 @@ export default class EachBlockWrapper extends Wrapper { block.chunks.init.push(b` const ${get_key} = #ctx => ${this.node.key.manipulate(block)}; + ${this.renderer.options.dev && b`@validate_each_keys(#ctx, ${this.vars.each_block_value}, ${this.vars.get_each_context}, ${get_key});`} for (let #i = 0; #i < ${data_length}; #i += 1) { let child_ctx = ${this.vars.get_each_context}(#ctx, ${this.vars.each_block_value}, #i); let key = ${get_key}(child_ctx); @@ -416,6 +417,7 @@ export default class EachBlockWrapper extends Wrapper { ${this.block.has_outros && b`@group_outros();`} ${this.node.has_animation && b`for (let #i = 0; #i < ${view_length}; #i += 1) ${iterations}[#i].r();`} + ${this.renderer.options.dev && b`@validate_each_keys(#ctx, ${this.vars.each_block_value}, ${this.vars.get_each_context}, ${get_key});`} ${iterations} = @update_keyed_each(${iterations}, #dirty, ${get_key}, ${dynamic ? 1 : 0}, #ctx, ${this.vars.each_block_value}, ${lookup}, ${update_mount_node}, ${destroy}, ${create_each_block}, ${update_anchor_node}, ${this.vars.get_each_context}); ${this.node.has_animation && b`for (let #i = 0; #i < ${view_length}; #i += 1) ${iterations}[#i].a();`} ${this.block.has_outros && b`@check_outros();`} diff --git a/src/runtime/internal/keyed_each.ts b/src/runtime/internal/keyed_each.ts index 8382a2f76a..b397335c87 100644 --- a/src/runtime/internal/keyed_each.ts +++ b/src/runtime/internal/keyed_each.ts @@ -108,9 +108,13 @@ export function update_keyed_each(old_blocks, dirty, get_key, dynamic, ctx, list return new_blocks; } -export function measure(blocks) { - const rects = {}; - let i = blocks.length; - while (i--) rects[blocks[i].key] = blocks[i].node.getBoundingClientRect(); - return rects; +export function validate_each_keys(ctx, list, get_context, get_key) { + const keys = new Set(); + for (let i = 0; i < list.length; i++) { + const key = get_key(get_context(ctx, list, i)); + if (keys.has(key)) { + throw new Error(`Cannot have duplicate keys in a keyed each`); + } + keys.add(key); + } } diff --git a/test/runtime/samples/keyed-each-dev-unique/_config.js b/test/runtime/samples/keyed-each-dev-unique/_config.js new file mode 100644 index 0000000000..8f46af9d52 --- /dev/null +++ b/test/runtime/samples/keyed-each-dev-unique/_config.js @@ -0,0 +1,7 @@ +export default { + compileOptions: { + dev: true + }, + + error: `Cannot have duplicate keys in a keyed each` +}; diff --git a/test/runtime/samples/keyed-each-dev-unique/main.svelte b/test/runtime/samples/keyed-each-dev-unique/main.svelte new file mode 100644 index 0000000000..870e7beaa1 --- /dev/null +++ b/test/runtime/samples/keyed-each-dev-unique/main.svelte @@ -0,0 +1,7 @@ + + +{#each array as item (item)} + {item} +{/each} From 3ba4f8abcad48b0380c9046d0f9230c1fc330964 Mon Sep 17 00:00:00 2001 From: Conduitry Date: Wed, 22 Jan 2020 20:11:45 -0500 Subject: [PATCH 53/79] site: fix a couple absolute links --- site/content/blog/2019-04-20-write-less-code.md | 2 +- site/content/docs/01-component-format.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/site/content/blog/2019-04-20-write-less-code.md b/site/content/blog/2019-04-20-write-less-code.md index d6c8b77193..d56c5312e8 100644 --- a/site/content/blog/2019-04-20-write-less-code.md +++ b/site/content/blog/2019-04-20-write-less-code.md @@ -159,6 +159,6 @@ In Vue, meanwhile, we have a default export with a `data` function that returns ## Death to boilerplate -These are just some of the ways that Svelte helps you build user interfaces with a minimum of fuss. There are plenty of others — for example, [reactive declarations](https://svelte.dev/tutorial/reactive-declarations) essentially do the work of React's `useMemo`, `useCallback` and `useEffect` without the boilerplate (or indeed the garbage collection overhead of creating inline functions and arrays on each state change). +These are just some of the ways that Svelte helps you build user interfaces with a minimum of fuss. There are plenty of others — for example, [reactive declarations](tutorial/reactive-declarations) essentially do the work of React's `useMemo`, `useCallback` and `useEffect` without the boilerplate (or indeed the garbage collection overhead of creating inline functions and arrays on each state change). How? By choosing a different set of constraints. Because [Svelte is a compiler](blog/frameworks-without-the-framework), we're not bound to the peculiarities of JavaScript: we can *design* a component authoring experience, rather than having to fit it around the semantics of the language. Paradoxically, this results in *more* idiomatic code — for example using variables naturally rather than via proxies or hooks — while delivering significantly more performant apps. diff --git a/site/content/docs/01-component-format.md b/site/content/docs/01-component-format.md index e541292e13..026a2da5b3 100644 --- a/site/content/docs/01-component-format.md +++ b/site/content/docs/01-component-format.md @@ -197,7 +197,7 @@ You can `export` bindings from this block, and they will become exports of the c You cannot `export default`, since the default export is the component itself. -> Variables defined in `module` scripts are not reactive — reassigning them will not trigger a rerender even though the variable itself will update. For values shared between multiple components, consider using a [store](https://svelte.dev/docs#svelte_store). +> Variables defined in `module` scripts are not reactive — reassigning them will not trigger a rerender even though the variable itself will update. For values shared between multiple components, consider using a [store](docs#svelte_store). ```html + +

{$store}

From 9cdf0da160d906948a4b4bbaebaf856751906177 Mon Sep 17 00:00:00 2001 From: Conduitry Date: Thu, 23 Jan 2020 10:44:35 -0500 Subject: [PATCH 58/79] fix changelog --- CHANGELOG.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7ff7d7603b..44253ce59c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,11 @@ # Svelte changelog -## 3.17.3 +## Unreleased * Make autosubscribing to a nullish store a no-op ([#2181](https://github.com/sveltejs/svelte/issues/2181)) + +## 3.17.3 + * Fix updating a `` inside an `{#if}` or other block ([#4292](https://github.com/sveltejs/svelte/issues/4292)) * Fix using RxJS observables in `derived` stores ([#4298](https://github.com/sveltejs/svelte/issues/4298)) * Add dev mode check to disallow duplicate keys in a keyed `{#each}` ([#4301](https://github.com/sveltejs/svelte/issues/4301)) From bf006a43e5fd2339adb6cfca1a322fdedcbf48da Mon Sep 17 00:00:00 2001 From: Dave Lunny <4298089+himynameisdave@users.noreply.github.com> Date: Thu, 23 Jan 2020 17:51:29 -0800 Subject: [PATCH 59/79] [Internals] Improve unit tests (#4262) --- .github/workflows/ci.yml | 6 ++++++ src/compiler/compile/utils/__test__.ts | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2488902b24..14824ecdfa 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,3 +23,9 @@ jobs: - uses: actions/checkout@v1 - uses: actions/setup-node@v1 - run: 'npm i && npm run lint' + Unit: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - uses: actions/setup-node@v1 + - run: 'npm i && npm run test:unit' diff --git a/src/compiler/compile/utils/__test__.ts b/src/compiler/compile/utils/__test__.ts index 60ad681b47..7777bc6afb 100644 --- a/src/compiler/compile/utils/__test__.ts +++ b/src/compiler/compile/utils/__test__.ts @@ -10,7 +10,7 @@ describe('get_name_from_filename', () => { assert.equal(get_name_from_filename('path/to/Widget/index.svelte'), 'Widget'); }); - it('handles unusual filenames', () => { - assert.equal(get_name_from_filename('path/to/[...parts].svelte'), 'Parts'); + it('handles Windows filenames', () => { + assert.equal(get_name_from_filename('path\\to\\Widget.svelte'), 'Widget'); }); }); From 8e245dc30ea971da953b1806ed980044546a03a9 Mon Sep 17 00:00:00 2001 From: David Kondrad Date: Sat, 25 Jan 2020 12:21:55 -0500 Subject: [PATCH 60/79] Internals: Scheduler: Fix infinite loop in flush (#4316) --- src/runtime/internal/scheduler.ts | 7 ++++--- .../lifecycle-onmount-infinite-loop/Child.svelte | 1 + .../lifecycle-onmount-infinite-loop/_config.js | 6 ++++++ .../lifecycle-onmount-infinite-loop/main.svelte | 16 ++++++++++++++++ 4 files changed, 27 insertions(+), 3 deletions(-) create mode 100644 test/runtime/samples/lifecycle-onmount-infinite-loop/Child.svelte create mode 100644 test/runtime/samples/lifecycle-onmount-infinite-loop/_config.js create mode 100644 test/runtime/samples/lifecycle-onmount-infinite-loop/main.svelte diff --git a/src/runtime/internal/scheduler.ts b/src/runtime/internal/scheduler.ts index 04c1264ab1..1ce255b217 100644 --- a/src/runtime/internal/scheduler.ts +++ b/src/runtime/internal/scheduler.ts @@ -31,8 +31,8 @@ export function add_flush_callback(fn) { flush_callbacks.push(fn); } +const seen_callbacks = new Set(); export function flush() { - const seen_callbacks = new Set(); do { // first, call beforeUpdate functions @@ -52,10 +52,10 @@ export function flush() { const callback = render_callbacks[i]; if (!seen_callbacks.has(callback)) { - callback(); - // ...so guard against infinite loops seen_callbacks.add(callback); + + callback(); } } @@ -67,6 +67,7 @@ export function flush() { } update_scheduled = false; + seen_callbacks.clear(); } function update($$) { diff --git a/test/runtime/samples/lifecycle-onmount-infinite-loop/Child.svelte b/test/runtime/samples/lifecycle-onmount-infinite-loop/Child.svelte new file mode 100644 index 0000000000..ef16875b64 --- /dev/null +++ b/test/runtime/samples/lifecycle-onmount-infinite-loop/Child.svelte @@ -0,0 +1 @@ +Child diff --git a/test/runtime/samples/lifecycle-onmount-infinite-loop/_config.js b/test/runtime/samples/lifecycle-onmount-infinite-loop/_config.js new file mode 100644 index 0000000000..a76a2686ac --- /dev/null +++ b/test/runtime/samples/lifecycle-onmount-infinite-loop/_config.js @@ -0,0 +1,6 @@ +export default { + test({ assert, component }) { + const { count } = component; + assert.deepEqual(count, 1); + } +}; diff --git a/test/runtime/samples/lifecycle-onmount-infinite-loop/main.svelte b/test/runtime/samples/lifecycle-onmount-infinite-loop/main.svelte new file mode 100644 index 0000000000..1fa4263e39 --- /dev/null +++ b/test/runtime/samples/lifecycle-onmount-infinite-loop/main.svelte @@ -0,0 +1,16 @@ + + +
From 5d4408ba23655c54e8b921e27461273dc5e63610 Mon Sep 17 00:00:00 2001 From: Conduitry Date: Sat, 25 Jan 2020 12:23:50 -0500 Subject: [PATCH 61/79] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 44253ce59c..b5784f4148 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## Unreleased +* Fix infinite loop when instantiating another component during `onMount` ([#3218](https://github.com/sveltejs/svelte/issues/3218)) * Make autosubscribing to a nullish store a no-op ([#2181](https://github.com/sveltejs/svelte/issues/2181)) ## 3.17.3 From efe8ab9ca569b8cc706cb4c231b39c160ba479e3 Mon Sep 17 00:00:00 2001 From: Conduitry Date: Sat, 25 Jan 2020 12:26:19 -0500 Subject: [PATCH 62/79] -> v3.18.0 --- CHANGELOG.md | 2 +- package-lock.json | 2 +- package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b5784f4148..ed6feef9d4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Svelte changelog -## Unreleased +## 3.18.0 * Fix infinite loop when instantiating another component during `onMount` ([#3218](https://github.com/sveltejs/svelte/issues/3218)) * Make autosubscribing to a nullish store a no-op ([#2181](https://github.com/sveltejs/svelte/issues/2181)) diff --git a/package-lock.json b/package-lock.json index cfbc71cdd2..6300fd40ac 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "svelte", - "version": "3.17.3", + "version": "3.18.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 2b0b09299b..791327d3f0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "svelte", - "version": "3.17.3", + "version": "3.18.0", "description": "Cybernetically enhanced web apps", "module": "index.mjs", "main": "index", From 3eb298fd28ff68f782f632a9029b430745cb0c2b Mon Sep 17 00:00:00 2001 From: Conduitry Date: Mon, 27 Jan 2020 14:02:30 -0500 Subject: [PATCH 63/79] fix code generation with adjacent inline and block comments (#4327) --- CHANGELOG.md | 4 ++++ package-lock.json | 6 +++--- package.json | 2 +- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ed6feef9d4..217651e20b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Svelte changelog +## Unreleased + +* Fix code generation error with adjacent inline and block comments ([#4312](https://github.com/sveltejs/svelte/issues/4312)) + ## 3.18.0 * Fix infinite loop when instantiating another component during `onMount` ([#3218](https://github.com/sveltejs/svelte/issues/3218)) diff --git a/package-lock.json b/package-lock.json index 6300fd40ac..5ffb1ba0da 100644 --- a/package-lock.json +++ b/package-lock.json @@ -597,9 +597,9 @@ "dev": true }, "code-red": { - "version": "0.0.31", - "resolved": "https://registry.npmjs.org/code-red/-/code-red-0.0.31.tgz", - "integrity": "sha512-7Gf3vm8pDbs+H/hKsaqOZe0xKlE9Neah12GCfs7qun3fBUaOXwexAMjn0Eo9cvJJvhRMaL0jgPiY9ZGLTWoe8A==", + "version": "0.0.32", + "resolved": "https://registry.npmjs.org/code-red/-/code-red-0.0.32.tgz", + "integrity": "sha512-mE+EZc2vJ4HxiejW5S2CvcVDKtopFEmrqAd9DTBDLCNjLgxekPP8wLi/ZiwDTwZwwW3dzeetaubLaMlIvkhVNw==", "dev": true, "requires": { "acorn": "^7.1.0", diff --git a/package.json b/package.json index 791327d3f0..3b43d6fa46 100644 --- a/package.json +++ b/package.json @@ -70,7 +70,7 @@ "acorn": "^7.1.0", "agadoo": "^1.1.0", "c8": "^5.0.1", - "code-red": "0.0.31", + "code-red": "0.0.32", "codecov": "^3.5.0", "css-tree": "1.0.0-alpha22", "eslint": "^6.3.0", From 43f19d93a9fe33ec71856d7b080aca1425460a3e Mon Sep 17 00:00:00 2001 From: Wolfr Date: Mon, 27 Jan 2020 20:28:06 +0100 Subject: [PATCH 64/79] site: Improve open graph images for website (#4328) --- site/src/template.html | 1 + 1 file changed, 1 insertion(+) diff --git a/site/src/template.html b/site/src/template.html index dc930a7f72..344684d766 100644 --- a/site/src/template.html +++ b/site/src/template.html @@ -15,6 +15,7 @@ +