diff --git a/src/compiler/compile/index.ts b/src/compiler/compile/index.ts index afe9c56cf4..3d47be1851 100644 --- a/src/compiler/compile/index.ts +++ b/src/compiler/compile/index.ts @@ -35,8 +35,16 @@ const valid_options = [ 'cssHash' ]; +const valid_css_values = [ + true, + false, + 'injected', + 'external', + 'none' +]; + function validate_options(options: CompileOptions, warnings: Warning[]) { - const { name, filename, loopGuardTimeout, dev, namespace } = options; + const { name, filename, loopGuardTimeout, dev, namespace, css } = options; Object.keys(options).forEach(key => { if (!valid_options.includes(key)) { @@ -72,6 +80,21 @@ function validate_options(options: CompileOptions, warnings: Warning[]) { }); } + if (valid_css_values.indexOf(css) === -1) { + throw new Error(`options.css must be true, false, "injected", "external" or "none" (got '${css}')`); + } + + if (css === true || css === false) { + options.css = css === true ? 'injected' : 'external'; + const message = `options.css as a boolean is deprecated. Use "${options.css}" instead of ${css}.`; + warnings.push({ + code: 'options-css-boolean-deprecated', + message, + filename, + toString: () => message + }); + } + if (namespace && valid_namespaces.indexOf(namespace) === -1) { const match = fuzzymatch(namespace, valid_namespaces); if (match) { @@ -83,7 +106,7 @@ function validate_options(options: CompileOptions, warnings: Warning[]) { } export default function compile(source: string, options: CompileOptions = {}) { - options = Object.assign({ generate: 'dom', dev: false, enableSourcemap: true }, options); + options = Object.assign({ generate: 'dom', dev: false, enableSourcemap: true, css: 'injected' }, options); const stats = new Stats(); const warnings = []; diff --git a/src/compiler/compile/render_dom/index.ts b/src/compiler/compile/render_dom/index.ts index 173d93d5dd..b06c5b577c 100644 --- a/src/compiler/compile/render_dom/index.ts +++ b/src/compiler/compile/render_dom/index.ts @@ -53,7 +53,7 @@ export default function dom( const should_add_css = ( !options.customElement && !!styles && - options.css !== false + options.css === 'injected' ); if (should_add_css) { diff --git a/src/compiler/interfaces.ts b/src/compiler/interfaces.ts index 248175da59..eb2cc336ed 100644 --- a/src/compiler/interfaces.ts +++ b/src/compiler/interfaces.ts @@ -179,7 +179,7 @@ export interface CompileOptions { legacy?: boolean; customElement?: boolean; tag?: string; - css?: boolean; + css?: 'injected' | 'external' | 'none' | boolean; loopGuardTimeout?: number; namespace?: string; cssHash?: CssHashGetter; @@ -191,6 +191,7 @@ export interface CompileOptions { export interface ParserOptions { filename?: string; customElement?: boolean; + css?: 'injected' | 'external' | 'none' | boolean; } export interface Visitor { diff --git a/src/compiler/parse/index.ts b/src/compiler/parse/index.ts index e5e2260bc0..ce873c7d84 100644 --- a/src/compiler/parse/index.ts +++ b/src/compiler/parse/index.ts @@ -19,6 +19,7 @@ export class Parser { readonly template: string; readonly filename?: string; readonly customElement: boolean; + readonly css_mode: 'injected' | 'external' | 'none' | boolean; index = 0; stack: TemplateNode[] = []; @@ -37,6 +38,7 @@ export class Parser { this.template = template.trimRight(); this.filename = options.filename; this.customElement = options.customElement; + this.css_mode = options.css; this.html = { start: null, diff --git a/src/compiler/parse/read/style.ts b/src/compiler/parse/read/style.ts index e4a885a8cc..15e77d2ff6 100644 --- a/src/compiler/parse/read/style.ts +++ b/src/compiler/parse/read/style.ts @@ -16,6 +16,12 @@ export default function read_style(parser: Parser, start: number, attributes: No const content_end = parser.index; + // discard styles when css is disabled + if (parser.css_mode === 'none') { + parser.read(/<\/style\s*>/); + return null; + } + let ast; try { diff --git a/test/parser/samples/css-option-none/input.svelte b/test/parser/samples/css-option-none/input.svelte new file mode 100644 index 0000000000..659c4343f6 --- /dev/null +++ b/test/parser/samples/css-option-none/input.svelte @@ -0,0 +1,7 @@ +
foo
+ + diff --git a/test/parser/samples/css-option-none/options.json b/test/parser/samples/css-option-none/options.json new file mode 100644 index 0000000000..b10d517cc9 --- /dev/null +++ b/test/parser/samples/css-option-none/options.json @@ -0,0 +1,3 @@ +{ + "css": "none" +} diff --git a/test/parser/samples/css-option-none/output.json b/test/parser/samples/css-option-none/output.json new file mode 100644 index 0000000000..ef1f9c9a37 --- /dev/null +++ b/test/parser/samples/css-option-none/output.json @@ -0,0 +1,32 @@ +{ + "html": { + "start": 0, + "end": 14, + "type": "Fragment", + "children": [ + { + "start": 0, + "end": 14, + "type": "Element", + "name": "div", + "attributes": [], + "children": [ + { + "start": 5, + "end": 8, + "type": "Text", + "raw": "foo", + "data": "foo" + } + ] + }, + { + "start": 14, + "end": 16, + "type": "Text", + "raw": "\n\n", + "data": "\n\n" + } + ] + } +}