Merge branch 'master' into onmount_triggers_in_reverse_order_for_siblings

* master: (35 commits)
  Fix overwrite of 'offset' value in reactive statement
  fix slide example
  typos
  update svelte-repl (fixes download button)
  update svelte-repl
  update svelte-repl version
  use better eliza package
  gitignore workers
  add compiler typings to list of published files
  improve typings for animate, easing, transition, motion and internal apis
  update bundler worker
  fix gitignore
  fix types for easing functions
  fix build order
  generate internal-exports file
  update gitignore
  update folder structure - 
  bump estree-walker to fix some svelte.walk bugs
  bundle locally
  -> v3.4.4
  ...
pull/2752/head
Colin Casey 6 years ago
commit a9193fd9d6

@ -38,7 +38,6 @@
"sourceType": "module" "sourceType": "module"
}, },
"settings": { "settings": {
"import/core-modules": ["svelte"], "import/core-modules": ["svelte"]
"svelte3/extensions": ["html"]
} }
} }

@ -1,5 +1,5 @@
[ignore] [ignore]
<PROJECT_ROOT>/dist/.* <PROJECT_ROOT>/types/.*
[include] [include]

17
.gitignore vendored

@ -3,15 +3,15 @@
.nyc_output .nyc_output
node_modules node_modules
*.map *.map
/src/compile/internal-exports.ts /src/compiler/compile/internal-exports.ts
/compiler.*js /compiler.*js
/index.*js /index.*js
/internal.*js /internal
/store.*js /store
/easing.*js /easing
/motion.*js /motion
/transition.*js /transition
/animate.*js /animate
/scratch/ /scratch/
/coverage/ /coverage/
/coverage.lcov/ /coverage.lcov/
@ -21,7 +21,7 @@ node_modules
/test/sourcemaps/samples/*/output.css.map /test/sourcemaps/samples/*/output.css.map
/yarn-error.log /yarn-error.log
_actual*.* _actual*.*
/dist /types
/site/cypress/screenshots/ /site/cypress/screenshots/
/site/__sapper__/ /site/__sapper__/
@ -29,5 +29,6 @@ _actual*.*
/site/.sessions /site/.sessions
/site/static/svelte-app.json /site/static/svelte-app.json
/site/static/contributors.jpg /site/static/contributors.jpg
/site/static/workers
/site/scripts/svelte-app /site/scripts/svelte-app
/site/src/routes/_contributors.js /site/src/routes/_contributors.js

