tidy up custom element options

pull/1839/head
Rich Harris 7 years ago
parent 6060a308ad
commit a09dc36ea5

@ -108,7 +108,7 @@ export default class Stats {
timings, timings,
warnings: this.warnings, warnings: this.warnings,
imports, imports,
templateReferences: component && component.expectedProperties, templateReferences: component && component.template_references,
hooks hooks
}; };
} }

@ -59,8 +59,7 @@ export default class Component {
instance_scope_map: WeakMap<Node, Scope>; instance_scope_map: WeakMap<Node, Scope>;
meta: Meta; meta: Meta;
namespace: string;
customElement: CustomElementOptions;
tag: string; tag: string;
properties: Map<string, Node>; properties: Map<string, Node>;
@ -69,7 +68,6 @@ export default class Component {
module_script: Node; module_script: Node;
imports: Node[] = []; imports: Node[] = [];
namespace: string;
hasComponents: boolean; hasComponents: boolean;
module_javascript: string; module_javascript: string;
javascript: string; javascript: string;
@ -86,7 +84,7 @@ export default class Component {
code: MagicString; code: MagicString;
indirectDependencies: Map<string, Set<string>> = new Map(); indirectDependencies: Map<string, Set<string>> = new Map();
expectedProperties: Set<string> = new Set(); template_references: Set<string> = new Set();
refs: Set<string> = new Set(); refs: Set<string> = new Set();
file: string; file: string;
@ -141,28 +139,25 @@ export default class Component {
this.meta = process_meta(this, this.ast.html.children); this.meta = process_meta(this, this.ast.html.children);
this.namespace = namespaces[this.meta.namespace] || this.meta.namespace; this.namespace = namespaces[this.meta.namespace] || this.meta.namespace;
if (options.customElement === true) { if (options.customElement === true && !this.meta.tag) {
this.customElement = {
tag: this.meta.tag,
props: [] // TODO!!!
};
} else {
this.customElement = options.customElement;
}
if (this.customElement && !this.customElement.tag) {
throw new Error(`No tag name specified`); // TODO better error throw new Error(`No tag name specified`); // TODO better error
} }
this.tag = options.customElement
? options.customElement === true
? this.meta.tag
: <string>options.customElement
: this.name;
this.fragment = new Fragment(this, ast.html); this.fragment = new Fragment(this, ast.html);
if (!this.customElement) this.stylesheet.reify(); if (!options.customElement) this.stylesheet.reify();
this.stylesheet.warnOnUnusedSelectors(options.onwarn); this.stylesheet.warnOnUnusedSelectors(options.onwarn);
if (!this.instance_script) { if (!this.instance_script) {
const props = [...this.expectedProperties]; const props = [...this.template_references];
this.declarations.push(...props); this.declarations.push(...props);
addToSet(this.writable_declarations, this.expectedProperties); addToSet(this.writable_declarations, this.template_references);
this.exports = props.map(name => ({ this.exports = props.map(name => ({
name, name,
@ -270,7 +265,7 @@ export default class Component {
addString(finalChunk); addString(finalChunk);
const css = this.customElement ? const css = options.customElement ?
{ code: null, map: null } : { code: null, map: null } :
this.stylesheet.render(options.cssOutputFilename, true); this.stylesheet.render(options.cssOutputFilename, true);

@ -22,7 +22,7 @@ export default class InlineComponent extends Node {
if (info.name !== 'svelte:component' && info.name !== 'svelte:self') { if (info.name !== 'svelte:component' && info.name !== 'svelte:self') {
component.warn_if_undefined(info, scope); component.warn_if_undefined(info, scope);
component.expectedProperties.add(info.name); component.template_references.add(info.name);
} }
component.hasComponents = true; component.hasComponents = true;

@ -137,7 +137,7 @@ export default class Expression {
}); });
} else { } else {
dependencies.add(name); dependencies.add(name);
component.expectedProperties.add(name); component.template_references.add(name);
} }
this.skip(); this.skip();
@ -216,7 +216,7 @@ export default class Expression {
}); });
} else { } else {
dependencies.add(name); dependencies.add(name);
component.expectedProperties.add(name); component.template_references.add(name);
} }
} else if (!is_synthetic) { } else if (!is_synthetic) {
code.prependRight(node.start, key === 'key' && parent.shorthand code.prependRight(node.start, key === 'key' && parent.shorthand

@ -27,12 +27,12 @@ export default function dom(
builder.addLine(`const ${renderer.fileVar} = ${JSON.stringify(component.file)};`); 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 ? const styles = component.stylesheet.hasStyles && stringify(options.dev ?
`${css.code}\n/*# sourceMappingURL=${css.map.toUrl()} */` : `${css.code}\n/*# sourceMappingURL=${css.map.toUrl()} */` :
css.code, { onlyEscapeAtSymbol: true }); css.code, { onlyEscapeAtSymbol: true });
if (styles && component.options.css !== false && !component.customElement) { if (styles && component.options.css !== false && !options.customElement) {
builder.addBlock(deindent` builder.addBlock(deindent`
function @add_css() { function @add_css() {
var style = @createElement("style"); 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 // TODO injecting CSS this way is kinda dirty. Maybe it should be an
// explicit opt-in, or something? // explicit opt-in, or something?
const should_add_css = ( const should_add_css = (
!component.options.customElement && !options.customElement &&
component.stylesheet.hasStyles && component.stylesheet.hasStyles &&
options.css !== false options.css !== false
); );
@ -95,7 +95,6 @@ export default function dom(
const body = []; const body = [];
const debug_name = `<${component.customElement ? component.customElement.tag : name}>`;
const not_equal = component.options.immutable ? `@not_equal` : `@safe_not_equal`; const not_equal = component.options.immutable ? `@not_equal` : `@safe_not_equal`;
let dev_props_check; let dev_props_check;
@ -116,7 +115,7 @@ export default function dom(
} else if (component.options.dev) { } else if (component.options.dev) {
body.push(deindent` body.push(deindent`
set ${x.as}(value) { 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(); const state = this.$$.get();
${expected.map(name => deindent` ${expected.map(name => deindent`
if (state.${name} === undefined${component.customElement && ` && !('${name}' in this.attributes)`}) { if (state.${name} === undefined${options.customElement && ` && !('${name}' in this.attributes)`}) {
console.warn("${debug_name} was created without expected data property '${name}'"); 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` builder.addBlock(deindent`
class ${name} extends @SvelteElement { class ${name} extends @SvelteElement {
constructor(options) { constructor(options) {
@ -226,7 +225,7 @@ export default function dom(
${body.join('\n\n')} ${body.join('\n\n')}
} }
customElements.define("${component.customElement.tag}", ${name}); customElements.define("${component.tag}", ${name});
`); `);
} else { } else {
builder.addBlock(deindent` builder.addBlock(deindent`

@ -1,9 +1,7 @@
import deindent from '../../utils/deindent'; import deindent from '../../utils/deindent';
import Component from '../Component'; import Component from '../Component';
import globalWhitelist from '../../utils/globalWhitelist';
import { CompileOptions } from '../../interfaces'; import { CompileOptions } from '../../interfaces';
import { stringify } from '../../utils/stringify'; import { stringify } from '../../utils/stringify';
import CodeBuilder from '../../utils/CodeBuilder';
import Renderer from './Renderer'; import Renderer from './Renderer';
export default function ssr( export default function ssr(
@ -19,13 +17,10 @@ export default function ssr(
locate: component.locate locate: component.locate
}, options)); }, options));
const css = component.customElement ? const css = options.customElement ?
{ code: null, map: null } : { code: null, map: null } :
component.stylesheet.render(options.filename, true); component.stylesheet.render(options.filename, true);
const expectedProperties = Array.from(component.expectedProperties);
const debugName = `<${component.customElement ? component.tag : name}>`;
// TODO concatenate CSS maps // TODO concatenate CSS maps
return (deindent` return (deindent`
function #define($$props) { function #define($$props) {

Loading…
Cancel
Save