From 8c47518371e3cf3e73333f7eaca1db86f72a4d0d Mon Sep 17 00:00:00 2001 From: tanhauhau Date: Tue, 13 Sep 2022 14:01:50 +0800 Subject: [PATCH] disallow calling getContext inside element --- src/compiler/compile/render_ssr/index.ts | 2 +- src/runtime/internal/Component.ts | 43 ++++++++++--------- src/runtime/internal/lifecycle.ts | 8 ++++ .../context-api-in-element-1/_config.js | 3 ++ .../context-api-in-element-1/main.svelte | 5 +++ .../context-api-in-element-2/_config.js | 3 ++ .../context-api-in-element-2/main.svelte | 5 +++ .../context-api-in-element-3/_config.js | 3 ++ .../context-api-in-element-3/main.svelte | 5 +++ 9 files changed, 56 insertions(+), 21 deletions(-) create mode 100644 test/runtime/samples/context-api-in-element-1/_config.js create mode 100644 test/runtime/samples/context-api-in-element-1/main.svelte create mode 100644 test/runtime/samples/context-api-in-element-2/_config.js create mode 100644 test/runtime/samples/context-api-in-element-2/main.svelte create mode 100644 test/runtime/samples/context-api-in-element-3/_config.js create mode 100644 test/runtime/samples/context-api-in-element-3/main.svelte diff --git a/src/compiler/compile/render_ssr/index.ts b/src/compiler/compile/render_ssr/index.ts index e256ba78fbf0..670aa9baeb3b 100644 --- a/src/compiler/compile/render_ssr/index.ts +++ b/src/compiler/compile/render_ssr/index.ts @@ -198,7 +198,7 @@ export default function ssr( instance_javascript, ...parent_bindings, css.code && b`$$result.css.add(#css);`, - main + b`return @no_current_component(() => { ${main} });` ].filter(Boolean); const css_sourcemap_enabled = check_enable_sourcemap(options.enableSourcemap, 'css'); diff --git a/src/runtime/internal/Component.ts b/src/runtime/internal/Component.ts index 3e4801054757..a642a56944cc 100644 --- a/src/runtime/internal/Component.ts +++ b/src/runtime/internal/Component.ts @@ -1,5 +1,5 @@ import { add_render_callback, flush, schedule_update, dirty_components } from './scheduler'; -import { current_component, set_current_component } from './lifecycle'; +import { current_component, no_current_component, set_current_component } from './lifecycle'; import { blank_object, is_empty, is_function, run, run_all, noop } from './utils'; import { children, detach, start_hydrating, end_hydrating } from './dom'; import { transition_in } from './transitions'; @@ -152,26 +152,29 @@ export function init(component, options, instance, create_fragment, not_equal, p ready = true; run_all($$.before_update); - // `false` as a special case of no DOM component - $$.fragment = create_fragment ? create_fragment($$.ctx) : false; - - if (options.target) { - if (options.hydrate) { - start_hydrating(); - const nodes = children(options.target); - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - $$.fragment && $$.fragment!.l(nodes); - nodes.forEach(detach); - } else { - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - $$.fragment && $$.fragment!.c(); - } + no_current_component(() => { + // `false` as a special case of no DOM component + $$.fragment = create_fragment ? create_fragment($$.ctx) : false; + + + if (options.target) { + if (options.hydrate) { + start_hydrating(); + const nodes = children(options.target); + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + $$.fragment && $$.fragment!.l(nodes); + nodes.forEach(detach); + } else { + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + $$.fragment && $$.fragment!.c(); + } - if (options.intro) transition_in(component.$$.fragment); - mount_component(component, options.target, options.anchor, options.customElement); - end_hydrating(); - flush(); - } + if (options.intro) transition_in(component.$$.fragment); + mount_component(component, options.target, options.anchor, options.customElement); + end_hydrating(); + flush(); + } + }); set_current_component(parent_component); } diff --git a/src/runtime/internal/lifecycle.ts b/src/runtime/internal/lifecycle.ts index fbbeca9a67c0..ae024c52d09c 100644 --- a/src/runtime/internal/lifecycle.ts +++ b/src/runtime/internal/lifecycle.ts @@ -11,6 +11,14 @@ export function get_current_component() { return current_component; } +export function no_current_component(callback: () => void) { + const old_current_component = current_component; + current_component = undefined; + const value = callback(); + current_component = old_current_component; + return value; +} + export function beforeUpdate(fn: () => any) { get_current_component().$$.before_update.push(fn); } diff --git a/test/runtime/samples/context-api-in-element-1/_config.js b/test/runtime/samples/context-api-in-element-1/_config.js new file mode 100644 index 000000000000..79b5908ab718 --- /dev/null +++ b/test/runtime/samples/context-api-in-element-1/_config.js @@ -0,0 +1,3 @@ +export default { + error: 'Function called outside component initialization' +}; diff --git a/test/runtime/samples/context-api-in-element-1/main.svelte b/test/runtime/samples/context-api-in-element-1/main.svelte new file mode 100644 index 000000000000..584d2bb05389 --- /dev/null +++ b/test/runtime/samples/context-api-in-element-1/main.svelte @@ -0,0 +1,5 @@ + + +{getContext('test')} diff --git a/test/runtime/samples/context-api-in-element-2/_config.js b/test/runtime/samples/context-api-in-element-2/_config.js new file mode 100644 index 000000000000..79b5908ab718 --- /dev/null +++ b/test/runtime/samples/context-api-in-element-2/_config.js @@ -0,0 +1,3 @@ +export default { + error: 'Function called outside component initialization' +}; diff --git a/test/runtime/samples/context-api-in-element-2/main.svelte b/test/runtime/samples/context-api-in-element-2/main.svelte new file mode 100644 index 000000000000..c852c7f5d7ad --- /dev/null +++ b/test/runtime/samples/context-api-in-element-2/main.svelte @@ -0,0 +1,5 @@ + + +xxx diff --git a/test/runtime/samples/context-api-in-element-3/_config.js b/test/runtime/samples/context-api-in-element-3/_config.js new file mode 100644 index 000000000000..79b5908ab718 --- /dev/null +++ b/test/runtime/samples/context-api-in-element-3/_config.js @@ -0,0 +1,3 @@ +export default { + error: 'Function called outside component initialization' +}; diff --git a/test/runtime/samples/context-api-in-element-3/main.svelte b/test/runtime/samples/context-api-in-element-3/main.svelte new file mode 100644 index 000000000000..04f969fff35f --- /dev/null +++ b/test/runtime/samples/context-api-in-element-3/main.svelte @@ -0,0 +1,5 @@ + + +{getContext('test')}