@ -1,5 +1,15 @@
# Svelte changelog # Svelte changelog
## 3.4.4
* Publish type declaration files ([#2874](https://github.com/sveltejs/svelte/issues/2874))
* Don't trigger updates for unreferenced values ([#2865](https://github.com/sveltejs/svelte/pull/2865))
* Omit readonly bindings from SSR output ([#2339](https://github.com/sveltejs/svelte/issues/2339))
* Prevent outdated animation CSS ([#2871](https://github.com/sveltejs/svelte/issues/2871))
* Repair dynamic `{@html ...}` in head ([#2880](https://github.com/sveltejs/svelte/pull/2880))
* Don't create unknown prop warnings for internal props, or if component has `$$props` ([#2881](https://github.com/sveltejs/svelte/pull/2881))
## 3.4.3 ## 3.4.3
* Add type declaration files for everything ([#2842](https://github.com/sveltejs/svelte/pull/2842)) * Add type declaration files for everything ([#2842](https://github.com/sveltejs/svelte/pull/2842))

1
animate.d.ts vendored

@ -1 +0,0 @@
export * from './dist/animate';

2
compiler.d.ts vendored

@ -1 +1 @@
export * from './dist/compiler'; export * from './types/compiler';

1
easing.d.ts vendored

@ -1 +0,0 @@
export * from './dist/easing';

1
index.d.ts vendored

@ -1 +0,0 @@
export * from './dist/index';

1
internal.d.ts vendored

@ -1 +0,0 @@
export * from './dist/internal';

1
motion.d.ts vendored

@ -1 +0,0 @@
export * from './dist/motion';

819
package-lock.json generated

File diff suppressed because it is too large Load Diff

@ -1,22 +1,24 @@
{ {
"name": "svelte", "name": "svelte",
"version": "3.4.3", "version": "3.4.4",
"description": "Cybernetically enhanced web apps", "description": "Cybernetically enhanced web apps",
"module": "index.mjs", "module": "index.mjs",
"main": "index", "main": "index",
"files": [ "files": [
"compiler.js", "types",
"compiler.*",
"register.js", "register.js",
"index.*", "index.*",
"internal.*", "internal",
"store.*", "store",
"animate.*", "animate",
"transition.*", "transition",
"easing.*", "easing",
"motion.*", "motion",
"svelte", "svelte",
"README.md" "README.md"
], ],
"types": "types/runtime",
"scripts": { "scripts": {
"test": "mocha --opts mocha.opts", "test": "mocha --opts mocha.opts",
"test:unit": "mocha --require sucrase/register --recursive ./**/__test__.ts", "test:unit": "mocha --require sucrase/register --recursive ./**/__test__.ts",
@ -25,13 +27,13 @@
"coverage": "c8 report --reporter=text-lcov > coverage.lcov && c8 report --reporter=html", "coverage": "c8 report --reporter=text-lcov > coverage.lcov && c8 report --reporter=html",
"codecov": "codecov", "codecov": "codecov",
"precodecov": "npm run coverage", "precodecov": "npm run coverage",
"lint": "eslint src test/*.js",
"build": "rollup -c", "build": "rollup -c",
"prepare": "npm run build && npm run tsd", "prepare": "npm run build && npm run tsd",
"dev": "rollup -cw", "dev": "rollup -cw",
"pretest": "npm run build", "pretest": "npm run build",
"posttest": "agadoo internal.mjs", "posttest": "agadoo internal/index.mjs",
"prepublishOnly": "export PUBLISH=true && npm run lint && npm test", "prepublishOnly": "export PUBLISH=true && npm test && npm run create-stubs",
"create-stubs": "node scripts/create-stubs.js",
"tsd": "tsc -p . --emitDeclarationOnly", "tsd": "tsc -p . --emitDeclarationOnly",
"typecheck": "tsc -p . --noEmit" "typecheck": "tsc -p . --noEmit"
}, },
@ -61,10 +63,7 @@
"c8": "^3.4.0", "c8": "^3.4.0",
"codecov": "^3.0.0", "codecov": "^3.0.0",
"css-tree": "1.0.0-alpha22", "css-tree": "1.0.0-alpha22",
"eslint": "^5.3.0", "estree-walker": "^0.6.1",
"eslint-plugin-html": "^5.0.0",
"eslint-plugin-import": "^2.11.0",
"estree-walker": "^0.6.0",
"is-reference": "^1.1.1", "is-reference": "^1.1.1",
"jsdom": "^12.2.0", "jsdom": "^12.2.0",
"kleur": "^3.0.0", "kleur": "^3.0.0",

@ -9,7 +9,7 @@ import pkg from './package.json';
const is_publish = !!process.env.PUBLISH; const is_publish = !!process.env.PUBLISH;
const tsPlugin = is_publish const ts_plugin = is_publish
? typescript({ ? typescript({
include: 'src/**', include: 'src/**',
typescript: require('typescript') typescript: require('typescript')
@ -18,39 +18,61 @@ const tsPlugin = is_publish
transforms: ['typescript'] transforms: ['typescript']
}); });
const external = id => id.startsWith('svelte/');
export default [ export default [
/* internal.[m]js */ /* runtime */
{ {
input: `src/internal/index.ts`, input: `src/runtime/index.ts`,
output: [ output: [
{ {
file: `internal.mjs`, file: `index.mjs`,
format: 'esm', format: 'esm',
paths: id => id.startsWith('svelte/') && id.replace('svelte', '.') paths: id => id.startsWith('svelte/') && `${id.replace('svelte', '.')}`
}, },
{ {
file: `internal.js`, file: `index.js`,
format: 'cjs', format: 'cjs',
paths: id => id.startsWith('svelte/') && id.replace('svelte', '.') paths: id => id.startsWith('svelte/') && `${id.replace('svelte', '.')}`
} }
], ],
external: id => id.startsWith('svelte/'), external,
plugins: [ts_plugin]
},
plugins: [ ...fs.readdirSync('src/runtime')
tsPlugin, .filter(dir => fs.statSync(`src/runtime/${dir}`).isDirectory())
.map(dir => ({
input: `src/runtime/${dir}/index.ts`,
output: [
{
file: `${dir}/index.mjs`,
format: 'esm',
paths: id => id.startsWith('svelte/') && `${id.replace('svelte', '..')}`
},
{ {
file: `${dir}/index.js`,
format: 'cjs',
paths: id => id.startsWith('svelte/') && `${id.replace('svelte', '..')}`
}
],
external,
plugins: [
ts_plugin,
dir === 'internal' && {
generateBundle(options, bundle) { generateBundle(options, bundle) {
const mod = bundle['internal.mjs']; const mod = bundle['index.mjs'];
if (mod) { if (mod) {
fs.writeFileSync('src/compile/internal-exports.ts', `// This file is automatically generated\nexport default new Set(${JSON.stringify(mod.exports)});`); fs.writeFileSync('src/compiler/compile/internal-exports.ts', `// This file is automatically generated\nexport default new Set(${JSON.stringify(mod.exports)});`);
} }
} }
}] }
}, ]
})),
/* compiler.js */ /* compiler.js */
{ {
input: 'src/compiler.ts', input: 'src/compiler/index.ts',
plugins: [ plugins: [
replace({ replace({
__VERSION__: pkg.version __VERSION__: pkg.version
@ -60,7 +82,7 @@ export default [
include: ['node_modules/**'] include: ['node_modules/**']
}), }),
json(), json(),
tsPlugin ts_plugin
], ],
output: { output: {
file: 'compiler.js', file: 'compiler.js',
@ -71,47 +93,5 @@ export default [
external: is_publish external: is_publish
? [] ? []
: id => id === 'acorn' || id === 'magic-string' || id.startsWith('css-tree') : id => id === 'acorn' || id === 'magic-string' || id.startsWith('css-tree')
},
/* motion.mjs */
{
input: `src/motion/index.ts`,
output: [
{
file: `motion.mjs`,
format: 'esm',
paths: id => id.startsWith('svelte/') && id.replace('svelte', '.')
},
{
file: `motion.js`,
format: 'cjs',
paths: id => id.startsWith('svelte/') && id.replace('svelte', '.')
}
],
plugins: [
tsPlugin
],
external: id => id.startsWith('svelte/')
},
// everything else
...['index', 'easing', 'transition', 'animate', 'store'].map(name => ({
input: `src/${name}.ts`,
output: [
{
file: `${name}.mjs`,
format: 'esm',
paths: id => id.startsWith('svelte/') && id.replace('svelte', '.')
},
{
file: `${name}.js`,
format: 'cjs',
paths: id => id.startsWith('svelte/') && id.replace('svelte', '.')
} }
],
plugins: [
tsPlugin
],
external: id => id.startsWith('svelte/')
}))
]; ];

@ -0,0 +1,12 @@
const fs = require('fs');
fs.readdirSync('src/runtime')
.filter(dir => fs.statSync(`src/runtime/${dir}`).isDirectory())
.forEach(dir => {
fs.writeFileSync(`${dir}/package.json`, JSON.stringify({
main: './index.js',
module: './index.mjs'
}, null, ' '));
fs.writeFileSync(`${dir}/index.d.ts`, `export * from '../types/runtime/${dir}/index.d.ts';`);
});

@ -618,13 +618,13 @@ Slides an element in and out.
```html ```html
<script> <script>
import { fly } from 'svelte/transition'; import { slide } from 'svelte/transition';
import { quintOut } from 'svelte/easing'; import { quintOut } from 'svelte/easing';
</script> </script>
{#if condition} {#if condition}
<div transition:fly="{{delay: 250, duration: 300, easing: quintOut }}"> <div transition:slide="{{delay: 250, duration: 300, easing: quintOut }}">
flies in and out slides in and out
</div> </div>
{/if} {/if}
``` ```

@ -1,5 +1,5 @@
<script> <script>
import Eliza from 'elizanode'; import Eliza from 'elizabot';
import { beforeUpdate, afterUpdate } from 'svelte'; import { beforeUpdate, afterUpdate } from 'svelte';
let div; let div;

@ -1,5 +1,5 @@
<script> <script>
import Eliza from 'elizanode'; import Eliza from 'elizabot';
import { beforeUpdate, afterUpdate } from 'svelte'; import { beforeUpdate, afterUpdate } from 'svelte';
let div; let div;

@ -1,5 +1,5 @@
<script> <script>
import Eliza from 'elizanode'; import Eliza from 'elizabot';
import { beforeUpdate, afterUpdate } from 'svelte'; import { beforeUpdate, afterUpdate } from 'svelte';
let div; let div;

@ -1362,13 +1362,15 @@
} }
}, },
"@sveltejs/svelte-repl": { "@sveltejs/svelte-repl": {
"version": "0.0.11", "version": "0.1.2",
"resolved": "https://registry.npmjs.org/@sveltejs/svelte-repl/-/svelte-repl-0.0.11.tgz", "resolved": "https://registry.npmjs.org/@sveltejs/svelte-repl/-/svelte-repl-0.1.2.tgz",
"integrity": "sha512-F284f8qaUs1rp8akqWXcB6oovlaso7qmsUz1rqm80FwUKLffjYIWy2a1p6+Yo1kRy6Q+fW8kj21JLEqv7pjOwA==", "integrity": "sha512-OHIj01ly4+/WwNb0zGqLSQL7POSs2BPx47CzryVsbu0omVDe7olYTJnCYV4ePUENnlL5JzZihzvlvxmVGP6knw==",
"dev": true, "dev": true,
"requires": { "requires": {
"codemirror": "^5.45.0", "codemirror": "^5.45.0",
"sourcemap-codec": "^1.4.4" "estree-walker": "^0.6.0",
"sourcemap-codec": "^1.4.4",
"yootils": "0.0.15"
} }
}, },
"@types/estree": { "@types/estree": {
@ -1799,9 +1801,9 @@
"dev": true "dev": true
}, },
"codemirror": { "codemirror": {
"version": "5.46.0", "version": "5.47.0",
"resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.46.0.tgz", "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.47.0.tgz",
"integrity": "sha512-3QpMge0vg4QEhHW3hBAtCipJEWjTJrqLLXdIaWptJOblf1vHFeXLNtFhPai/uX2lnFCehWNk4yOdaMR853Z02w==", "integrity": "sha512-kV49Fr+NGFHFc/Imsx6g180hSlkGhuHxTSDDmDHOuyln0MQYFLixDY4+bFkBVeCEiepYfDimAF/e++9jPJk4QA==",
"dev": true "dev": true
}, },
"collection-visit": { "collection-visit": {

@ -3,9 +3,10 @@
"version": "1.0.0", "version": "1.0.0",
"description": "Docs and examples for Svelte", "description": "Docs and examples for Svelte",
"scripts": { "scripts": {
"dev": "sapper dev", "dev": "npm run copy-workers && sapper dev",
"copy-workers": "rm -rf static/workers && cp -r node_modules/@sveltejs/svelte-repl/workers static",
"migrate": "node-pg-migrate -r dotenv/config", "migrate": "node-pg-migrate -r dotenv/config",
"sapper": "sapper build --legacy", "sapper": "npm run copy-workers && sapper build --legacy",
"update_shimport": "cp node_modules/shimport/index.js __sapper__/build/client/shimport@0.0.14.js", "update_shimport": "cp node_modules/shimport/index.js __sapper__/build/client/shimport@0.0.14.js",
"update": "node scripts/update_template.js && node scripts/get-contributors.js", "update": "node scripts/update_template.js && node scripts/get-contributors.js",
"start": "node __sapper__/build", "start": "node __sapper__/build",
@ -38,7 +39,7 @@
"@babel/runtime": "^7.4.4", "@babel/runtime": "^7.4.4",
"@sindresorhus/slugify": "^0.9.1", "@sindresorhus/slugify": "^0.9.1",
"@sveltejs/site-kit": "^1.0.4", "@sveltejs/site-kit": "^1.0.4",
"@sveltejs/svelte-repl": "0.0.11", "@sveltejs/svelte-repl": "^0.1.2",
"degit": "^2.1.3", "degit": "^2.1.3",
"dotenv": "^8.0.0", "dotenv": "^8.0.0",
"eslint-plugin-svelte3": "^1.0.0", "eslint-plugin-svelte3": "^1.0.0",

@ -116,6 +116,7 @@
{#if process.browser} {#if process.browser}
<Repl <Repl
bind:this={repl} bind:this={repl}
workersUrl="workers"
fixed={mobile} fixed={mobile}
{svelteUrl} {svelteUrl}
{rollupUrl} {rollupUrl}

@ -39,6 +39,10 @@
let isLoading = false; let isLoading = false;
const cache = {}; const cache = {};
function showExampleCodeOnChange() {
offset = 1;
}
$: title = title_by_slug[active_slug] || ''; $: title = title_by_slug[active_slug] || '';
$: first_slug = sections[0].examples[0].slug; $: first_slug = sections[0].examples[0].slug;
$: mobile = width < 768; // note: same as per media query below $: mobile = width < 768; // note: same as per media query below
@ -46,7 +50,7 @@
$: if (repl && active_slug) { $: if (repl && active_slug) {
if (active_slug in cache) { if (active_slug in cache) {
repl.set({ components: cache[active_slug] }); repl.set({ components: cache[active_slug] });
offset = 1; showExampleCodeOnChange();
} else { } else {
isLoading = true; isLoading = true;
fetch(`examples/${active_slug}.json`) fetch(`examples/${active_slug}.json`)
@ -59,7 +63,7 @@
.then(components => { .then(components => {
cache[active_slug] = components; cache[active_slug] = components;
repl.set({components}); repl.set({components});
offset = 1; showExampleCodeOnChange();
isLoading = false; isLoading = false;
}) })
.catch(() => { .catch(() => {
@ -102,6 +106,7 @@
<div class="repl-container" class:loading={isLoading}> <div class="repl-container" class:loading={isLoading}>
<Repl <Repl
bind:this={repl} bind:this={repl}
workersUrl="workers"
{svelteUrl} {svelteUrl}
{rollupUrl} {rollupUrl}
orientation={replOrientation} orientation={replOrientation}

@ -206,6 +206,7 @@
<div class="viewport" class:offset={checked}> <div class="viewport" class:offset={checked}>
<Repl <Repl
bind:this={repl} bind:this={repl}
workersUrl="workers"
{svelteUrl} {svelteUrl}
{rollupUrl} {rollupUrl}
{relaxed} {relaxed}

@ -302,6 +302,7 @@
<div class="tutorial-repl"> <div class="tutorial-repl">
<Repl <Repl
bind:this={repl} bind:this={repl}
workersUrl="workers"
{svelteUrl} {svelteUrl}
{rollupUrl} {rollupUrl}
orientation={mobile ? 'columns' : 'rows'} orientation={mobile ? 'columns' : 'rows'}

@ -7,6 +7,7 @@ const { PORT=3000 } = process.env;
API() API()
.use( .use(
sirv('static', { sirv('static', {
dev: process.env.NODE_ENV === 'development',
setHeaders(res) { setHeaders(res) {
res.setHeader('Access-Control-Allow-Origin', '*'); res.setHeader('Access-Control-Allow-Origin', '*');
res.hasHeader('Cache-Control') || res.setHeader('Cache-Control', 'max-age=600'); // 10min default res.hasHeader('Cache-Control') || res.setHeader('Cache-Control', 'max-age=600'); // 10min default

@ -789,6 +789,10 @@ export default class Component {
return `${name.slice(1)}.set(${name})` return `${name.slice(1)}.set(${name})`
} }
if (variable && !variable.referenced && !variable.is_reactive_dependency && !variable.export_name && !name.startsWith('$$')) {
return value || name;
}
if (value) { if (value) {
return `$$invalidate('${name}', ${value})`; return `$$invalidate('${name}', ${value})`;
} }
@ -1120,8 +1124,9 @@ export default class Component {
if (!assignee_nodes.has(identifier)) { if (!assignee_nodes.has(identifier)) {
const { name } = identifier; const { name } = identifier;
const owner = scope.find_owner(name); const owner = scope.find_owner(name);
const component_var = component.var_lookup.get(name); const variable = component.var_lookup.get(name);
const is_writable_or_mutated = component_var && (component_var.writable || component_var.mutated); if (variable) variable.is_reactive_dependency = true;
const is_writable_or_mutated = variable && (variable.writable || variable.mutated);
if ( if (
(!owner || owner === component.instance_scope) && (!owner || owner === component.instance_scope) &&
(name[0] === '$' || is_writable_or_mutated) (name[0] === '$' || is_writable_or_mutated)

@ -1,4 +1,4 @@
import { assign } from '../internal/index'; import { assign } from '../../runtime/internal/index';
import Stats from '../Stats'; import Stats from '../Stats';
import parse from '../parse/index'; import parse from '../parse/index';
import render_dom from './render-dom/index'; import render_dom from './render-dom/index';

@ -3,6 +3,15 @@ import get_object from '../utils/get_object';
import Expression from './shared/Expression'; import Expression from './shared/Expression';
import Component from '../Component'; import Component from '../Component';
import TemplateScope from './shared/TemplateScope'; import TemplateScope from './shared/TemplateScope';
import {dimensions} from "../../utils/patterns";
// TODO this should live in a specific binding
const read_only_media_attributes = new Set([
'duration',
'buffered',
'seekable',
'played'
]);
export default class Binding extends Node { export default class Binding extends Node {
type: 'Binding'; type: 'Binding';
@ -11,6 +20,7 @@ export default class Binding extends Node {
is_contextual: boolean; is_contextual: boolean;
obj: string; obj: string;
prop: string; prop: string;
is_readonly: boolean;
constructor(component: Component, parent, scope: TemplateScope, info) { constructor(component: Component, parent, scope: TemplateScope, info) {
super(component, parent, scope, info); super(component, parent, scope, info);
@ -64,5 +74,17 @@ export default class Binding extends Node {
this.obj = obj; this.obj = obj;
this.prop = prop; this.prop = prop;
const type = parent.get_static_attribute_value('type');
this.is_readonly = (
dimensions.test(this.name) ||
(parent.is_media_node && parent.is_media_node() && read_only_media_attributes.has(this.name)) ||
(parent.name === 'input' && type === 'file') // TODO others?
);
}
is_readonly_media_attribute() {
return read_only_media_attributes.has(this.name);
} }
} }

@ -1,5 +1,5 @@
import Block from '../../render-dom/Block'; import Block from '../../render-dom/Block';
import Component from './../../Component'; import Component from '../../Component';
import Node from './Node'; import Node from './Node';
import { INode } from '../interfaces'; import { INode } from '../interfaces';

@ -1,5 +1,5 @@
import Attribute from './../Attribute'; import Attribute from '../Attribute';
import Component from './../../Component'; import Component from '../../Component';
import { INode } from '../interfaces'; import { INode } from '../interfaces';
import Text from '../Text'; import Text from '../Text';
@ -47,7 +47,7 @@ export default class Node {
} }
get_static_attribute_value(name: string) { get_static_attribute_value(name: string) {
const attribute = this.attributes.find( const attribute = this.attributes && this.attributes.find(
(attr: Attribute) => attr.type === 'Attribute' && attr.name.toLowerCase() === name (attr: Attribute) => attr.type === 'Attribute' && attr.name.toLowerCase() === name
); );

@ -164,7 +164,7 @@ export default class Block {
if (parent_node) { if (parent_node) {
this.builders.mount.add_line(`@append(${parent_node}, ${name});`); this.builders.mount.add_line(`@append(${parent_node}, ${name});`);
if (parent_node === 'document.head') this.builders.destroy.add_line(`@detach(${name});`); if (parent_node === 'document.head' && !no_detach) this.builders.destroy.add_line(`@detach(${name});`);
} else { } else {
this.builders.mount.add_line(`@insert(#target, ${name}, anchor);`); this.builders.mount.add_line(`@insert(#target, ${name}, anchor);`);
if (!no_detach) this.builders.destroy.add_conditional('detaching', `@detach(${name});`); if (!no_detach) this.builders.destroy.add_conditional('detaching', `@detach(${name});`);

@ -203,8 +203,10 @@ export default function dom(
if (variable && (variable.hoistable || variable.global || variable.module)) return; if (variable && (variable.hoistable || variable.global || variable.module)) return;
if (single && !(variable.subscribable && variable.reassigned)) { if (single && !(variable.subscribable && variable.reassigned)) {
if (variable.referenced || variable.is_reactive_dependency || variable.export_name) {
code.prependRight(node.start, `$$invalidate('${name}', `); code.prependRight(node.start, `$$invalidate('${name}', `);
code.appendLeft(node.end, `)`); code.appendLeft(node.end, `)`);
}
} else { } else {
pending_assignments.add(name); pending_assignments.add(name);
} }
@ -395,11 +397,11 @@ export default function dom(
}); });
let unknown_props_check; let unknown_props_check;
if (component.compile_options.dev && writable_props.length) { if (component.compile_options.dev && !component.var_lookup.has('$$props') && writable_props.length) {
unknown_props_check = deindent` unknown_props_check = deindent`
const writable_props = [${writable_props.map(prop => `'${prop.export_name}'`).join(', ')}]; const writable_props = [${writable_props.map(prop => `'${prop.export_name}'`).join(', ')}];
Object.keys($$props).forEach(key => { Object.keys($$props).forEach(key => {
if (!writable_props.includes(key)) console.warn(\`<${component.tag}> was created with unknown prop '\${key}'\`); if (!writable_props.includes(key) && !key.startsWith('$$')) console.warn(\`<${component.tag}> was created with unknown prop '\${key}'\`);
}); });
`; `;
} }

@ -1,5 +1,5 @@
import Binding from '../../../nodes/Binding'; import Binding from '../../../nodes/Binding';
import ElementWrapper from '.'; import ElementWrapper from '../Element';
import { dimensions } from '../../../../utils/patterns'; import { dimensions } from '../../../../utils/patterns';
import get_object from '../../../utils/get_object'; import get_object from '../../../utils/get_object';
import Block from '../../Block'; import Block from '../../Block';
@ -9,14 +9,6 @@ import flatten_reference from '../../../utils/flatten_reference';
import EachBlock from '../../../nodes/EachBlock'; import EachBlock from '../../../nodes/EachBlock';
import { Node as INode } from '../../../../interfaces'; import { Node as INode } from '../../../../interfaces';
// TODO this should live in a specific binding
const read_only_media_attributes = new Set([
'duration',
'buffered',
'seekable',
'played'
]);
function get_tail(node: INode) { function get_tail(node: INode) {
const end = node.end; const end = node.end;
while (node.type === 'MemberExpression') node = node.object; while (node.type === 'MemberExpression') node = node.object;
@ -74,13 +66,7 @@ export default class BindingWrapper {
this.snippet = this.node.expression.render(block); this.snippet = this.node.expression.render(block);
const type = parent.node.get_static_attribute_value('type'); this.is_readonly = this.node.is_readonly;
this.is_readonly = (
dimensions.test(this.node.name) ||
(parent.node.is_media_node() && read_only_media_attributes.has(this.node.name)) ||
(parent.node.name === 'input' && type === 'file') // TODO others?
);
this.needs_lock = this.node.name === 'currentTime'; // TODO others? this.needs_lock = this.node.name === 'currentTime'; // TODO others?
} }
@ -101,7 +87,7 @@ export default class BindingWrapper {
} }
is_readonly_media_attribute() { is_readonly_media_attribute() {
return read_only_media_attributes.has(this.node.name); return this.node.is_readonly_media_attribute()
} }
render(block: Block, lock: string) { render(block: Block, lock: string) {

@ -1,7 +1,7 @@
import Attribute from '../../../nodes/Attribute'; import Attribute from '../../../nodes/Attribute';
import Block from '../../Block'; import Block from '../../Block';
import AttributeWrapper from './Attribute'; import AttributeWrapper from './Attribute';
import ElementWrapper from '.'; import ElementWrapper from '../Element';
import { stringify } from '../../../utils/stringify'; import { stringify } from '../../../utils/stringify';
import add_to_set from '../../../utils/add_to_set'; import add_to_set from '../../../utils/add_to_set';
import Expression from '../../../nodes/shared/Expression'; import Expression from '../../../nodes/shared/Expression';

@ -30,6 +30,6 @@ export default class HeadWrapper extends Wrapper {
} }
render(block: Block, parent_node: string, parent_nodes: string) { render(block: Block, parent_node: string, parent_nodes: string) {
this.fragment.render(block, 'document.head', null); this.fragment.render(block, 'document.head', 'nodes');
} }
} }

@ -154,16 +154,18 @@ export default class IfBlockWrapper extends Wrapper {
const vars = { name, anchor, if_name, has_else, has_transitions }; const vars = { name, anchor, if_name, has_else, has_transitions };
const detaching = (parent_node && parent_node !== 'document.head') ? '' : 'detaching';
if (this.node.else) { if (this.node.else) {
if (has_outros) { if (has_outros) {
this.render_compound_with_outros(block, parent_node, parent_nodes, dynamic, vars); this.render_compound_with_outros(block, parent_node, parent_nodes, dynamic, vars, detaching);
block.builders.outro.add_line(`if (${name}) ${name}.o();`); block.builders.outro.add_line(`if (${name}) ${name}.o();`);
} else { } else {
this.render_compound(block, parent_node, parent_nodes, dynamic, vars); this.render_compound(block, parent_node, parent_nodes, dynamic, vars, detaching);
} }
} else { } else {
this.render_simple(block, parent_node, parent_nodes, dynamic, vars); this.render_simple(block, parent_node, parent_nodes, dynamic, vars, detaching);
if (has_outros) { if (has_outros) {
block.builders.outro.add_line(`if (${name}) ${name}.o();`); block.builders.outro.add_line(`if (${name}) ${name}.o();`);
@ -201,7 +203,8 @@ export default class IfBlockWrapper extends Wrapper {
parent_node: string, parent_node: string,
parent_nodes: string, parent_nodes: string,
dynamic, dynamic,
{ name, anchor, has_else, if_name, has_transitions } { name, anchor, has_else, if_name, has_transitions },
detaching
) { ) {
const select_block_type = this.renderer.component.get_unique_name(`select_block_type`); const select_block_type = this.renderer.component.get_unique_name(`select_block_type`);
const current_block_type = block.get_unique_name(`current_block_type`); const current_block_type = block.get_unique_name(`current_block_type`);
@ -254,7 +257,7 @@ export default class IfBlockWrapper extends Wrapper {
`); `);
} }
block.builders.destroy.add_line(`${if_name}${name}.d(${parent_node ? '' : 'detaching'});`); block.builders.destroy.add_line(`${if_name}${name}.d(${detaching});`);
} }
// if any of the siblings have outros, we need to keep references to the blocks // if any of the siblings have outros, we need to keep references to the blocks
@ -264,7 +267,8 @@ export default class IfBlockWrapper extends Wrapper {
parent_node: string, parent_node: string,
parent_nodes: string, parent_nodes: string,
dynamic, dynamic,
{ name, anchor, has_else, has_transitions } { name, anchor, has_else, has_transitions },
detaching
) { ) {
const select_block_type = this.renderer.component.get_unique_name(`select_block_type`); const select_block_type = this.renderer.component.get_unique_name(`select_block_type`);
const current_block_type_index = block.get_unique_name(`current_block_type_index`); const current_block_type_index = block.get_unique_name(`current_block_type_index`);
@ -375,7 +379,7 @@ export default class IfBlockWrapper extends Wrapper {
} }
block.builders.destroy.add_line(deindent` block.builders.destroy.add_line(deindent`
${if_current_block_type_index}${if_blocks}[${current_block_type_index}].d(${parent_node ? '' : 'detaching'}); ${if_current_block_type_index}${if_blocks}[${current_block_type_index}].d(${detaching});
`); `);
} }
@ -384,7 +388,8 @@ export default class IfBlockWrapper extends Wrapper {
parent_node: string, parent_node: string,
parent_nodes: string, parent_nodes: string,
dynamic, dynamic,
{ name, anchor, if_name, has_transitions } { name, anchor, if_name, has_transitions },
detaching
) { ) {
const branch = this.branches[0]; const branch = this.branches[0];
@ -450,6 +455,6 @@ export default class IfBlockWrapper extends Wrapper {
} }
`); `);
block.builders.destroy.add_line(`${if_name}${name}.d(${parent_node ? '' : 'detaching'});`); block.builders.destroy.add_line(`${if_name}${name}.d(${detaching});`);
} }
} }

@ -22,9 +22,18 @@ export default class RawMustacheTagWrapper extends Tag {
render(block: Block, parent_node: string, parent_nodes: string) { render(block: Block, parent_node: string, parent_nodes: string) {
const name = this.var; const name = this.var;
const in_head = parent_node === 'document.head';
const needs_anchors = !parent_node || in_head;
// if in head always needs anchors
if (in_head) {
this.prev = null;
this.next = null;
}
// TODO use is_dom_node instead of type === 'Element'? // TODO use is_dom_node instead of type === 'Element'?
const needs_anchor_before = this.prev ? this.prev.node.type !== 'Element' : !parent_node; const needs_anchor_before = this.prev ? this.prev.node.type !== 'Element' : needs_anchors;
const needs_anchor_after = this.next ? this.next.node.type !== 'Element' : !parent_node; const needs_anchor_after = this.next ? this.next.node.type !== 'Element' : needs_anchors;
const anchor_before = needs_anchor_before const anchor_before = needs_anchor_before
? block.get_unique_name(`${name}_before`) ? block.get_unique_name(`${name}_before`)
@ -90,7 +99,7 @@ export default class RawMustacheTagWrapper extends Tag {
block.builders.mount.add_line(insert(init)); block.builders.mount.add_line(insert(init));
if (!parent_node) { if (needs_anchors) {
block.builders.destroy.add_conditional('detaching', needs_anchor_before block.builders.destroy.add_conditional('detaching', needs_anchor_before
? `${detach}\n@detach(${anchor_before});` ? `${detach}\n@detach(${anchor_before});`
: detach); : detach);

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save