pull/14210/head
Simon Holthausen 2 years ago
parent 6b0af693bd
commit b36329af90

@ -22,4 +22,5 @@ export const EFFECT_HAS_DERIVED = 1 << 19;
export const STATE_SYMBOL = Symbol('$state');
export const STATE_SYMBOL_METADATA = Symbol('$state metadata');
export const LEGACY_PROPS = Symbol('legacy props');
export const LOADING_ATTR_SYMBOL = Symbol('');

@ -20,7 +20,13 @@ import {
} from '../runtime.js';
import { safe_equals } from './equality.js';
import * as e from '../errors.js';
import { BRANCH_EFFECT, LEGACY_DERIVED_PROP, ROOT_EFFECT, STATE_SYMBOL } from '../constants.js';
import {
BRANCH_EFFECT,
LEGACY_DERIVED_PROP,
LEGACY_PROPS,
ROOT_EFFECT,
STATE_SYMBOL
} from '../constants.js';
import { proxy } from '../proxy.js';
import { capture_store_binding } from './store.js';
import { legacy_mode_flag } from '../../flags/index.js';
@ -283,10 +289,12 @@ export function prop(props, key, flags, fallback) {
prop_value = /** @type {V} */ (props[key]);
}
// Can be the case when someone does `mount(Component, props)` with `let props = $state({...})`
// or `createClassComponent(Component, props)`
var is_entry_props = STATE_SYMBOL in props || LEGACY_PROPS in props;
var setter =
get_descriptor(props, key)?.set ??
// Can be the case when someone does `mount(Component, props)` with `let props = $state({...})`
(STATE_SYMBOL in props ? (v) => (props[key] = v) : undefined);
get_descriptor(props, key)?.set ?? (is_entry_props ? (v) => (props[key] = v) : undefined);
var fallback_value = /** @type {V} */ (fallback);
var fallback_dirty = true;
@ -307,7 +315,7 @@ export function prop(props, key, flags, fallback) {
};
if (prop_value === undefined && fallback !== undefined) {
if (setter && runes) {
if (setter && runes && !is_entry_props) {
e.props_invalid_value(key);
}

@ -1,4 +1,4 @@
import { dev_current_component_function, untrack } from './runtime.js';
import { dev_current_component_function } from './runtime.js';
import { get_descriptor, is_array } from '../shared/utils.js';
import * as e from './errors.js';
import { FILENAME } from '../../constants.js';
@ -6,15 +6,6 @@ import { render_effect } from './reactivity/effects.js';
import * as w from './warnings.js';
import { capture_store_binding } from './reactivity/store.js';
/** regex of all html void element names */
const void_element_names =
/^(?:area|base|br|col|command|embed|hr|img|input|keygen|link|meta|param|source|track|wbr)$/;
/** @param {string} tag */
function is_void(tag) {
return void_element_names.test(tag) || tag.toLowerCase() === '!doctype';
}
/**
* @param {() => any} collection
* @param {(item: any, index: number) => string} key_fn

@ -1,5 +1,5 @@
/** @import { ComponentConstructorOptions, ComponentType, SvelteComponent, Component } from 'svelte' */
import { DIRTY, MAYBE_DIRTY } from '../internal/client/constants.js';
import { DIRTY, LEGACY_PROPS, MAYBE_DIRTY } from '../internal/client/constants.js';
import { user_pre_effect } from '../internal/client/reactivity/effects.js';
import { mutable_source, set } from '../internal/client/reactivity/sources.js';
import { hydrate, mount, unmount } from '../internal/client/render.js';
@ -89,7 +89,7 @@ class Svelte4Component {
};
// Replicate coarse-grained props through a proxy that has a version source for
// each property, which is increment on updates to the property itself. Do not
// each property, which is incremented on updates to the property itself. Do not
// use our $state proxy because that one has fine-grained reactivity.
const props = new Proxy(
{ ...(options.props || {}), $$events: {} },
@ -98,26 +98,15 @@ class Svelte4Component {
return get(sources.get(prop) ?? add_source(prop, Reflect.get(target, prop)));
},
has(target, prop) {
// Necessary to not throw "invalid binding" validation errors on the component side
if (prop === LEGACY_PROPS) return true;
get(sources.get(prop) ?? add_source(prop, Reflect.get(target, prop)));
return Reflect.has(target, prop);
},
set(target, prop, value) {
set(sources.get(prop) ?? add_source(prop, value), value);
return Reflect.set(target, prop, value);
},
getOwnPropertyDescriptor(target, prop) {
// TODO this throws "invalid binding" errors on the component side
const desc = Reflect.getOwnPropertyDescriptor(target, prop);
if (!desc?.configurable) return desc;
return {
get: () => get(sources.get(prop) ?? add_source(prop, Reflect.get(target, prop))),
set: (value) => {
set(sources.get(prop) ?? add_source(prop, value), value);
return Reflect.set(target, prop, value);
},
enumerable: desc.enumerable,
configurable: desc.configurable
};
}
}
);

Loading…
Cancel
Save