diff --git a/src/Stats.ts b/src/Stats.ts index 7653d6e303..ea378bcaeb 100644 --- a/src/Stats.ts +++ b/src/Stats.ts @@ -108,7 +108,7 @@ export default class Stats { timings, warnings: this.warnings, imports, - templateReferences: component && component.expectedProperties, + templateReferences: component && component.template_references, hooks }; } diff --git a/src/compile/Component.ts b/src/compile/Component.ts index c603ae047b..22e8a6ac1e 100644 --- a/src/compile/Component.ts +++ b/src/compile/Component.ts @@ -59,8 +59,7 @@ export default class Component { instance_scope_map: WeakMap; meta: Meta; - - customElement: CustomElementOptions; + namespace: string; tag: string; properties: Map; @@ -69,7 +68,6 @@ export default class Component { module_script: Node; imports: Node[] = []; - namespace: string; hasComponents: boolean; module_javascript: string; javascript: string; @@ -86,7 +84,7 @@ export default class Component { code: MagicString; indirectDependencies: Map> = new Map(); - expectedProperties: Set = new Set(); + template_references: Set = new Set(); refs: Set = new Set(); file: string; @@ -141,28 +139,25 @@ export default class Component { this.meta = process_meta(this, this.ast.html.children); this.namespace = namespaces[this.meta.namespace] || this.meta.namespace; - if (options.customElement === true) { - this.customElement = { - tag: this.meta.tag, - props: [] // TODO!!! - }; - } else { - this.customElement = options.customElement; - } - - if (this.customElement && !this.customElement.tag) { + if (options.customElement === true && !this.meta.tag) { throw new Error(`No tag name specified`); // TODO better error } + this.tag = options.customElement + ? options.customElement === true + ? this.meta.tag + : options.customElement + : this.name; + this.fragment = new Fragment(this, ast.html); - if (!this.customElement) this.stylesheet.reify(); + if (!options.customElement) this.stylesheet.reify(); this.stylesheet.warnOnUnusedSelectors(options.onwarn); if (!this.instance_script) { - const props = [...this.expectedProperties]; + const props = [...this.template_references]; this.declarations.push(...props); - addToSet(this.writable_declarations, this.expectedProperties); + addToSet(this.writable_declarations, this.template_references); this.exports = props.map(name => ({ name, @@ -270,7 +265,7 @@ export default class Component { addString(finalChunk); - const css = this.customElement ? + const css = options.customElement ? { code: null, map: null } : this.stylesheet.render(options.cssOutputFilename, true); diff --git a/src/compile/nodes/InlineComponent.ts b/src/compile/nodes/InlineComponent.ts index 32f1425059..017b28afd1 100644 --- a/src/compile/nodes/InlineComponent.ts +++ b/src/compile/nodes/InlineComponent.ts @@ -22,7 +22,7 @@ export default class InlineComponent extends Node { if (info.name !== 'svelte:component' && info.name !== 'svelte:self') { component.warn_if_undefined(info, scope); - component.expectedProperties.add(info.name); + component.template_references.add(info.name); } component.hasComponents = true; diff --git a/src/compile/nodes/shared/Expression.ts b/src/compile/nodes/shared/Expression.ts index 0bb524ff35..80bc89a678 100644 --- a/src/compile/nodes/shared/Expression.ts +++ b/src/compile/nodes/shared/Expression.ts @@ -137,7 +137,7 @@ export default class Expression { }); } else { dependencies.add(name); - component.expectedProperties.add(name); + component.template_references.add(name); } this.skip(); @@ -216,7 +216,7 @@ export default class Expression { }); } else { dependencies.add(name); - component.expectedProperties.add(name); + component.template_references.add(name); } } else if (!is_synthetic) { code.prependRight(node.start, key === 'key' && parent.shorthand diff --git a/src/compile/render-dom/index.ts b/src/compile/render-dom/index.ts index f2c46a31ea..09564f0a84 100644 --- a/src/compile/render-dom/index.ts +++ b/src/compile/render-dom/index.ts @@ -27,12 +27,12 @@ export default function dom( builder.addLine(`const ${renderer.fileVar} = ${JSON.stringify(component.file)};`); } - const css = component.stylesheet.render(options.filename, !component.customElement); + const css = component.stylesheet.render(options.filename, !options.customElement); const styles = component.stylesheet.hasStyles && stringify(options.dev ? `${css.code}\n/*# sourceMappingURL=${css.map.toUrl()} */` : css.code, { onlyEscapeAtSymbol: true }); - if (styles && component.options.css !== false && !component.customElement) { + if (styles && component.options.css !== false && !options.customElement) { builder.addBlock(deindent` function @add_css() { var style = @createElement("style"); @@ -64,7 +64,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 = ( - !component.options.customElement && + !options.customElement && component.stylesheet.hasStyles && options.css !== false ); @@ -95,7 +95,6 @@ export default function dom( const body = []; - const debug_name = `<${component.customElement ? component.customElement.tag : name}>`; const not_equal = component.options.immutable ? `@not_equal` : `@safe_not_equal`; let dev_props_check; @@ -116,7 +115,7 @@ export default function dom( } else if (component.options.dev) { body.push(deindent` set ${x.as}(value) { - throw new Error("${debug_name}: Cannot set read-only property '${x.as}'"); + throw new Error("<${component.tag}>: Cannot set read-only property '${x.as}'"); } `); } @@ -134,8 +133,8 @@ export default function dom( const state = this.$$.get(); ${expected.map(name => deindent` - if (state.${name} === undefined${component.customElement && ` && !('${name}' in this.attributes)`}) { - console.warn("${debug_name} was created without expected data property '${name}'"); + if (state.${name} === undefined${options.customElement && ` && !('${name}' in this.attributes)`}) { + console.warn("<${component.tag}> was created without expected data property '${name}'"); }`)} `; } @@ -195,7 +194,7 @@ export default function dom( } `); - if (component.customElement) { + if (options.customElement) { builder.addBlock(deindent` class ${name} extends @SvelteElement { constructor(options) { @@ -226,7 +225,7 @@ export default function dom( ${body.join('\n\n')} } - customElements.define("${component.customElement.tag}", ${name}); + customElements.define("${component.tag}", ${name}); `); } else { builder.addBlock(deindent` diff --git a/src/compile/render-ssr/index.ts b/src/compile/render-ssr/index.ts index 95f028574d..ffe2f24fb4 100644 --- a/src/compile/render-ssr/index.ts +++ b/src/compile/render-ssr/index.ts @@ -1,9 +1,7 @@ import deindent from '../../utils/deindent'; import Component from '../Component'; -import globalWhitelist from '../../utils/globalWhitelist'; import { CompileOptions } from '../../interfaces'; import { stringify } from '../../utils/stringify'; -import CodeBuilder from '../../utils/CodeBuilder'; import Renderer from './Renderer'; export default function ssr( @@ -19,13 +17,10 @@ export default function ssr( locate: component.locate }, options)); - const css = component.customElement ? + const css = options.customElement ? { code: null, map: null } : component.stylesheet.render(options.filename, true); - const expectedProperties = Array.from(component.expectedProperties); - const debugName = `<${component.customElement ? component.tag : name}>`; - // TODO concatenate CSS maps return (deindent` function #define($$props) {