|
|
|
@ -9,9 +9,9 @@ import { hydrating } from '../hydration.js';
|
|
|
|
|
*/
|
|
|
|
|
export function svelte_html(get_attributes) {
|
|
|
|
|
const node = document.documentElement;
|
|
|
|
|
const own = {};
|
|
|
|
|
const self = {};
|
|
|
|
|
|
|
|
|
|
/** @type {Record<string, Array<[any, any]>>} to check who set the last value of each attribute */
|
|
|
|
|
/** @type {Record<string, Array<{ owner: any, value: any }>>} to check who set the last value of each attribute */
|
|
|
|
|
// @ts-expect-error
|
|
|
|
|
const current_setters = (node.__attributes_setters ??= {});
|
|
|
|
|
|
|
|
|
@ -23,11 +23,11 @@ export function svelte_html(get_attributes) {
|
|
|
|
|
|
|
|
|
|
for (const name in attributes) {
|
|
|
|
|
const current = (current_setters[name] ??= []);
|
|
|
|
|
const index = current.findIndex(([owner]) => owner === own);
|
|
|
|
|
const old = index === -1 ? null : current.splice(index, 1)[0][1];
|
|
|
|
|
const index = current.findIndex((c) => c.owner === self);
|
|
|
|
|
const old = index === -1 ? null : current.splice(index, 1)[0].value;
|
|
|
|
|
|
|
|
|
|
let value = attributes[name];
|
|
|
|
|
current.push([own, value]);
|
|
|
|
|
current.push({ owner: self, 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.
|
|
|
|
@ -36,7 +36,7 @@ export function svelte_html(get_attributes) {
|
|
|
|
|
if (name === 'class') {
|
|
|
|
|
// Avoid unrelated attribute changes from triggering class changes
|
|
|
|
|
if (old !== value) {
|
|
|
|
|
set_class(node, current_setters[name].map(([_, text]) => text).join(' '));
|
|
|
|
|
set_class(node, current_setters[name].map((e) => e.value).join(' '));
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
set_attribute(node, name, value);
|
|
|
|
@ -47,15 +47,15 @@ export function svelte_html(get_attributes) {
|
|
|
|
|
teardown(() => {
|
|
|
|
|
for (const name in attributes) {
|
|
|
|
|
const old = current_setters[name];
|
|
|
|
|
current_setters[name] = old.filter(([owner]) => owner !== own);
|
|
|
|
|
current_setters[name] = old.filter((o) => o.owner !== self);
|
|
|
|
|
const current = current_setters[name];
|
|
|
|
|
|
|
|
|
|
if (name === 'class') {
|
|
|
|
|
set_class(node, current.map(([_, text]) => text).join(' '));
|
|
|
|
|
set_class(node, current.map((c) => c.value).join(' '));
|
|
|
|
|
|
|
|
|
|
// If this was the last one setting this attribute, revert to the previous value
|
|
|
|
|
} else if (old[old.length - 1][0] === own) {
|
|
|
|
|
set_attribute(node, name, current[current.length - 1]?.[1]);
|
|
|
|
|
} else if (old[old.length - 1].owner === self) {
|
|
|
|
|
set_attribute(node, name, current[current.length - 1]?.value);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|