From f89c7ddd7eebaa1ef3cc540400bec2c9140b330c Mon Sep 17 00:00:00 2001 From: Elliott Johnson Date: Wed, 18 Feb 2026 10:53:42 -0700 Subject: [PATCH] Merge commit from fork Co-authored-by: Rich Harris --- .changeset/elliott-elliott-elliott.md | 5 +++++ packages/svelte/src/internal/server/index.js | 13 +++++++------ packages/svelte/src/internal/server/renderer.js | 2 +- packages/svelte/src/internal/shared/attributes.js | 6 +++--- packages/svelte/src/internal/shared/clone.js | 2 +- 5 files changed, 17 insertions(+), 11 deletions(-) create mode 100644 .changeset/elliott-elliott-elliott.md diff --git a/.changeset/elliott-elliott-elliott.md b/.changeset/elliott-elliott-elliott.md new file mode 100644 index 0000000000..cf2e2e1cc1 --- /dev/null +++ b/.changeset/elliott-elliott-elliott.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: replace usage of `for in` with `for of Object.keys` diff --git a/packages/svelte/src/internal/server/index.js b/packages/svelte/src/internal/server/index.js index 015db09a64..d978ed6355 100644 --- a/packages/svelte/src/internal/server/index.js +++ b/packages/svelte/src/internal/server/index.js @@ -138,7 +138,7 @@ export function attributes(attrs, css_hash, classes, styles, flags = 0) { const lowercase = (flags & ELEMENT_PRESERVE_ATTRIBUTE_CASE) === 0; const is_input = (flags & ELEMENT_IS_INPUT) !== 0; - for (name in attrs) { + for (name of Object.keys(attrs)) { // omit functions, internal svelte properties and invalid attribute names if (typeof attrs[name] === 'function') continue; if (name[0] === '$' && name[1] === '$') continue; // faster than name.startsWith('$$') @@ -174,7 +174,8 @@ export function spread_props(props) { for (let i = 0; i < props.length; i++) { const obj = props[i]; - for (key in obj) { + if (obj == null) continue; + for (key of Object.keys(obj)) { const desc = Object.getOwnPropertyDescriptor(obj, key); if (desc) { Object.defineProperty(merged_props, key, desc); @@ -302,7 +303,7 @@ export function update_store_pre(store_values, store_name, store, d = 1) { /** @param {Record} store_values */ export function unsubscribe_stores(store_values) { - for (const store_name in store_values) { + for (const store_name of Object.keys(store_values)) { store_values[store_name][1](); } } @@ -338,7 +339,7 @@ export function rest_props(props, rest) { /** @type {Record} */ const rest_props = {}; let key; - for (key in props) { + for (key of Object.keys(props)) { if (!rest.includes(key)) { rest_props[key] = props[key]; } @@ -363,7 +364,7 @@ export function sanitize_slots(props) { /** @type {Record} */ const sanitized = {}; if (props.children) sanitized.default = true; - for (const key in props.$$slots) { + for (const key of Object.keys(props.$$slots || {})) { sanitized[key] = true; } return sanitized; @@ -376,7 +377,7 @@ export function sanitize_slots(props) { * @param {Record} props_now */ export function bind_props(props_parent, props_now) { - for (const key in props_now) { + for (const key of Object.keys(props_now)) { const initial_value = props_parent[key]; const value = props_now[key]; if ( diff --git a/packages/svelte/src/internal/server/renderer.js b/packages/svelte/src/internal/server/renderer.js index d18a48bdb4..9df914b35a 100644 --- a/packages/svelte/src/internal/server/renderer.js +++ b/packages/svelte/src/internal/server/renderer.js @@ -267,7 +267,7 @@ export class Renderer { * @param {{ head?: string, body: any }} content */ const close = (renderer, value, { head, body }) => { - if ('value' in attrs) { + if (Object.hasOwn(attrs, 'value')) { value = attrs.value; } diff --git a/packages/svelte/src/internal/shared/attributes.js b/packages/svelte/src/internal/shared/attributes.js index 8bfa91f80c..21bfd3d5a8 100644 --- a/packages/svelte/src/internal/shared/attributes.js +++ b/packages/svelte/src/internal/shared/attributes.js @@ -27,7 +27,7 @@ export function attr(name, value, is_boolean = false) { is_boolean = true; } if (value == null || (!value && is_boolean)) return ''; - const normalized = (name in replacements && replacements[name].get(value)) || value; + const normalized = (Object.hasOwn(replacements, name) && replacements[name].get(value)) || value; const assignment = is_boolean ? `=""` : `="${escape_html(normalized, true)}"`; return ` ${name}${assignment}`; } @@ -61,7 +61,7 @@ export function to_class(value, hash, directives) { } if (directives) { - for (var key in directives) { + for (var key of Object.keys(directives)) { if (directives[key]) { classname = classname ? classname + ' ' + key : key; } else if (classname.length) { @@ -96,7 +96,7 @@ function append_styles(styles, important = false) { var separator = important ? ' !important;' : ';'; var css = ''; - for (var key in styles) { + for (var key of Object.keys(styles)) { var value = styles[key]; if (value != null && value !== '') { css += ' ' + key + ': ' + value + separator; diff --git a/packages/svelte/src/internal/shared/clone.js b/packages/svelte/src/internal/shared/clone.js index b8f99ee198..1a83adf8c5 100644 --- a/packages/svelte/src/internal/shared/clone.js +++ b/packages/svelte/src/internal/shared/clone.js @@ -89,7 +89,7 @@ function clone(value, cloned, path, paths, original = null, no_tojson = false) { cloned.set(original, copy); } - for (var key in value) { + for (var key of Object.keys(value)) { copy[key] = clone( // @ts-expect-error value[key],