Merge branch 'master' into gh-3019

pull/3424/head
Richard Harris 5 years ago
commit a53849d54f

10
package-lock.json generated

@ -535,11 +535,6 @@
"safe-buffer": "~5.1.1"
}
},
"cookie": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz",
"integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg=="
},
"core-util-is": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
@ -1306,11 +1301,6 @@
"integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==",
"dev": true
},
"flru": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/flru/-/flru-1.0.2.tgz",
"integrity": "sha512-kWyh8ADvHBFz6ua5xYOPnUroZTT/bwWfrCeL0Wj1dzG4/YOmOcfJ99W8dOVyyynJN35rZ9aCOtHChqQovV7yog=="
},
"foreground-child": {
"version": "1.5.6",
"resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-1.5.6.tgz",

@ -98,9 +98,5 @@
],
"sourceMap": true,
"instrument": true
},
"dependencies": {
"cookie": "^0.4.0",
"flru": "^1.0.2"
}
}

@ -5,8 +5,4 @@ BASEURL=
DATABASE_URL=
GITHUB_CLIENT_ID=
GITHUB_CLIENT_SECRET=
MAPBOX_ACCESS_TOKEN=
JWT_EXP=30d
JWT_ALG=HS512
JWT_KEY=
MAPBOX_ACCESS_TOKEN=

@ -907,7 +907,68 @@ app.count += 1;
### Custom element API
* TODO
---
Svelte components can also be compiled to custom elements (aka web components) using the `customElements: true` compiler option. You should specify a tag name for the component using the `<svelte:options>` [element](docs#svelte_options).
```html
<svelte:options tag="my-element">
<script>
export let name = 'world';
</script>
<h1>Hello {name}!</h1>
<slot></slot>
```
---
Alternatively, use `tag={null}` to indicate that the consumer of the custom element should name it.
```js
import MyElement from './MyElement.svelte';
customElements.define('my-element', MyElement);
```
---
Once a custom element has been defined, it can be used as a regular DOM element:
```js
document.body.innerHTML = `
<my-element>
<p>This is some slotted content</p>
</my-element>
`;
```
---
By default, custom elements are compiled with `accessors: true`, which means that any [props](docs#Attributes_and_props) are exposed as properties of the DOM element (as well as being readable/writable as attributes, where possible).
To prevent this, add `accessors={false}` to `<svelte:options>`.
```js
const el = document.querySelector('my-element');
// get the current value of the 'name' prop
console.log(el.name);
// set a new value, updating the shadow DOM
el.name = 'everybody';
```
Custom elements can be a useful way to package components for consumption in a non-Svelte app, as they will work with vanilla HTML and JavaScript as well as [most frameworks](https://custom-elements-everywhere.com/). There are, however, some important differences to be aware of:
* Styles are *encapsulated*, rather than merely *scoped*. This means that any non-component styles (such as you might have in a `global.css` file) will not apply to the custom element, including styles with the `:global(...)` modifier
* Instead of being extracted out as a separate .css file, styles are inlined into the component as a JavaScript string
* Custom elements are not generally suitable for server-side rendering, as the shadow DOM is invisible until JavaScript loads
* In Svelte, slotted content renders *lazily*. In the DOM, it renders *eagerly*. In other words, it will always be created even if the component's `<slot>` element is inside an `{#if ...}` block. Similarly, including a `<slot>` in an `{#each ...}` block will not cause the slotted content to be rendered multiple times
* The `let:` directive has no effect
* Polyfills are required to support older browsers
### Server-side component API

@ -1647,6 +1647,11 @@
"safe-buffer": "~5.1.1"
}
},
"cookie": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz",
"integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg=="
},
"core-js": {
"version": "2.6.5",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.5.tgz",
@ -1906,6 +1911,11 @@
"is-buffer": "~2.0.3"
}
},
"flru": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/flru/-/flru-1.0.2.tgz",
"integrity": "sha512-kWyh8ADvHBFz6ua5xYOPnUroZTT/bwWfrCeL0Wj1dzG4/YOmOcfJ99W8dOVyyynJN35rZ9aCOtHChqQovV7yog=="
},
"for-each": {
"version": "0.3.3",
"resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz",
@ -3840,11 +3850,6 @@
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
"dev": true
},
"uuid": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz",
"integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA=="
},
"validate-npm-package-license": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",

