diff --git a/site/content/docs/04-compile-time.md b/site/content/docs/04-compile-time.md index f9bfa772fec1..fc2b38ad7985 100644 --- a/site/content/docs/04-compile-time.md +++ b/site/content/docs/04-compile-time.md @@ -58,7 +58,8 @@ The following options can be passed to the compiler. None are required: | `preserveWhitespace` | boolean | `false` | `outputFilename` | string | `null` | `cssOutputFilename` | string | `null` -| `sveltePath` | string | `"svelte"` --> +| `sveltePath` | string | `"svelte"` +| `prefix` | string | `"svelte-"` --> | option | default | description | | --- | --- | --- | @@ -80,7 +81,7 @@ The following options can be passed to the compiler. None are required: | `outputFilename` | `null` | A `string` used for your JavaScript sourcemap. | `cssOutputFilename` | `null` | A `string` used for your CSS sourcemap. | `sveltePath` | `"svelte"` | The location of the `svelte` package. Any imports from `svelte` or `svelte/[module]` will be modified accordingly. - +| `prefix` | `"svelte-"` | The prefix that will be used for scoping of css classes. It has to start with a `letter`, `-` or `_` and can be followed by `alphanumerics`, `-` or `_`. --- diff --git a/src/compiler/compile/Component.ts b/src/compiler/compile/Component.ts index c83f8153a01e..9466a1e47ff4 100644 --- a/src/compiler/compile/Component.ts +++ b/src/compiler/compile/Component.ts @@ -29,6 +29,7 @@ import add_to_set from './utils/add_to_set'; import check_graph_for_cycles from './utils/check_graph_for_cycles'; import { print, x, b } from 'code-red'; import { is_reserved_keyword } from './utils/reserved_keywords'; +import get_prefix from './utils/get_prefix'; interface ComponentOptions { namespace?: string; @@ -133,7 +134,8 @@ export default class Component { source, ast, compile_options.filename, - compile_options.dev + compile_options.dev, + get_prefix(compile_options.prefix), ); this.stylesheet.validate(this); diff --git a/src/compiler/compile/css/Stylesheet.ts b/src/compiler/compile/css/Stylesheet.ts index 246dab0f1219..94cf6641e4c3 100644 --- a/src/compiler/compile/css/Stylesheet.ts +++ b/src/compiler/compile/css/Stylesheet.ts @@ -291,14 +291,14 @@ export default class Stylesheet { nodes_with_css_class: Set = new Set(); - constructor(source: string, ast: Ast, filename: string, dev: boolean) { + constructor(source: string, ast: Ast, filename: string, dev: boolean, prefix: string) { 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 = `${prefix}-${hash(ast.css.content.styles)}`; this.has_styles = true; diff --git a/src/compiler/compile/index.ts b/src/compiler/compile/index.ts index 12b161aeeb0e..cff688b09c00 100644 --- a/src/compiler/compile/index.ts +++ b/src/compiler/compile/index.ts @@ -26,7 +26,8 @@ const valid_options = [ 'css', 'loopGuardTimeout', 'preserveComments', - 'preserveWhitespace' + 'preserveWhitespace', + 'prefix', ]; function validate_options(options: CompileOptions, warnings: Warning[]) { diff --git a/src/compiler/compile/utils/get_prefix.ts b/src/compiler/compile/utils/get_prefix.ts new file mode 100644 index 000000000000..9bed13e30b82 --- /dev/null +++ b/src/compiler/compile/utils/get_prefix.ts @@ -0,0 +1,9 @@ +export default function get_prefix(str?: string): string { + const standard_prefix = 'svelte'; + if (!str + || typeof str !== 'string') return standard_prefix; + str = str.replace(/^[^_\-a-z]+|[^_\-a-z0-9]/gi, ''); + return str.length + ? str + : standard_prefix; +} \ No newline at end of file diff --git a/src/compiler/interfaces.ts b/src/compiler/interfaces.ts index a5e286462ff3..05b7fb667a58 100644 --- a/src/compiler/interfaces.ts +++ b/src/compiler/interfaces.ts @@ -123,6 +123,7 @@ export interface CompileOptions { tag?: string; css?: boolean; loopGuardTimeout?: number; + prefix?: string; preserveComments?: boolean; preserveWhitespace?: boolean; diff --git a/test/css/index.js b/test/css/index.js index dc17314597fa..5fd9faae0d9e 100644 --- a/test/css/index.js +++ b/test/css/index.js @@ -84,7 +84,13 @@ describe('css', () => { css: read(`${__dirname}/samples/${dir}/expected.css`) }; - const actual_css = dom.css.code.replace(/svelte(-ref)?-[a-z0-9]+/g, (m, $1) => $1 ? m : 'svelte-xyz'); + const replacement = ((config.compileOptions || {}).prefix) + ? '-xyz{' + : 'svelte-xyz'; + const regex = ((config.compileOptions || {}).prefix) + ? /(-ref)?-[a-z0-9]+\{/g + : /svelte(-ref)?-[a-z0-9]+/g; + const actual_css = dom.css.code.replace(regex, (m, $1) => $1 ? m : replacement); try { assert.equal(actual_css, expected.css); } catch (error) { diff --git a/test/css/samples/custom-prefix-has-only-disallowed-characters/_config.js b/test/css/samples/custom-prefix-has-only-disallowed-characters/_config.js new file mode 100644 index 000000000000..90eadd250571 --- /dev/null +++ b/test/css/samples/custom-prefix-has-only-disallowed-characters/_config.js @@ -0,0 +1,5 @@ +export default { + compileOptions: { + prefix: ' $!*' + } +}; \ No newline at end of file diff --git a/test/css/samples/custom-prefix-has-only-disallowed-characters/expected.css b/test/css/samples/custom-prefix-has-only-disallowed-characters/expected.css new file mode 100644 index 000000000000..5e31d0bc6b09 --- /dev/null +++ b/test/css/samples/custom-prefix-has-only-disallowed-characters/expected.css @@ -0,0 +1 @@ +div.svelte-xyz{color:blue} \ No newline at end of file diff --git a/test/css/samples/custom-prefix-has-only-disallowed-characters/input.svelte b/test/css/samples/custom-prefix-has-only-disallowed-characters/input.svelte new file mode 100644 index 000000000000..242eb44a660e --- /dev/null +++ b/test/css/samples/custom-prefix-has-only-disallowed-characters/input.svelte @@ -0,0 +1,7 @@ +
+ + \ No newline at end of file diff --git a/test/css/samples/custom-prefix-has-special-character/_config.js b/test/css/samples/custom-prefix-has-special-character/_config.js new file mode 100644 index 000000000000..18ab64783944 --- /dev/null +++ b/test/css/samples/custom-prefix-has-special-character/_config.js @@ -0,0 +1,5 @@ +export default { + compileOptions: { + prefix: 'me$' + } +}; \ No newline at end of file diff --git a/test/css/samples/custom-prefix-has-special-character/expected.css b/test/css/samples/custom-prefix-has-special-character/expected.css new file mode 100644 index 000000000000..2af15fb79732 --- /dev/null +++ b/test/css/samples/custom-prefix-has-special-character/expected.css @@ -0,0 +1 @@ +div.me-xyz{color:blue} \ No newline at end of file diff --git a/test/css/samples/custom-prefix-has-special-character/input.svelte b/test/css/samples/custom-prefix-has-special-character/input.svelte new file mode 100644 index 000000000000..242eb44a660e --- /dev/null +++ b/test/css/samples/custom-prefix-has-special-character/input.svelte @@ -0,0 +1,7 @@ +
+ + \ No newline at end of file diff --git a/test/css/samples/custom-prefix-has-whitespace/_config.js b/test/css/samples/custom-prefix-has-whitespace/_config.js new file mode 100644 index 000000000000..ba04f4a11109 --- /dev/null +++ b/test/css/samples/custom-prefix-has-whitespace/_config.js @@ -0,0 +1,5 @@ +export default { + compileOptions: { + prefix: 'm e' + } +}; \ No newline at end of file diff --git a/test/css/samples/custom-prefix-has-whitespace/expected.css b/test/css/samples/custom-prefix-has-whitespace/expected.css new file mode 100644 index 000000000000..2af15fb79732 --- /dev/null +++ b/test/css/samples/custom-prefix-has-whitespace/expected.css @@ -0,0 +1 @@ +div.me-xyz{color:blue} \ No newline at end of file diff --git a/test/css/samples/custom-prefix-has-whitespace/input.svelte b/test/css/samples/custom-prefix-has-whitespace/input.svelte new file mode 100644 index 000000000000..242eb44a660e --- /dev/null +++ b/test/css/samples/custom-prefix-has-whitespace/input.svelte @@ -0,0 +1,7 @@ +
+ + \ No newline at end of file diff --git a/test/css/samples/custom-prefix-no-string/_config.js b/test/css/samples/custom-prefix-no-string/_config.js new file mode 100644 index 000000000000..616abeeb1343 --- /dev/null +++ b/test/css/samples/custom-prefix-no-string/_config.js @@ -0,0 +1,5 @@ +export default { + compileOptions: { + prefix: true + } +}; \ No newline at end of file diff --git a/test/css/samples/custom-prefix-no-string/expected.css b/test/css/samples/custom-prefix-no-string/expected.css new file mode 100644 index 000000000000..5e31d0bc6b09 --- /dev/null +++ b/test/css/samples/custom-prefix-no-string/expected.css @@ -0,0 +1 @@ +div.svelte-xyz{color:blue} \ No newline at end of file diff --git a/test/css/samples/custom-prefix-no-string/input.svelte b/test/css/samples/custom-prefix-no-string/input.svelte new file mode 100644 index 000000000000..242eb44a660e --- /dev/null +++ b/test/css/samples/custom-prefix-no-string/input.svelte @@ -0,0 +1,7 @@ +
+ + \ No newline at end of file diff --git a/test/css/samples/custom-prefix-starts-with-number/_config.js b/test/css/samples/custom-prefix-starts-with-number/_config.js new file mode 100644 index 000000000000..3d6f9735fc3d --- /dev/null +++ b/test/css/samples/custom-prefix-starts-with-number/_config.js @@ -0,0 +1,5 @@ +export default { + compileOptions: { + prefix: '0me' + } +}; \ No newline at end of file diff --git a/test/css/samples/custom-prefix-starts-with-number/expected.css b/test/css/samples/custom-prefix-starts-with-number/expected.css new file mode 100644 index 000000000000..2af15fb79732 --- /dev/null +++ b/test/css/samples/custom-prefix-starts-with-number/expected.css @@ -0,0 +1 @@ +div.me-xyz{color:blue} \ No newline at end of file diff --git a/test/css/samples/custom-prefix-starts-with-number/input.svelte b/test/css/samples/custom-prefix-starts-with-number/input.svelte new file mode 100644 index 000000000000..242eb44a660e --- /dev/null +++ b/test/css/samples/custom-prefix-starts-with-number/input.svelte @@ -0,0 +1,7 @@ +
+ + \ No newline at end of file diff --git a/test/css/samples/custom-prefix-starts-with-whitespace/_config.js b/test/css/samples/custom-prefix-starts-with-whitespace/_config.js new file mode 100644 index 000000000000..c0f23c1e5897 --- /dev/null +++ b/test/css/samples/custom-prefix-starts-with-whitespace/_config.js @@ -0,0 +1,5 @@ +export default { + compileOptions: { + prefix: ' me' + } +}; \ No newline at end of file diff --git a/test/css/samples/custom-prefix-starts-with-whitespace/expected.css b/test/css/samples/custom-prefix-starts-with-whitespace/expected.css new file mode 100644 index 000000000000..2af15fb79732 --- /dev/null +++ b/test/css/samples/custom-prefix-starts-with-whitespace/expected.css @@ -0,0 +1 @@ +div.me-xyz{color:blue} \ No newline at end of file diff --git a/test/css/samples/custom-prefix-starts-with-whitespace/input.svelte b/test/css/samples/custom-prefix-starts-with-whitespace/input.svelte new file mode 100644 index 000000000000..242eb44a660e --- /dev/null +++ b/test/css/samples/custom-prefix-starts-with-whitespace/input.svelte @@ -0,0 +1,7 @@ +
+ + \ No newline at end of file diff --git a/test/css/samples/custom-prefix/_config.js b/test/css/samples/custom-prefix/_config.js new file mode 100644 index 000000000000..95391be75ba0 --- /dev/null +++ b/test/css/samples/custom-prefix/_config.js @@ -0,0 +1,5 @@ +export default { + compileOptions: { + prefix: 'me' + } +}; \ No newline at end of file diff --git a/test/css/samples/custom-prefix/expected.css b/test/css/samples/custom-prefix/expected.css new file mode 100644 index 000000000000..2af15fb79732 --- /dev/null +++ b/test/css/samples/custom-prefix/expected.css @@ -0,0 +1 @@ +div.me-xyz{color:blue} \ No newline at end of file diff --git a/test/css/samples/custom-prefix/input.svelte b/test/css/samples/custom-prefix/input.svelte new file mode 100644 index 000000000000..242eb44a660e --- /dev/null +++ b/test/css/samples/custom-prefix/input.svelte @@ -0,0 +1,7 @@ +
+ + \ No newline at end of file