diff --git a/src/compile/Component.ts b/src/compile/Component.ts index bf2fdf9a5a..3fcc470070 100644 --- a/src/compile/Component.ts +++ b/src/compile/Component.ts @@ -168,7 +168,7 @@ export default class Component { this.walk_instance_js_post_template(); - if (!compile_options.customElement) this.stylesheet.reify(); + if (!compile_options.shadowDom) this.stylesheet.reify(); this.stylesheet.warn_on_unused_selectors(this); } @@ -317,7 +317,7 @@ export default class Component { add_string(final_chunk); - css = compile_options.customElement ? + css = compile_options.shadowDom ? { code: null, map: null } : this.stylesheet.render(compile_options.cssOutputFilename, true); diff --git a/src/compile/render-dom/index.ts b/src/compile/render-dom/index.ts index 6b2bbe1c29..196d248fe5 100644 --- a/src/compile/render-dom/index.ts +++ b/src/compile/render-dom/index.ts @@ -22,8 +22,6 @@ export default function dom( block.has_outro_method = true; - const should_use_shadow_dom = options.customElement && options.shadowDom !== false; - // prevent fragment being created twice (#1063) if (options.customElement) block.builders.create.add_line(`this.c = @noop;`); @@ -33,12 +31,13 @@ export default function dom( builder.add_line(`const ${renderer.file_var} = ${JSON.stringify(component.file)};`); } - const css = component.stylesheet.render(options.filename, !options.customElement); + + const css = component.stylesheet.render(options.filename, !options.shadowDom); const styles = component.stylesheet.has_styles && stringify(options.dev ? `${css.code}\n/*# sourceMappingURL=${css.map.toUrl()} */` : css.code, { only_escape_at_symbol: true }); - if (styles && component.compile_options.css !== false && !options.customElement) { + if (styles && component.compile_options.css !== false && !options.shadowDom) { builder.add_block(deindent` function @add_css() { var style = @element("style"); @@ -66,7 +65,7 @@ export default function dom( // TODO injecting CSS this way is kinda dirty. Maybe it should be an // explicit opt-in, or something? const should_add_css = ( - !should_use_shadow_dom && + !options.shadowDom && component.stylesheet.has_styles && options.css !== false ); @@ -445,11 +444,12 @@ export default function dom( builder.add_block(deindent` class ${name} extends @SvelteElement { constructor(options) { - super(${should_use_shadow_dom ? '' : '{ use_shadow_dom: false }'}); + super(${options.shadowDom ? '' : '{ use_shadow_dom: false }'}); - ${css.code && should_use_shadow_dom && `this.shadowRoot.innerHTML = \`\`;`} + ${css.code && options.shadowDom && `this.shadowRoot.innerHTML = \`\`;`} + ${should_add_css && `if (!document.getElementById("${component.stylesheet.id}-style")) @add_css();`} - @init(this, { target: this${should_use_shadow_dom ? '.shadowRoot' : ''} }, ${definition}, create_fragment, ${not_equal}, ${prop_names}); + @init(this, { target: this${options.shadowDom ? '.shadowRoot' : ''} }, ${definition}, create_fragment, ${not_equal}, ${prop_names}); ${dev_props_check} diff --git a/src/compile/render-ssr/index.ts b/src/compile/render-ssr/index.ts index 10f82beb5e..9cf02d271c 100644 --- a/src/compile/render-ssr/index.ts +++ b/src/compile/render-ssr/index.ts @@ -19,7 +19,7 @@ export default function ssr( }, options)); // TODO concatenate CSS maps - const css = options.customElement ? + const css = options.shadowDom ? { code: null, map: null } : component.stylesheet.render(options.filename, true); diff --git a/src/parse/index.ts b/src/parse/index.ts index 39c6972213..2e1cc23bc5 100644 --- a/src/parse/index.ts +++ b/src/parse/index.ts @@ -8,7 +8,7 @@ import error from '../utils/error'; interface ParserOptions { filename?: string; - customElement?: boolean; + shadowDom?: boolean; } type ParserState = (parser: Parser) => (ParserState | void); @@ -16,7 +16,7 @@ type ParserState = (parser: Parser) => (ParserState | void); export class Parser { readonly template: string; readonly filename?: string; - readonly customElement: boolean; + readonly shadowDom: boolean; index = 0; stack: Array = []; @@ -33,7 +33,7 @@ export class Parser { this.template = template.replace(/\s+$/, ''); this.filename = options.filename; - this.customElement = options.customElement; + this.shadowDom = options.shadowDom; this.html = { start: null, diff --git a/src/parse/state/tag.ts b/src/parse/state/tag.ts index 3747d2d482..2e6f0a7e09 100644 --- a/src/parse/state/tag.ts +++ b/src/parse/state/tag.ts @@ -132,7 +132,7 @@ export default function tag(parser: Parser) { ? meta_tags.get(name) : (/[A-Z]/.test(name[0]) || name === 'svelte:self' || name === 'svelte:component') ? 'InlineComponent' : name === 'title' && parent_is_head(parser.stack) ? 'Title' - : name === 'slot' && !parser.customElement ? 'Slot' : 'Element'; + : name === 'slot' && !parser.shadowDom ? 'Slot' : 'Element'; const element: Node = { start, diff --git a/test/js/samples/css-custom-element-no-shadow-dom/expected.js b/test/js/samples/css-custom-element-no-shadow-dom/expected.js index eb6fed9478..0591092b99 100644 --- a/test/js/samples/css-custom-element-no-shadow-dom/expected.js +++ b/test/js/samples/css-custom-element-no-shadow-dom/expected.js @@ -1,6 +1,7 @@ /* generated by Svelte vX.Y.Z */ import { SvelteElement, + append, detach, element, init, @@ -9,6 +10,13 @@ import { safe_not_equal } from "svelte/internal"; +function add_css() { + var style = element("style"); + style.id = 'svelte-pbe34-style'; + style.textContent = "h1.svelte-pbe34{color:blue}"; + append(document.head, style); +} + function create_fragment(ctx) { var h1; @@ -17,6 +25,7 @@ function create_fragment(ctx) { h1 = element("h1"); h1.textContent = "Hello world"; this.c = noop; + h1.className = "svelte-pbe34"; }, m(target, anchor) { @@ -38,6 +47,7 @@ function create_fragment(ctx) { class Component extends SvelteElement { constructor(options) { super({ use_shadow_dom: false }); + if (!document.getElementById("svelte-pbe34-style")) add_css(); init(this, { target: this }, null, create_fragment, safe_not_equal, []);