@ -15,8 +15,10 @@
"dependencies": {
"@polka/redirect": "^1.0.0-next.0",
"@polka/send": "^1.0.0-next.3",
"cookie": "^0.4.0",
"devalue": "^2.0.0",
"do-not-zip": "^1.0.0",
"flru": "^1.0.2",
"httpie": "^1.1.2",
"jsonwebtoken": "^8.5.1",
"marked": "^0.7.0",
@ -24,7 +26,6 @@
"polka": "^1.0.0-next.4",
"prismjs": "^1.17.1",
"sirv": "^0.4.2",
"uuid": "^3.3.2",
"yootils": "0.0.16"
},
"devDependencies": {

@ -53,6 +53,7 @@
<a target="_blank" rel="noopener" href="https://deck.nl"><img src="organisations/deck.svg" alt="Deck logo" loading="lazy"></a>
<a target="_blank" rel="noopener" href="https://from-now-on.com"><img src="organisations/from-now-on.png" alt="From-Now-On logo" loading="lazy"></a>
<a target="_blank" rel="noopener" href="https://godaddy.com"><img src="organisations/godaddy.svg" alt="GoDaddy logo" loading="lazy"></a>
<a target="_blank" rel="noopener" href="http://healthtree.org/"><img src="organisations/healthtree.png" alt="HealthTree logo" loading="lazy"></a>
<a target="_blank" rel="noopener" href="https://itslearning.com"><img src="organisations/itslearning.svg" alt="itslearning logo" loading="lazy"></a>
<a target="_blank" rel="noopener" href="http://mustlab.ru"><img src="organisations/mustlab.png" alt="Mustlab logo" loading="lazy"></a>
<a target="_blank" rel="noopener" href="https://www.nesta.org.uk"><img src="organisations/nesta.svg" alt="Nesta logo" loading="lazy"></a>
@ -69,6 +70,6 @@
<a target="_blank" rel="noopener" href="https://thunderdome.dev"><img src="organisations/thunderdome.svg" alt="Thunderdome logo" loading="lazy"></a>
<a target="_blank" rel="noopener" href="https://m.tokopedia.com"><img src="organisations/tokopedia.png" alt="Tokopedia logo" srcset="organisations/tokopedia.2x.png 2x, organisations/tokopedia.3x.png 3x" loading="lazy"></a>
<a target="_blank" rel="noopener" href="https://webdesq.net"><img src="organisations/webdesq.svg" alt="Webdesq logo" loading="lazy"></a>
<a target="_blank" rel="noopener" href="http://healthtree.org/"><img src="organisations/healthtree.png" alt="HealthTree logo" loading="lazy"></a>
<a target="_blank" rel="noopener" href="https://zevvle.com/"><img src="organisations/zevvle.svg" alt="Zevvle logo" loading="lazy"></a>
<a target="_blank" rel="noopener" href="https://github.com/sveltejs/svelte/blob/master/site/src/routes/_components/WhosUsingSvelte.svelte" class="add-yourself"><span>+ your company?</span></a>
</div>

@ -23,7 +23,7 @@ async function import_gist(req, res) {
if (!user) {
const { id, name, login, avatar_url } = data.owner;
[user] = await query(`
user = await find(`
insert into users(uid, name, username, avatar)
values ($1, $2, $3, $4)
returning *
@ -45,7 +45,8 @@ async function import_gist(req, res) {
// add gist to database...
await query(`
insert into gists(uid, user_id, name, files)
values ($1, $2, $3, $4) returning *`, [req.params.id, user.id, data.description, JSON.stringify(files)]);
values ($1, $2, $3, $4)
`, [req.params.id, user.id, data.description, JSON.stringify(files)]);
send(res, 200, {
uid: req.params.id,

@ -0,0 +1 @@
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 2219.27 506.75"><path d="M431.45,2755.61L543.53,2584c9.12-13.74,13.75-30,13.75-47.54a95.29,95.29,0,0,0-24.77-64.64c-16.92-18.56-39.14-30.17-64.25-30.17h-232L120,2627.61H290.57l-109.84,168.6a83.29,83.29,0,0,0-13.82,46.68c0,23.67,8.53,45.24,25.35,63.64,23.17,25.35,51.13,32.36,67.2,32.36l250.4,0.5,108.49-183.77H431.45Zm53.15,129-3.41,5.41-217-1.38-2.25.08a44.72,44.72,0,0,1-44.67-44.67,48.4,48.4,0,0,1,6.43-23.43l0.57-.9,150.94-228.06,5.46-8.77,1.83-3.3H208.41l54.79-84H468.26c11.5,0,20.45,3,28.17,11.49,8.1,8.88,12,18.2,12,29.46,0,7.92-1.8,14.24-5.5,19.81L346.8,2792.24l-5.46,7.92-1.83,2.45h194l-10.24,17.61C506.76,2848.2,492.66,2871.85,484.6,2884.64Z" transform="translate(-119.96 -2432.63)" fill="#da291c"/><path d="M784.72,2832.35a20.51,20.51,0,0,1-4.81-13.36,16.91,16.91,0,0,1,2.14-8.55l146.42-235.13H792.73a7.31,7.31,0,0,1-7.48-7.48v-24.58a7.31,7.31,0,0,1,7.48-7.48H965.87a16,16,0,0,1,12.56,5.88,19.26,19.26,0,0,1,5.08,12.83,16.87,16.87,0,0,1-2.67,9.08L834.41,2798.68H978.7a7.31,7.31,0,0,1,7.48,7.48v24.58a7.31,7.31,0,0,1-7.48,7.48H797A15.16,15.16,0,0,1,784.72,2832.35Z" transform="translate(-119.96 -2432.63)" fill="#da291c"/><path d="M1097.33,2822.73a113.59,113.59,0,0,1-42.22-42.48,115.42,115.42,0,0,1-15.5-58.51v-76.42a115.46,115.46,0,0,1,15.5-58.51,115.81,115.81,0,0,1,200.93,0,115.54,115.54,0,0,1,15.5,58.51v36.34a19.16,19.16,0,0,1-19.24,19.24h-171v23.51a73.34,73.34,0,0,0,9.89,37.41,72.54,72.54,0,0,0,27,27,73.34,73.34,0,0,0,37.41,9.89h77.49a7.31,7.31,0,0,1,7.48,7.48v24.58a7.31,7.31,0,0,1-7.48,7.48h-77.49A114,114,0,0,1,1097.33,2822.73Zm132.53-160.31v-19.77a74.58,74.58,0,0,0-111.69-64.39,73.77,73.77,0,0,0-36.87,64.39v19.77h148.56Z" transform="translate(-119.96 -2432.63)" fill="#da291c"/><path d="M1426.23,2836.35a9.37,9.37,0,0,1-4-5.08l-100.46-283.76a9.09,9.09,0,0,1-.53-3.74,7.69,7.69,0,0,1,2.4-5.61,8.32,8.32,0,0,1,6.15-2.41h24.58a11.31,11.31,0,0,1,6.15,1.87,9.47,9.47,0,0,1,4,5.08l84.43,243.68,82.83-243.68a9.39,9.39,0,0,1,4-5.08,11.29,11.29,0,0,1,6.15-1.87h23.51a8.2,8.2,0,0,1,7.21,3.47q2.41,3.48.8,8.28L1473,2831.28a9.44,9.44,0,0,1-4,5.08,11.24,11.24,0,0,1-6.15,1.87h-30.46A11.22,11.22,0,0,1,1426.23,2836.35Z" transform="translate(-119.96 -2432.63)" fill="#da291c"/><path d="M1724.42,2836.35a9.37,9.37,0,0,1-4-5.08l-100.46-283.76a9.09,9.09,0,0,1-.53-3.74,7.69,7.69,0,0,1,2.4-5.61,8.32,8.32,0,0,1,6.15-2.41h24.58a11.31,11.31,0,0,1,6.15,1.87,9.47,9.47,0,0,1,4,5.08l84.43,243.68L1830,2542.71a9.39,9.39,0,0,1,4-5.08,11.29,11.29,0,0,1,6.15-1.87h23.51a8.2,8.2,0,0,1,7.21,3.47q2.41,3.48.8,8.28l-100.46,283.76a9.44,9.44,0,0,1-4,5.08,11.24,11.24,0,0,1-6.15,1.87h-30.46A11.22,11.22,0,0,1,1724.42,2836.35Z" transform="translate(-119.96 -2432.63)" fill="#da291c"/><path d="M1956.35,2832.61a18.55,18.55,0,0,1-5.61-13.63V2472.17H1901a7.31,7.31,0,0,1-7.48-7.48v-24.58a7.31,7.31,0,0,1,7.48-7.48h72.14a19.16,19.16,0,0,1,19.24,19.24v346.81h56.64a7.31,7.31,0,0,1,7.48,7.48v24.58a7.31,7.31,0,0,1-7.48,7.48H1970A18.55,18.55,0,0,1,1956.35,2832.61Z" transform="translate(-119.96 -2432.63)" fill="#da291c"/><path d="M2165,2822.73a113.59,113.59,0,0,1-42.22-42.48,115.42,115.42,0,0,1-15.5-58.51v-76.42a115.46,115.46,0,0,1,15.5-58.51,115.81,115.81,0,0,1,200.93,0,115.55,115.55,0,0,1,15.5,58.51v36.34a19.16,19.16,0,0,1-19.24,19.24H2149v23.51a73.34,73.34,0,0,0,9.89,37.41,72.54,72.54,0,0,0,27,27,73.34,73.34,0,0,0,37.41,9.89h77.49a7.31,7.31,0,0,1,7.48,7.48v24.58a7.31,7.31,0,0,1-7.48,7.48h-77.49A114,114,0,0,1,2165,2822.73Zm132.53-160.31v-19.77a74.58,74.58,0,0,0-111.69-64.39,73.77,73.77,0,0,0-36.87,64.39v19.77h148.56Z" transform="translate(-119.96 -2432.63)" fill="#da291c"/></svg>

After

Width:  |  Height:  |  Size: 3.6 KiB

@ -415,6 +415,13 @@ export default class Element extends Node {
}
}
if (name === 'is') {
component.warn(attribute, {
code: 'avoid-is',
message: `The 'is' attribute is not supported cross-browser and should be avoided`
});
}
attribute_map.set(attribute.name, attribute);
});

@ -383,6 +383,11 @@ export default class ElementWrapper extends Wrapper {
return `@_document.createElementNS("${namespace}", "${name}")`;
}
const is = this.attributes.find(attr => attr.node.name === 'is');
if (is) {
return `@element_is("${name}", ${is.render_chunks().join(' + ')});`
}
return `@element("${name}")`;
}

@ -20,6 +20,10 @@ export function element<K extends keyof HTMLElementTagNameMap>(name: K) {
return document.createElement<K>(name);
}
export function element_is<K extends keyof HTMLElementTagNameMap>(name: K, is: string) {
return document.createElement<K>(name, { is });
}
export function object_without_properties<T, K extends keyof T>(obj: T, exclude: K[]) {
// eslint-disable-next-line @typescript-eslint/no-object-literal-type-assertion
const target = {} as Pick<T, Exclude<keyof T, K>>;

@ -0,0 +1,17 @@
export default {
warnings: [{
code: "avoid-is",
message: "The 'is' attribute is not supported cross-browser and should be avoided",
pos: 97,
start: {
character: 97,
column: 8,
line: 7
},
end: {
character: 114,
column: 25,
line: 7
}
}]
};

@ -0,0 +1,2 @@
class FancyButton extends HTMLButtonElement {}
customElements.define('fancy-button', FancyButton, { extends: 'button' });

@ -0,0 +1,7 @@
<svelte:options tag="custom-element"/>
<script>
import './fancy-button.js';
</script>
<button is="fancy-button">click me</button>

@ -0,0 +1,15 @@
import * as assert from 'assert';
import CustomElement from './main.svelte';
export default function (target) {
new CustomElement({
target
});
assert.equal(target.innerHTML, '<custom-element></custom-element>');
const el = target.querySelector('custom-element');
const button = el.shadowRoot.querySelector('button');
assert.ok(button instanceof customElements.get('fancy-button'));
}
Loading…
Cancel
Save