Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/fast-boxes-sort.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'svelte': patch
---

chore: generate CSS hash using the filename
20 changes: 11 additions & 9 deletions packages/svelte/src/compiler/phases/2-analyze/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -456,10 +456,19 @@ export function analyze_component(root, source, options) {

const is_custom_element = !!options.customElementOptions || options.customElement;

const name = module.scope.generate(options.name ?? component_name);

state.adjust({
component_name: name,
dev: options.dev,
rootDir: options.rootDir,
runes
});

// TODO remove all the ?? stuff, we don't need it now that we're validating the config
/** @type {ComponentAnalysis} */
const analysis = {
name: module.scope.generate(options.name ?? component_name),
name,
root: scope_root,
module,
instance,
Expand Down Expand Up @@ -520,7 +529,7 @@ export function analyze_component(root, source, options) {
hash: root.css
? options.cssHash({
css: root.css.content.styles,
filename: options.filename,
filename: state.filename,
name: component_name,
hash
})
Expand All @@ -534,13 +543,6 @@ export function analyze_component(root, source, options) {
async_deriveds: new Set()
};

state.adjust({
component_name: analysis.name,
dev: options.dev,
rootDir: options.rootDir,
runes
});

if (!runes) {
// every exported `let` or `var` declaration becomes a prop, everything else becomes an export
for (const node of instance.ast.body) {
Expand Down
2 changes: 1 addition & 1 deletion packages/svelte/src/compiler/types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ export interface CompileOptions extends ModuleCompileOptions {
css?: 'injected' | 'external';
/**
* A function that takes a `{ hash, css, name, filename }` argument and returns the string that is used as a classname for scoped CSS.
* It defaults to returning `svelte-${hash(css)}`.
* It defaults to returning `svelte-${hash(filename ?? css)}`.
*
* @default undefined
*/
Expand Down
4 changes: 2 additions & 2 deletions packages/svelte/src/compiler/validate-options.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,8 @@ const component_options = {
return input;
}),

cssHash: fun(({ css, hash }) => {
return `svelte-${hash(css)}`;
cssHash: fun(({ css, filename, hash }) => {
return `svelte-${hash(filename === '(unknown)' ? css : filename ?? css)}`;
}),

// TODO this is a sourcemap option, would be good to put under a sourcemap namespace
Expand Down
8 changes: 7 additions & 1 deletion packages/svelte/tests/html_equal.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,13 @@ function clean_children(node, opts) {
return;
}

node.setAttribute(attr.name, attr.value);
let value = attr.value;

if (attr.name === 'class') {
value = value.replace(/svelte-\w+/, 'svelte-xyz123');
}

node.setAttribute(attr.name, value);
});

for (let child of [...node.childNodes]) {
Expand Down
1 change: 1 addition & 0 deletions packages/svelte/tests/runtime-browser/assert.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ function normalize_html(window, html) {
node.innerHTML = html
.replace(/<!--.*?-->/g, '')
.replace(/>[\s\r\n]+</g, '><')
.replace(/svelte-\w+/g, 'svelte-xyz123')
.trim();

normalize_children(node);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,43 +1,43 @@
import { ok, test } from '../../test';

export default test({
html: '<div class="svelte-x1o6ra"></div>',
html: '<div class="svelte-70s021"></div>',

test({ assert, component, target }) {
const div = target.querySelector('div');
ok(div);

component.testName = null;
assert.equal(div.className, 'svelte-x1o6ra');
assert.equal(div.className, 'svelte-70s021');

component.testName = undefined;
assert.equal(div.className, 'svelte-x1o6ra');
assert.equal(div.className, 'svelte-70s021');

component.testName = undefined + '';
assert.equal(div.className, 'undefined svelte-x1o6ra');
assert.equal(div.className, 'undefined svelte-70s021');

component.testName = null + '';
assert.equal(div.className, 'null svelte-x1o6ra');
assert.equal(div.className, 'null svelte-70s021');

component.testName = 1;
assert.equal(div.className, '1 svelte-x1o6ra');
assert.equal(div.className, '1 svelte-70s021');

component.testName = 0;
assert.equal(div.className, '0 svelte-x1o6ra');
assert.equal(div.className, '0 svelte-70s021');

component.testName = false;
assert.equal(div.className, 'false svelte-x1o6ra');
assert.equal(div.className, 'false svelte-70s021');

component.testName = true;
assert.equal(div.className, 'true svelte-x1o6ra');
assert.equal(div.className, 'true svelte-70s021');

component.testName = {};
assert.equal(div.className, 'svelte-x1o6ra');
assert.equal(div.className, 'svelte-70s021');

component.testName = '';
assert.equal(div.className, 'svelte-x1o6ra');
assert.equal(div.className, 'svelte-70s021');

component.testName = 'testClassName';
assert.equal(div.className, 'testClassName svelte-x1o6ra');
assert.equal(div.className, 'testClassName svelte-70s021');
}
});
Original file line number Diff line number Diff line change
Expand Up @@ -10,43 +10,43 @@ export default test({
};
},

html: '<div class="test1test2 svelte-x1o6ra"></div>',
html: '<div class="test1test2 svelte-70s021"></div>',

test({ assert, component, target }) {
const div = target.querySelector('div');
ok(div);
assert.equal(div.className, 'test1test2 svelte-x1o6ra');
assert.equal(div.className, 'test1test2 svelte-70s021');

component.testName1 = null;
component.testName2 = null;
assert.equal(div.className, '0 svelte-x1o6ra');
assert.equal(div.className, '0 svelte-70s021');

component.testName1 = null;
component.testName2 = 'test';
assert.equal(div.className, 'nulltest svelte-x1o6ra');
assert.equal(div.className, 'nulltest svelte-70s021');

component.testName1 = undefined;
component.testName2 = 'test';
assert.equal(div.className, 'undefinedtest svelte-x1o6ra');
assert.equal(div.className, 'undefinedtest svelte-70s021');

component.testName1 = undefined;
component.testName2 = undefined;
assert.equal(div.className, 'NaN svelte-x1o6ra');
assert.equal(div.className, 'NaN svelte-70s021');

component.testName1 = null;
component.testName2 = 1;
assert.equal(div.className, '1 svelte-x1o6ra');
assert.equal(div.className, '1 svelte-70s021');

component.testName1 = undefined;
component.testName2 = 1;
assert.equal(div.className, 'NaN svelte-x1o6ra');
assert.equal(div.className, 'NaN svelte-70s021');

component.testName1 = null;
component.testName2 = 0;
assert.equal(div.className, '0 svelte-x1o6ra');
assert.equal(div.className, '0 svelte-70s021');

component.testName1 = undefined;
component.testName2 = 0;
assert.equal(div.className, 'NaN svelte-x1o6ra');
assert.equal(div.className, 'NaN svelte-70s021');
}
});
Original file line number Diff line number Diff line change
Expand Up @@ -8,41 +8,41 @@ export default test({
};
},

html: '<div class="testClassName svelte-x1o6ra"></div>',
html: '<div class="testClassName svelte-70s021"></div>',

test({ assert, component, target }) {
const div = target.querySelector('div');
ok(div);
assert.equal(div.className, 'testClassName svelte-x1o6ra');
assert.equal(div.className, 'testClassName svelte-70s021');

component.testName = null;
assert.equal(div.className, 'svelte-x1o6ra');
assert.equal(div.className, 'svelte-70s021');

component.testName = undefined;
assert.equal(div.className, 'svelte-x1o6ra');
assert.equal(div.className, 'svelte-70s021');

component.testName = undefined + '';
assert.equal(div.className, 'undefined svelte-x1o6ra');
assert.equal(div.className, 'undefined svelte-70s021');

component.testName = null + '';
assert.equal(div.className, 'null svelte-x1o6ra');
assert.equal(div.className, 'null svelte-70s021');

component.testName = 1;
assert.equal(div.className, '1 svelte-x1o6ra');
assert.equal(div.className, '1 svelte-70s021');

component.testName = 0;
assert.equal(div.className, '0 svelte-x1o6ra');
assert.equal(div.className, '0 svelte-70s021');

component.testName = false;
assert.equal(div.className, 'false svelte-x1o6ra');
assert.equal(div.className, 'false svelte-70s021');

component.testName = true;
assert.equal(div.className, 'true svelte-x1o6ra');
assert.equal(div.className, 'true svelte-70s021');

component.testName = {};
assert.equal(div.className, 'svelte-x1o6ra');
assert.equal(div.className, 'svelte-70s021');

component.testName = '';
assert.equal(div.className, 'svelte-x1o6ra');
assert.equal(div.className, 'svelte-70s021');
}
});
Original file line number Diff line number Diff line change
Expand Up @@ -10,43 +10,43 @@ export default test({
};
},

html: '<div class="test1test2 svelte-x1o6ra"></div>',
html: '<div class="test1test2 svelte-70s021"></div>',

async test({ assert, component, target }) {
const div = target.querySelector('div');
ok(div);
assert.equal(div.className, 'test1test2 svelte-x1o6ra');
assert.equal(div.className, 'test1test2 svelte-70s021');

component.testName1 = null;
component.testName2 = null;
assert.equal(div.className, '0 svelte-x1o6ra');
assert.equal(div.className, '0 svelte-70s021');

component.testName1 = null;
component.testName2 = 'test';
assert.equal(div.className, 'nulltest svelte-x1o6ra');
assert.equal(div.className, 'nulltest svelte-70s021');

component.testName1 = undefined;
component.testName2 = 'test';
assert.equal(div.className, 'undefinedtest svelte-x1o6ra');
assert.equal(div.className, 'undefinedtest svelte-70s021');

component.testName1 = undefined;
component.testName2 = undefined;
assert.equal(div.className, 'NaN svelte-x1o6ra');
assert.equal(div.className, 'NaN svelte-70s021');

component.testName1 = null;
component.testName2 = 1;
assert.equal(div.className, '1 svelte-x1o6ra');
assert.equal(div.className, '1 svelte-70s021');

component.testName1 = undefined;
component.testName2 = 1;
assert.equal(div.className, 'NaN svelte-x1o6ra');
assert.equal(div.className, 'NaN svelte-70s021');

component.testName1 = null;
component.testName2 = 0;
assert.equal(div.className, '0 svelte-x1o6ra');
assert.equal(div.className, '0 svelte-70s021');

component.testName1 = undefined;
component.testName2 = 0;
assert.equal(div.className, 'NaN svelte-x1o6ra');
assert.equal(div.className, 'NaN svelte-70s021');
}
});
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { test } from '../../test';
export default test({
async test({ assert, target, logs }) {
const [my_element, my_element_1] = target.querySelectorAll('my-element');
assert.equal(my_element.classList.contains('svelte-1koh33s'), true);
assert.equal(my_element_1.classList.contains('svelte-1koh33s'), true);
assert.equal(my_element.classList.contains('svelte-70s021'), true);
assert.equal(my_element_1.classList.contains('svelte-70s021'), true);
}
});
Original file line number Diff line number Diff line change
@@ -1,14 +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>`,
html: `<custom-element class="red svelte-70s021"></custom-element><custom-element class="red svelte-70s021"></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');
assert.deepEqual(el.className, 'red svelte-70s021');
assert.deepEqual(el2.className, 'red svelte-70s021');
}
});
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<!--[--><div class="foo svelte-gfnjhw">foo</div><!--]-->
<!--[--><div class="foo svelte-1h3glmj">foo</div><!--]-->
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<style id="svelte-gfnjhw">.foo.svelte-gfnjhw {color:green;}.foo.svelte-gfnjhw {color:green;} .foo.svelte-gfnjhw {color:green;}.foo.svelte-gfnjhw, .foo.svelte-gfnjhw {color:green;}</style>
<style id="svelte-1h3glmj">.foo.svelte-1h3glmj {color:green;}.foo.svelte-1h3glmj {color:green;} .foo.svelte-1h3glmj {color:green;}.foo.svelte-1h3glmj, .foo.svelte-1h3glmj {color:green;}</style>
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@

