diff --git a/src/compiler/compile/Component.ts b/src/compiler/compile/Component.ts index 8aab2b4898..22dec220b7 100644 --- a/src/compiler/compile/Component.ts +++ b/src/compiler/compile/Component.ts @@ -133,12 +133,15 @@ export default class Component { this.locate = getLocator(this.source, { offsetLine: 1 }); // styles - this.stylesheet = new Stylesheet( + this.stylesheet = new Stylesheet({ source, ast, - compile_options.filename, - compile_options.dev - ); + filename: compile_options.filename, + options: { + dev: compile_options.dev, + scope_class_getter: compile_options.scopeClass + } + }); this.stylesheet.validate(this); this.component_options = process_component_options( diff --git a/src/compiler/compile/css/Stylesheet.ts b/src/compiler/compile/css/Stylesheet.ts index b730079a89..1332192b3a 100644 --- a/src/compiler/compile/css/Stylesheet.ts +++ b/src/compiler/compile/css/Stylesheet.ts @@ -2,7 +2,7 @@ import MagicString from 'magic-string'; import { walk } from 'estree-walker'; import Selector from './Selector'; import Element from '../nodes/Element'; -import { Ast } from '../../interfaces'; +import { Ast, CssScopeClassGetter } from '../../interfaces'; import Component from '../Component'; import { CssNode } from './interfaces'; import hash from '../utils/hash'; @@ -275,6 +275,10 @@ class Atrule { } } +const getDefaultScopeClass: CssScopeClassGetter = ({ hash }) => { + return `svelte-${hash}`; +}; + export default class Stylesheet { source: string; ast: Ast; @@ -289,14 +293,27 @@ export default class Stylesheet { nodes_with_css_class: Set = new Set(); - constructor(source: string, ast: Ast, filename: string, dev: boolean) { + constructor({ + source, + ast, + filename, + options: { dev, scope_class_getter = getDefaultScopeClass }, + }: { + source: string; + ast: Ast; + filename: string; + options: { + dev: boolean; + scope_class_getter: CssScopeClassGetter; + }; + }) { this.source = source; this.ast = ast; this.filename = filename; this.dev = dev; if (ast.css && ast.css.children.length) { - this.id = `svelte-${hash(ast.css.content.styles)}`; + this.id = scope_class_getter({ filename, hash: hash(ast.css.content.styles) }); this.has_styles = true; diff --git a/src/compiler/compile/index.ts b/src/compiler/compile/index.ts index 9f9b31917e..17266cafc5 100644 --- a/src/compiler/compile/index.ts +++ b/src/compiler/compile/index.ts @@ -28,7 +28,8 @@ const valid_options = [ 'css', 'loopGuardTimeout', 'preserveComments', - 'preserveWhitespace' + 'preserveWhitespace', + 'scopeClass', ]; function validate_options(options: CompileOptions, warnings: Warning[]) { diff --git a/src/compiler/interfaces.ts b/src/compiler/interfaces.ts index b9c95ae06d..86da4f32a0 100644 --- a/src/compiler/interfaces.ts +++ b/src/compiler/interfaces.ts @@ -104,6 +104,12 @@ export interface Warning { export type ModuleFormat = 'esm' | 'cjs'; + +export type CssScopeClassGetter = (args: { + filename: string; + hash: string; +}) => string; + export interface CompileOptions { format?: ModuleFormat; name?: string; @@ -125,6 +131,7 @@ export interface CompileOptions { css?: boolean; loopGuardTimeout?: number; namespace?: string; + scopeClass?: CssScopeClassGetter; preserveComments?: boolean; preserveWhitespace?: boolean; @@ -166,7 +173,7 @@ export interface Var { imported?: boolean; } -export interface CssResult { +export interface CssResult { code: string; map: SourceMap; } diff --git a/test/css/samples/custom-scope-class/_config.js b/test/css/samples/custom-scope-class/_config.js new file mode 100644 index 0000000000..6e4386ecda --- /dev/null +++ b/test/css/samples/custom-scope-class/_config.js @@ -0,0 +1,7 @@ +export default { + compileOptions: { + scopeClass({ hash }) { + return `sv-${hash}`; + } + }, +}; diff --git a/test/css/samples/custom-scope-class/expected.css b/test/css/samples/custom-scope-class/expected.css new file mode 100644 index 0000000000..5eecaebfca --- /dev/null +++ b/test/css/samples/custom-scope-class/expected.css @@ -0,0 +1 @@ +div.sv-bzh57p{color:red} \ No newline at end of file diff --git a/test/css/samples/custom-scope-class/input.svelte b/test/css/samples/custom-scope-class/input.svelte new file mode 100644 index 0000000000..bfe5a23214 --- /dev/null +++ b/test/css/samples/custom-scope-class/input.svelte @@ -0,0 +1,7 @@ +
red
+ +