Skip to content

Commit

Permalink
fix: add css hash to custom element rendered with svelte:element (#…
Browse files Browse the repository at this point in the history
…12715)

* fix: add css hash to custom element rendered with `svelte:element`

* simplify

* skip arg where possible

* drive-by improvements — remove some unnecessary arguments where possible

---------

Co-authored-by: Rich Harris <[email protected]>
  • Loading branch information
paoloricciuti and Rich-Harris authored Aug 3, 2024
1 parent 8e04a91 commit 93cfa6c
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 23 deletions.
5 changes: 5 additions & 0 deletions .changeset/chilly-carpets-switch.md
Original file line number Diff line number Diff line change
@@ -0,0 1,5 @@
---
'svelte': patch
---

fix: add css hash to custom element rendered with `svelte:element`
Original file line number Diff line number Diff line change
Expand Up @@ -470,10 470,8 @@ function build_element_spread_attributes(
attribute.type === 'SpreadAttribute' && attribute.metadata.expression.has_call;
}

const lowercase_attributes =
element.metadata.svg || element.metadata.mathml || is_custom_element_node(element)
? b.false
: b.true;
const preserve_attribute_case =
element.metadata.svg || element.metadata.mathml || is_custom_element_node(element);
const id = context.state.scope.generate('attributes');

const update = b.stmt(
Expand All @@ -485,8 483,8 @@ function build_element_spread_attributes(
element_id,
b.id(id),
b.object(values),
lowercase_attributes,
b.literal(context.state.analysis.css.hash),
context.state.analysis.css.hash !== '' && b.literal(context.state.analysis.css.hash),
preserve_attribute_case && b.true,
is_ignored(element, 'hydration_attribute_changed') && b.true
)
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 200,7 @@ function build_dynamic_element_attributes(attributes, context, element_id) {
element_id,
b.id(id),
b.object(values),
b.literal(context.state.analysis.css.hash)
context.state.analysis.css.hash !== '' && b.literal(context.state.analysis.css.hash)
)
)
);
Expand All @@ -221,7 221,7 @@ function build_dynamic_element_attributes(attributes, context, element_id) {
element_id,
b.literal(null),
b.object(values),
b.literal(context.state.analysis.css.hash)
context.state.analysis.css.hash !== '' && b.literal(context.state.analysis.css.hash)
)
)
);
Expand Down
35 changes: 20 additions & 15 deletions packages/svelte/src/internal/client/dom/elements/attributes.js
Original file line number Diff line number Diff line change
Expand Up @@ -147,13 147,19 @@ export function set_custom_element_data(node, prop, value) {
* @param {Element & ElementCSSInlineStyle} element
* @param {Record<string, any> | undefined} prev
* @param {Record<string, any>} next New attributes - this function mutates this object
* @param {boolean} lowercase_attributes
* @param {string} css_hash
* @param {string} [css_hash]
* @param {boolean} preserve_attribute_case
* @param {boolean} [skip_warning]
* @returns {Record<string, any>}
*/
export function set_attributes(element, prev, next, lowercase_attributes, css_hash, skip_warning) {
var has_hash = css_hash.length !== 0;
export function set_attributes(
element,
prev,
next,
css_hash,
preserve_attribute_case = false,
skip_warning
) {
var current = prev || {};
var is_option_element = element.tagName === 'OPTION';

Expand All @@ -163,8 169,8 @@ export function set_attributes(element, prev, next, lowercase_attributes, css_ha
}
}

if (has_hash && !next.class) {
next.class = '';
if (css_hash !== undefined) {
next.class = next.class ? next.class ' ' css_hash : css_hash;
}

var setters = setters_cache.get(element.nodeName);
Expand Down Expand Up @@ -267,7 273,7 @@ export function set_attributes(element, prev, next, lowercase_attributes, css_ha
element.value = element[key] = element.__value = value;
} else {
var name = key;
if (lowercase_attributes) {
if (!preserve_attribute_case) {
name = normalize_attribute(name);
}

Expand All @@ -279,11 285,6 @@ export function set_attributes(element, prev, next, lowercase_attributes, css_ha
element[name] = value;
}
} else if (typeof value !== 'function') {
if (has_hash && name === 'class') {
if (value) value = ' ';
value = css_hash;
}

set_attribute(element, name, value);
}
}
Expand All @@ -309,7 310,7 @@ export function set_attributes(element, prev, next, lowercase_attributes, css_ha
* @param {Element} node
* @param {Record<string, any> | undefined} prev
* @param {Record<string, any>} next The new attributes - this function mutates this object
* @param {string} css_hash
* @param {string} [css_hash]
*/
export function set_dynamic_element_attributes(node, prev, next, css_hash) {
if (node.tagName.includes('-')) {
Expand All @@ -319,6 320,10 @@ export function set_dynamic_element_attributes(node, prev, next, css_hash) {
}
}

if (css_hash !== undefined) {
next.class = next.class ? next.class ' ' css_hash : css_hash;
}

for (key in next) {
set_custom_element_data(node, key, next[key]);
}
Expand All @@ -330,8 335,8 @@ export function set_dynamic_element_attributes(node, prev, next, css_hash) {
/** @type {Element & ElementCSSInlineStyle} */ (node),
prev,
next,
node.namespaceURI !== NAMESPACE_SVG,
css_hash
css_hash,
node.namespaceURI !== NAMESPACE_SVG
);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 1,14 @@
import { ok, test } from '../../test';

export default test({
html: `<custom-element class="red svelte-p153w3"></custom-element><custom-element class="red svelte-p153w3"></custom-element>`,

async test({ assert, target }) {
const [el, el2] = target.querySelectorAll('custom-element');
ok(el);
ok(el2);

assert.deepEqual(el.className, 'red svelte-p153w3');
assert.deepEqual(el2.className, 'red svelte-p153w3');
}
});
Original file line number Diff line number Diff line change
@@ -0,0 1,8 @@
<svelte:element this={'custom-element'} class="red"></svelte:element>
<custom-element class="red"></custom-element>

<style>
.red {
color: red;
}
</style>

0 comments on commit 93cfa6c

Please sign in to comment.