diff --git a/src/compiler/compile/Component.ts b/src/compiler/compile/Component.ts
index ae2c4b704adb..6ab230c53691 100644
--- a/src/compiler/compile/Component.ts
+++ b/src/compiler/compile/Component.ts
@@ -187,6 +187,9 @@ export default class Component {
if (variable) {
variable.referenced = true;
} else if (is_reserved_keyword(name)) {
+ if (name === '$$host' && !this.compile_options.customElement) {
+ throw new Error(`$$host is for custom element. Did you forget the 'customElement: true' compile option?`);
+ }
this.add_var({
name,
injected: true,
@@ -655,6 +658,12 @@ export default class Component {
name,
injected: true,
});
+ if (name === '$$host' && !this.compile_options.customElement) {
+ this.error(node as any, {
+ code: 'illegal-host',
+ message: `$$host is for custom element. Did you forget the 'customElement: true' compile option?`
+ });
+ }
} else if (name[0] === '$') {
if (name === '$' || name[1] === '$') {
this.error(node as any, {
diff --git a/src/compiler/compile/render_dom/index.ts b/src/compiler/compile/render_dom/index.ts
index 4009c6bddf2b..aa1617429f4f 100644
--- a/src/compiler/compile/render_dom/index.ts
+++ b/src/compiler/compile/render_dom/index.ts
@@ -412,6 +412,7 @@ export default function dom(
body.push(b`
function ${definition}(${args}) {
+ ${component.var_lookup.has('$$host') ? 'const $$host = $$self' : null}
${rest}
${reactive_store_declarations}
diff --git a/src/compiler/compile/utils/reserved_keywords.ts b/src/compiler/compile/utils/reserved_keywords.ts
index 75825c17193b..6a81f5ddb12d 100644
--- a/src/compiler/compile/utils/reserved_keywords.ts
+++ b/src/compiler/compile/utils/reserved_keywords.ts
@@ -1,4 +1,4 @@
-export const reserved_keywords = new Set(["$$props", "$$restProps"]);
+export const reserved_keywords = new Set(["$$props", "$$restProps", "$$host"]);
export function is_reserved_keyword(name) {
return reserved_keywords.has(name);
diff --git a/test/custom-elements/index.js b/test/custom-elements/index.js
index d68d3b94c58e..d138f562bf81 100644
--- a/test/custom-elements/index.js
+++ b/test/custom-elements/index.js
@@ -43,14 +43,24 @@ describe('custom-elements', function() {
}
before(async () => {
- svelte = loadSvelte();
- server = await create_server();
- browser = await puppeteer.launch();
+ try {
+ svelte = loadSvelte();
+ server = await create_server();
+ browser = await puppeteer.launch();
+ console.log('Success!');
+ } catch (error) {
+ console.log('Error', error);
+ }
});
after(async () => {
- server.close();
- await browser.close();
+ try {
+ server.close();
+ await browser.close();
+ console.log('Success!');
+ } catch (error) {
+ console.log('Error', error);
+ }
});
fs.readdirSync(`${__dirname}/samples`).forEach(dir => {
@@ -105,7 +115,11 @@ describe('custom-elements', function() {
const page = await browser.newPage();
- page.on('console', (type, ...args) => {
+ page.on('console', async (consoleMessage) => {
+ const type = consoleMessage.type();
+ const args = await Promise.all(
+ consoleMessage.args().map(arg => arg.jsonValue())
+ )
console[type](...args);
});
diff --git a/test/custom-elements/samples/$$host/main.svelte b/test/custom-elements/samples/$$host/main.svelte
new file mode 100644
index 000000000000..26350cc4cf3f
--- /dev/null
+++ b/test/custom-elements/samples/$$host/main.svelte
@@ -0,0 +1,11 @@
+
+
+
+
+{typeof $$host}
\ No newline at end of file
diff --git a/test/custom-elements/samples/$$host/test.js b/test/custom-elements/samples/$$host/test.js
new file mode 100644
index 000000000000..55a9779f3d85
--- /dev/null
+++ b/test/custom-elements/samples/$$host/test.js
@@ -0,0 +1,12 @@
+import * as assert from 'assert';
+import './main.svelte';
+
+export default async function (target) {
+ target.innerHTML = '';
+ const el = target.querySelector('custom-element');
+
+ assert.equal(el.getHost(), el);
+ assert.equal(el.host, el);
+
+ assert.equal(el.shadowRoot.textContent, 'object');
+}
\ No newline at end of file
diff --git a/test/runtime/samples/$$host-2/_config.js b/test/runtime/samples/$$host-2/_config.js
new file mode 100644
index 000000000000..58017f485628
--- /dev/null
+++ b/test/runtime/samples/$$host-2/_config.js
@@ -0,0 +1,4 @@
+export default {
+ compileOptions: {},
+ error: "$$host is for custom element. Did you forget the 'customElement: true' compile option?"
+};
diff --git a/test/runtime/samples/$$host-2/main.svelte b/test/runtime/samples/$$host-2/main.svelte
new file mode 100644
index 000000000000..0fb72117ac11
--- /dev/null
+++ b/test/runtime/samples/$$host-2/main.svelte
@@ -0,0 +1 @@
+{$$host}
\ No newline at end of file
diff --git a/test/runtime/samples/$$host/_config.js b/test/runtime/samples/$$host/_config.js
new file mode 100644
index 000000000000..58017f485628
--- /dev/null
+++ b/test/runtime/samples/$$host/_config.js
@@ -0,0 +1,4 @@
+export default {
+ compileOptions: {},
+ error: "$$host is for custom element. Did you forget the 'customElement: true' compile option?"
+};
diff --git a/test/runtime/samples/$$host/main.svelte b/test/runtime/samples/$$host/main.svelte
new file mode 100644
index 000000000000..a52856c952e7
--- /dev/null
+++ b/test/runtime/samples/$$host/main.svelte
@@ -0,0 +1,3 @@
+