mirror of https://github.com/sveltejs/svelte
- revert to previous value on unmount, if it was the last one changing the value - special handling for classes: merge themsvelte-html
parent
0c1c8b992b
commit
86342319d8
@ -0,0 +1,54 @@
|
||||
import { render_effect, teardown } from '../../reactivity/effects.js';
|
||||
import { set_attribute } from '../elements/attributes.js';
|
||||
import { set_class } from '../elements/class.js';
|
||||
import { hydrating } from '../hydration.js';
|
||||
|
||||
/**
|
||||
* @param {() => Record<string, any>} get_attributes
|
||||
* @returns {void}
|
||||
*/
|
||||
export function svelte_html(get_attributes) {
|
||||
const node = document.documentElement;
|
||||
const own = {};
|
||||
|
||||
/** @type {Record<string, Array<[any, any]>>} to check who set the last value of each attribute */
|
||||
// @ts-expect-error
|
||||
const current_setters = (node.__attributes_setters ??= {});
|
||||
|
||||
/** @type {Record<string, any>} */
|
||||
let attributes;
|
||||
|
||||
render_effect(() => {
|
||||
attributes = get_attributes();
|
||||
|
||||
for (const name in attributes) {
|
||||
let value = attributes[name];
|
||||
current_setters[name] = (current_setters[name] ?? []).filter(([owner]) => owner !== own);
|
||||
current_setters[name].unshift([own, value]);
|
||||
|
||||
// Do nothing on initial render during hydration: If there are attribute duplicates, the last value
|
||||
// wins, which could result in needless hydration repairs from earlier values.
|
||||
if (hydrating) continue;
|
||||
|
||||
if (name === 'class') {
|
||||
set_class(node, current_setters[name].map(([_, value]) => value).join(' '));
|
||||
} else {
|
||||
set_attribute(node, name, value);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
teardown(() => {
|
||||
for (const name in attributes) {
|
||||
const old = current_setters[name];
|
||||
current_setters[name] = old.filter(([owner]) => owner !== own);
|
||||
const current = current_setters[name];
|
||||
|
||||
if (name === 'class') {
|
||||
set_class(node, current.map(([_, value]) => value).join(' '));
|
||||
} else if (old[0][0] === own) {
|
||||
set_attribute(node, name, current[0]?.[1]);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
Loading…
Reference in new issue