.foo.svelte-sg04hs {
.foo.svelte-1nvcr6w {
color: red;
}
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<!--[--><div class="bar svelte-ievf05">bar</div><!----> <div class="foo svelte-sg04hs">foo</div><!--]-->
<!--[--><div class="bar svelte-1nvcr6w">bar</div><!----> <div class="foo svelte-sg04hs">foo</div><!--]-->
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<style id="svelte-ievf05">.bar.svelte-ievf05 {color:red;}</style>
<style id="svelte-lr8eda">.bar.svelte-lr8eda {color:red;}</style>
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@

.foo.svelte-sg04hs {
.foo.svelte-okauro {
color: red;
}
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<div class="foo svelte-sg04hs">foo</div>
<div class="foo svelte-okauro">foo</div>
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<style id="svelte-sg04hs">.foo.svelte-sg04hs {color:red;}</style>
<style id="svelte-okauro">.foo.svelte-okauro {color:red;}</style>
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@

.foo.svelte-sg04hs {
.foo.svelte-e9omc {
color: red;
}
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<div class="foo svelte-sg04hs">foo</div>
<div class="foo svelte-e9omc">foo</div>
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<style id="svelte-sg04hs">.foo.svelte-sg04hs {color:red;}</style>
<style id="svelte-e9omc">.foo.svelte-e9omc {color:red;}</style>
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ export default test({
{ str: 'replace_me_script', strGenerated: 'done_replace_script_2' },
{ str: 'done_replace_script_2', idxGenerated: 1 }
],
css: [{ str: '.replace_me_style', strGenerated: '.done_replace_style_2.svelte-o6vre' }],
css: [{ str: '.replace_me_style', strGenerated: '.done_replace_style_2.svelte-1vsrjd4' }],
test({ assert, code_preprocessed, code_css }) {
assert.equal(
code_preprocessed.includes('\n/*# sourceMappingURL=data:application/json;base64,'),
Expand Down
Loading
Loading