diff --git a/packages/svelte/src/internal/client/operations.js b/packages/svelte/src/internal/client/operations.js index 7c4c58ac1e..d94e20dd3e 100644 --- a/packages/svelte/src/internal/client/operations.js +++ b/packages/svelte/src/internal/client/operations.js @@ -7,9 +7,7 @@ const has_browser_globals = typeof window !== 'undefined'; // We cache the Node and Element prototype methods, so that subsequent calls-sites are monomorphic rather // than megamorphic. const node_prototype = /** @type {Node} */ (has_browser_globals ? Node.prototype : {}); -const html_element_prototype = /** @type {Element} */ ( - has_browser_globals ? HTMLElement.prototype : {} -); +const element_prototype = /** @type {Element} */ (has_browser_globals ? Element.prototype : {}); const text_prototype = /** @type {Text} */ (has_browser_globals ? Text.prototype : {}); const map_prototype = Map.prototype; const append_child_method = node_prototype.appendChild; @@ -18,11 +16,11 @@ const map_set_method = map_prototype.set; const map_get_method = map_prototype.get; const map_delete_method = map_prototype.delete; // @ts-expect-error improve perf of expando on DOM events -html_element_prototype.__click = undefined; +element_prototype.__click = undefined; // @ts-expect-error improve perf of expando on DOM text updates text_prototype.__nodeValue = ' '; // @ts-expect-error improve perf of expando on DOM className updates -html_element_prototype.__className = ''; +element_prototype.__className = ''; const first_child_get = /** @type {(this: Node) => ChildNode | null} */ ( // @ts-ignore @@ -39,6 +37,11 @@ const text_content_set = /** @type {(this: Node, text: string ) => void} */ ( has_browser_globals ? get_descriptor(node_prototype, 'textContent').set : null ); +const class_name_set = /** @type {(this: Element, class_name: string) => void} */ ( + // @ts-ignore + has_browser_globals ? get_descriptor(element_prototype, 'className').set : null +); + /** * @template {Element} E * @template {Node} T @@ -144,6 +147,16 @@ export function sibling(node) { return next_sibling; } +/** + * @template {Element} N + * @param {N} node + * @param {string} class_name + * @returns {void} + */ +export function set_class_name(node, class_name) { + class_name_set.call(node, class_name); +} + /** * @template {Node} N * @param {N} node diff --git a/packages/svelte/src/internal/client/render.js b/packages/svelte/src/internal/client/render.js index 88f2910a4e..8fb36f0aeb 100644 --- a/packages/svelte/src/internal/client/render.js +++ b/packages/svelte/src/internal/client/render.js @@ -1,5 +1,13 @@ import { DEV } from 'esm-env'; -import { append_child, child, clone_node, create_element, map_get, map_set } from './operations.js'; +import { + append_child, + child, + clone_node, + create_element, + map_get, + map_set, + set_class_name +} from './operations.js'; import { create_root_block, create_each_item_block, @@ -349,7 +357,7 @@ export function class_name(dom, value) { if (next_class_name === '') { dom.removeAttribute('class'); } else { - dom.className = next_class_name; + set_class_name(dom, next_class_name); } // @ts-expect-error need to add __className to patched prototype dom.__className = next_class_name;