Merge branch 'master' into IlyaSemenov-gh-2843

pull/3030/head
Richard Harris 6 years ago
commit 1ad555cc32

@ -1,9 +0,0 @@
[ignore]
<PROJECT_ROOT>/types/.*
[include]
[libs]
[options]
strip_root=true

1
.gitignore vendored

@ -4,6 +4,7 @@
node_modules
*.map
/src/compiler/compile/internal-exports.ts
/compiler.d.ts
/compiler.*js
/index.*js
/internal

1
compiler.d.ts vendored

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

6
package-lock.json generated

@ -49,9 +49,9 @@
"dev": true
},
"@types/node": {
"version": "10.12.18",
"resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.18.tgz",
"integrity": "sha512-fh+pAqt4xRzPfqA6eh3Z2y6fyZavRIumvjhaCL753+TVkGKGhpPeyrJG2JftD0T9q4GF00KjefsQ+PQNDdWQaQ==",
"version": "8.10.49",
"resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.49.tgz",
"integrity": "sha512-YX30JVx0PvSmJ3Eqr74fYLGeBxD+C7vIL20ek+GGGLJeUbVYRUW3EzyAXpIRA0K8c8o0UWqR/GwEFYiFoz1T8w==",
"dev": true
},
"@typescript-eslint/eslint-plugin": {

@ -21,7 +21,7 @@
"engines": {
"node": ">= 8"
},
"types": "types/runtime",
"types": "types/runtime/index.d.ts",
"scripts": {
"test": "mocha --opts mocha.opts",
"test:unit": "mocha --require sucrase/register --recursive src/**/__test__.ts",
@ -35,10 +35,8 @@
"dev": "rollup -cw",
"pretest": "npm run build",
"posttest": "agadoo internal/index.mjs",
"prepublishOnly": "export PUBLISH=true && npm test && npm run create-stubs",
"create-stubs": "node scripts/create-stubs.js",
"tsd": "tsc -p . --emitDeclarationOnly",
"typecheck": "tsc -p . --noEmit",
"prepublishOnly": "PUBLISH=true npm test",
"tsd": "tsc -p src/compiler --emitDeclarationOnly && tsc -p src/runtime --emitDeclarationOnly",
"lint": "eslint \"{src,test}/**/*.{ts,js}\""
},
"repository": {
@ -59,7 +57,7 @@
"homepage": "https://github.com/sveltejs/svelte#README",
"devDependencies": {
"@types/mocha": "^5.2.0",
"@types/node": "^10.5.5",
"@types/node": "=8",
"@typescript-eslint/eslint-plugin": "^1.9.0",
"@typescript-eslint/parser": "^1.9.0",
"acorn": "^6.1.1",

@ -20,6 +20,8 @@ const ts_plugin = is_publish
const external = id => id.startsWith('svelte/');
fs.writeFileSync(`./compiler.d.ts`, `export * from './types/compiler/index';`);
export default [
/* runtime */
{
@ -59,12 +61,22 @@ export default [
external,
plugins: [
ts_plugin,
dir === 'internal' && {
generateBundle(options, bundle) {
const mod = bundle['index.mjs'];
if (mod) {
fs.writeFileSync('src/compiler/compile/internal-exports.ts', `// This file is automatically generated\nexport default new Set(${JSON.stringify(mod.exports)});`);
{
writeBundle(bundle) {
if (dir === 'internal') {
const mod = bundle['index.mjs'];
if (mod) {
fs.writeFileSync('src/compiler/compile/internal-exports.ts', `// This file is automatically generated\nexport default new Set(${JSON.stringify(mod.exports)});`);
}
}
fs.writeFileSync(`${dir}/package.json`, JSON.stringify({
main: './index',
module: './index.mjs',
types: './index.d.ts'
}, null, ' '));
fs.writeFileSync(`${dir}/index.d.ts`, `export * from '../types/runtime/${dir}/index';`);
}
}
]

@ -1,12 +0,0 @@
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',
module: './index.mjs'
}, null, ' '));
fs.writeFileSync(`${dir}/index.d.ts`, `export * from '../types/runtime/${dir}/index.d.ts';`);
});

@ -43,10 +43,12 @@
}
function remove() {
people = [...people.slice(0, i), ...people.slice(i + 1)];
// Remove selected person from the source array (people), not the filtered array
const index = people.indexOf(selected);
people = [...people.slice(0, index), ...people.slice(index + 1)];
first = last = '';
i = Math.min(i, people.length - 1);
i = Math.min(i, filteredPeople.length - 2);
}
function reset_inputs(person) {

@ -1,6 +1,6 @@
<script>
import { comicSans, link } from './styles.js';
import Hero from './Hero.html';
import Hero from './Hero.svelte';
</script>
<Hero/>

@ -1,4 +1,6 @@
import { css } from 'emotion/dist/emotion.umd.min.js';
import emotion from 'emotion/dist/emotion.umd.min.js';
const { css } = emotion;
const brand = '#74D900';
@ -30,4 +32,4 @@ export const link = css`
text-decoration: none;
background: ${brand};
}
`;
`;

@ -1,5 +0,0 @@
{
"name": "Using fixtures to represent data",
"email": "hello@cypress.io",
"body": "Fixtures are a great way to mock data for responses to routes"
}

@ -1,19 +0,0 @@
describe('Sapper template app', () => {
beforeEach(() => {
cy.visit('/')
});
it('has the correct <h1>', () => {
cy.contains('h1', 'Great success!')
});
it('navigates to /about', () => {
cy.get('nav a').contains('about').click();
cy.url().should('include', '/about');
});
it('navigates to /blog', () => {
cy.get('nav a').contains('blog').click();
cy.url().should('include', '/blog');
});
});

@ -1,17 +0,0 @@
// ***********************************************************
// This example plugins/index.js can be used to load plugins
//
// You can change the location of this file or turn off loading
// the plugins file with the 'pluginsFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/plugins-guide
// ***********************************************************
// This function is called when a project is opened or re-opened (e.g. due to
// the project's config changing)
module.exports = (on, config) => {
// `on` is used to hook into various events Cypress emits
// `config` is the resolved Cypress config
}

@ -1,25 +0,0 @@
// ***********************************************
// This example commands.js shows you how to
// create various custom commands and overwrite
// existing commands.
//
// For more comprehensive examples of custom
// commands please read more here:
// https://on.cypress.io/custom-commands
// ***********************************************
//
//
// -- This is a parent command --
// Cypress.Commands.add("login", (email, password) => { ... })
//
//
// -- This is a child command --
// Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... })
//
//
// -- This is a dual command --
// Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... })
//
//
// -- This is will overwrite an existing command --
// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... })

@ -1,20 +0,0 @@
// ***********************************************************
// This example support/index.js is processed and
// loaded automatically before your test files.
//
// This is a great place to put global configuration and
// behavior that modifies Cypress.
//
// You can change the location of this file or turn off
// automatically serving support files with the
// 'supportFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/configuration
// ***********************************************************
// Import commands.js using ES2015 syntax:
import './commands'
// Alternatively you can use CommonJS syntax:
// require('./commands')

@ -1362,9 +1362,9 @@
}
},
"@sveltejs/svelte-repl": {
"version": "0.1.7",
"resolved": "https://registry.npmjs.org/@sveltejs/svelte-repl/-/svelte-repl-0.1.7.tgz",
"integrity": "sha512-/023rff9mUtF+RqRbYUbMCwAMcvxkWc97Q8i+77G3LUVQSR44TR84lvdsnCHJwj1C+RhF/Npncd2GJSskRmgbQ==",
"version": "0.1.8",
"resolved": "https://registry.npmjs.org/@sveltejs/svelte-repl/-/svelte-repl-0.1.8.tgz",
"integrity": "sha512-RSKsuiQE3DrdT7B7DNhd5DK+DkYGLT5m6Ugchxc8iN+5v/hfVTbeNb+KJtItXLpDxiYdbb0HIiQPEdy0M+HThw==",
"dev": true,
"requires": {
"codemirror": "^5.45.0",

@ -7,13 +7,9 @@
"copy-workers": "rm -rf static/workers && cp -r node_modules/@sveltejs/svelte-repl/workers static",
"migrate": "node-pg-migrate -r dotenv/config",
"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": "node scripts/update_template.js && node scripts/get-contributors.js",
"start": "node __sapper__/build",
"cy:run": "cypress run",
"cy:open": "cypress open",
"test": "run-p --race dev cy:run",
"testsrc": "mocha -r esm test/**",
"test": "mocha -r esm test/**",
"deploy": "make deploy"
},
"dependencies": {
@ -39,7 +35,7 @@
"@babel/runtime": "^7.4.4",
"@sindresorhus/slugify": "^0.9.1",
"@sveltejs/site-kit": "^1.0.4",
"@sveltejs/svelte-repl": "^0.1.7",
"@sveltejs/svelte-repl": "^0.1.8",
"degit": "^2.1.3",
"dotenv": "^8.0.0",
"eslint-plugin-svelte3": "^1.0.0",

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

@ -610,7 +610,7 @@ export default class Element extends Node {
} else if (
name === 'text' ||
name === 'html'
){
) {
const contenteditable = this.attributes.find(
(attribute: Attribute) => attribute.name === 'contenteditable'
);
@ -626,7 +626,7 @@ export default class Element extends Node {
message: `'contenteditable' attribute cannot be dynamic if element uses two-way binding`
});
}
} else if (name !== 'this') {
} else if (name !== 'this') {
component.error(binding, {
code: `invalid-binding`,
message: `'${binding.name}' is not a valid binding`

@ -12,7 +12,7 @@ export default class Text extends Node {
super(component, parent, scope, info);
this.data = info.data;
if (!component.component_options.preserveWhitespace && !/\S/.test(info.data)) {
if (!component.component_options.preserveWhitespace && !/[\S\u00A0]/.test(info.data)) {
let node = parent;
while (node) {
if (node.type === 'Element' && node.name === 'pre') {

@ -224,79 +224,20 @@ export default class AttributeWrapper {
}
}
// source: https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes
// source: https://html.spec.whatwg.org/multipage/indices.html
const attribute_lookup = {
accept: { applies_to: ['form', 'input'] },
'accept-charset': { property_name: 'acceptCharset', applies_to: ['form'] },
accesskey: { property_name: 'accessKey' },
action: { applies_to: ['form'] },
align: {
applies_to: [
'applet',
'caption',
'col',
'colgroup',
'hr',
'iframe',
'img',
'table',
'tbody',
'td',
'tfoot',
'th',
'thead',
'tr',
],
},
allowfullscreen: { property_name: 'allowFullscreen', applies_to: ['iframe'] },
alt: { applies_to: ['applet', 'area', 'img', 'input'] },
allowpaymentrequest: { property_name: 'allowPaymentRequest', applies_to: ['iframe'] },
async: { applies_to: ['script'] },
autocomplete: { applies_to: ['form', 'input'] },
autofocus: { applies_to: ['button', 'input', 'keygen', 'select', 'textarea'] },
autoplay: { applies_to: ['audio', 'video'] },
autosave: { applies_to: ['input'] },
bgcolor: {
property_name: 'bgColor',
applies_to: [
'body',
'col',
'colgroup',
'marquee',
'table',
'tbody',
'tfoot',
'td',
'th',
'tr',
],
},
border: { applies_to: ['img', 'object', 'table'] },
buffered: { applies_to: ['audio', 'video'] },
challenge: { applies_to: ['keygen'] },
charset: { applies_to: ['meta', 'script'] },
checked: { applies_to: ['command', 'input'] },
cite: { applies_to: ['blockquote', 'del', 'ins', 'q'] },
class: { property_name: 'className' },
code: { applies_to: ['applet'] },
codebase: { property_name: 'codeBase', applies_to: ['applet'] },
color: { applies_to: ['basefont', 'font', 'hr'] },
cols: { applies_to: ['textarea'] },
colspan: { property_name: 'colSpan', applies_to: ['td', 'th'] },
content: { applies_to: ['meta'] },
contenteditable: { property_name: 'contentEditable' },
contextmenu: {},
checked: { applies_to: ['input'] },
controls: { applies_to: ['audio', 'video'] },
coords: { applies_to: ['area'] },
data: { applies_to: ['object'] },
datetime: { property_name: 'dateTime', applies_to: ['del', 'ins', 'time'] },
default: { applies_to: ['track'] },
defer: { applies_to: ['script'] },
dir: {},
dirname: { property_name: 'dirName', applies_to: ['input', 'textarea'] },
disabled: {
applies_to: [
'button',
'command',
'fieldset',
'input',
'keygen',
@ -306,119 +247,21 @@ const attribute_lookup = {
'textarea',
],
},
download: { applies_to: ['a', 'area'] },
draggable: {},
dropzone: {},
enctype: { applies_to: ['form'] },
for: { property_name: 'htmlFor', applies_to: ['label', 'output'] },
formaction: { applies_to: ['input', 'button'] },
headers: { applies_to: ['td', 'th'] },
height: {
applies_to: ['canvas', 'embed', 'iframe', 'img', 'input', 'object', 'video'],
},
formnovalidate: { property_name: 'formNoValidate', applies_to: ['button', 'input'] },
hidden: {},
high: { applies_to: ['meter'] },
href: { applies_to: ['a', 'area', 'base', 'link'] },
hreflang: { applies_to: ['a', 'area', 'link'] },
'http-equiv': { property_name: 'httpEquiv', applies_to: ['meta'] },
icon: { applies_to: ['command'] },
id: {},
indeterminate: { applies_to: ['input'] },
ismap: { property_name: 'isMap', applies_to: ['img'] },
itemprop: {},
keytype: { applies_to: ['keygen'] },
kind: { applies_to: ['track'] },
label: { applies_to: ['track'] },
lang: {},
language: { applies_to: ['script'] },
loop: { applies_to: ['audio', 'bgsound', 'marquee', 'video'] },
low: { applies_to: ['meter'] },
manifest: { applies_to: ['html'] },
max: { applies_to: ['input', 'meter', 'progress'] },
maxlength: { property_name: 'maxLength', applies_to: ['input', 'textarea'] },
media: { applies_to: ['a', 'area', 'link', 'source', 'style'] },
method: { applies_to: ['form'] },
min: { applies_to: ['input', 'meter'] },
loop: { applies_to: ['audio', 'bgsound', 'video'] },
multiple: { applies_to: ['input', 'select'] },
muted: { applies_to: ['audio', 'video'] },
name: {
applies_to: [
'button',
'form',
'fieldset',
'iframe',
'input',
'keygen',
'object',
'output',
'select',
'textarea',
'map',
'meta',
'param',
],
},
nomodule: { property_name: 'noModule', applies_to: ['script'] },
novalidate: { property_name: 'noValidate', applies_to: ['form'] },
open: { applies_to: ['details'] },
optimum: { applies_to: ['meter'] },
pattern: { applies_to: ['input'] },
ping: { applies_to: ['a', 'area'] },
placeholder: { applies_to: ['input', 'textarea'] },
poster: { applies_to: ['video'] },
preload: { applies_to: ['audio', 'video'] },
radiogroup: { applies_to: ['command'] },
open: { applies_to: ['details', 'dialog'] },
playsinline: { property_name: 'playsInline', applies_to: ['video'] },
readonly: { property_name: 'readOnly', applies_to: ['input', 'textarea'] },
rel: { applies_to: ['a', 'area', 'link'] },
required: { applies_to: ['input', 'select', 'textarea'] },
reversed: { applies_to: ['ol'] },
rows: { applies_to: ['textarea'] },
rowspan: { property_name: 'rowSpan', applies_to: ['td', 'th'] },
sandbox: { applies_to: ['iframe'] },
scope: { applies_to: ['th'] },
scoped: { applies_to: ['style'] },
seamless: { applies_to: ['iframe'] },
selected: { applies_to: ['option'] },
shape: { applies_to: ['a', 'area'] },
size: { applies_to: ['input', 'select'] },
sizes: { applies_to: ['link', 'img', 'source'] },
span: { applies_to: ['col', 'colgroup'] },
spellcheck: {},
src: {
applies_to: [
'audio',
'embed',
'iframe',
'img',
'input',
'script',
'source',
'track',
'video',
],
},
srcdoc: { applies_to: ['iframe'] },
srclang: { applies_to: ['track'] },
srcset: { applies_to: ['img'] },
start: { applies_to: ['ol'] },
step: { applies_to: ['input'] },
style: { property_name: 'style.cssText' },
summary: { applies_to: ['table'] },
tabindex: { property_name: 'tabIndex' },
target: { applies_to: ['a', 'area', 'base', 'form'] },
title: {},
type: {
applies_to: [
'button',
'command',
'embed',
'object',
'script',
'source',
'style',
'menu',
],
},
usemap: { property_name: 'useMap', applies_to: ['img', 'input', 'object'] },
value: {
applies_to: [
'button',
@ -432,12 +275,6 @@ const attribute_lookup = {
'textarea',
],
},
volume: { applies_to: ['audio', 'video'] },
playbackRate: { applies_to: ['audio', 'video'] },
width: {
applies_to: ['canvas', 'embed', 'iframe', 'img', 'input', 'object', 'video'],
},
wrap: { applies_to: ['textarea'] },
};
Object.keys(attribute_lookup).forEach(name => {

@ -151,12 +151,12 @@ export default function(node: Element, renderer: Renderer, options: RenderOption
if (name === 'group') {
// TODO server-render group bindings
} else if (contenteditable && (name === 'text' || name === 'html')) {
const snippet = snip(expression)
const snippet = snip(expression);
if (name == 'text') {
node_contents = '${@escape(' + snippet + ')}'
node_contents = '${@escape(' + snippet + ')}';
} else {
// Do not escape HTML content
node_contents = '${' + snippet + '}'
node_contents = '${' + snippet + '}';
}
} else if (binding.name === 'value' && node.name === 'textarea') {
const snippet = snip(expression);

@ -385,6 +385,7 @@ function read_attribute(parser: Parser, unique_names: Set<string>) {
let value: any[] | true = true;
if (parser.eat('=')) {
parser.allow_whitespace();
value = read_attribute_value(parser);
end = parser.index;
} else if (parser.match_regex(/["']/)) {

@ -0,0 +1,11 @@
{
"extends": "../../tsconfig.json",
"include": ["."],
"compilerOptions": {
"lib": ["es2017", "webworker"]
// TODO: remove mocha types from the whole project
// "types": ["node", "estree"]
}
}

@ -1,4 +1,5 @@
import { identity as linear, noop, now } from './utils';
import { identity as linear, noop } from './utils';
import { now } from './environment';
import { loop } from './loop';
import { create_rule, delete_rule } from './style_manager';
import { AnimationConfig } from '../animate';

@ -0,0 +1,16 @@
export const is_client = typeof window !== 'undefined';
export let now: () => number = is_client
? () => window.performance.now()
: () => Date.now();
export let raf = cb => requestAnimationFrame(cb);
// used internally for testing
export function set_now(fn) {
now = fn;
}
export function set_raf(fn) {
raf = fn;
}

@ -1,6 +1,7 @@
export * from './animations';
export * from './await-block';
export * from './dom';
export * from './environment';
export * from './keyed-each';
export * from './lifecycle';
export * from './loop';

@ -1,4 +1,4 @@
import { now, raf } from './utils';
import { now, raf } from './environment';
export interface Task { abort(): void; promise: Promise<void> }

@ -1,5 +1,5 @@
import { element } from './dom';
import { raf } from './utils';
import { raf } from './environment';
let stylesheet;
let active = 0;

@ -1,4 +1,5 @@
import { identity as linear, is_function, noop, now, run_all } from './utils';
import { identity as linear, is_function, noop, run_all } from './utils';
import { now } from "./environment";
import { loop } from './loop';
import { create_rule, delete_rule } from './style_manager';
import { custom_event } from './dom';

@ -87,22 +87,5 @@ export function once(fn) {
if (ran) return;
ran = true;
fn.call(this, ...args);
}
}
const is_client = typeof window !== 'undefined';
export let now: () => number = is_client
? () => window.performance.now()
: () => Date.now();
export let raf = is_client ? requestAnimationFrame : noop;
// used internally for testing
export function set_now(fn) {
now = fn;
}
export function set_raf(fn) {
raf = fn;
};
}

@ -0,0 +1,15 @@
{
"extends": "../../tsconfig.json",
"include": ["."],
"compilerOptions": {
"lib": ["es2015", "dom", "dom.iterable"],
"target": "es2015",
"types": [],
"baseUrl": ".",
"paths": {
"svelte/*": ["*"]
}
}
}

@ -1,6 +1,7 @@
/* generated by Svelte vX.Y.Z */
import {
SvelteComponent,
attr,
detach,
element,
init,
@ -16,7 +17,7 @@ function create_fragment(ctx) {
c() {
a = element("a");
a.textContent = "Test";
a.href = "#";
attr(a, "href", "#");
},
m(target, anchor) {

@ -2,6 +2,7 @@
import {
SvelteComponent,
append,
attr,
detach,
element,
init,
@ -26,7 +27,7 @@ function create_fragment(ctx) {
c() {
p = element("p");
t = text(ctx.foo);
p.className = "svelte-1a7i8ec";
attr(p, "class", "svelte-1a7i8ec");
},
m(target, anchor) {

@ -2,6 +2,7 @@
import {
SvelteComponent,
append,
attr,
detach,
element,
init,
@ -23,7 +24,7 @@ function create_fragment(ctx) {
return {
c() {
div = element("div");
div.className = "svelte-1slhpfn";
attr(div, "class", "svelte-1slhpfn");
},
m(target, anchor) {

@ -2,6 +2,7 @@
import {
SvelteComponent,
append,
attr,
destroy_each,
detach,
detach_after,
@ -39,8 +40,8 @@ function create_each_block(ctx) {
t5 = text(" ago:");
t6 = space();
raw_before = element('noscript');
span.className = "meta";
div.className = "comment";
attr(span, "class", "meta");
attr(div, "class", "comment");
},
m(target, anchor) {

@ -1,6 +1,7 @@
/* generated by Svelte vX.Y.Z */
import {
SvelteComponent,
attr,
detach,
element,
init,
@ -17,7 +18,7 @@ function create_fragment(ctx) {
c() {
a = element("a");
a.textContent = "this should not navigate to example.com";
a.href = "https://example.com";
attr(a, "href", "https://example.com");
dispose = listen(a, "touchstart", touchstart_handler);
},

@ -2,6 +2,7 @@
import {
SvelteComponent,
append,
attr,
detach,
element,
init,
@ -16,10 +17,10 @@ function create_fragment(ctx) {
c() {
meta0 = element("meta");
meta1 = element("meta");
meta0.name = "twitter:creator";
meta0.content = "@sveltejs";
meta1.name = "twitter:title";
meta1.content = "Svelte";
attr(meta0, "name", "twitter:creator");
attr(meta0, "content", "@sveltejs");
attr(meta1, "name", "twitter:title");
attr(meta1, "content", "Svelte");
},
m(target, anchor) {

@ -1,6 +1,7 @@
/* generated by Svelte vX.Y.Z */
import {
SvelteComponent,
attr,
detach,
element,
init,
@ -18,8 +19,8 @@ function create_fragment(ctx) {
div0 = element("div");
t = space();
div1 = element("div");
div0.style.cssText = ctx.style;
div1.style.cssText = div1_style_value = "" + ctx.key + ": " + ctx.value;
attr(div0, "style", ctx.style);
attr(div1, "style", div1_style_value = "" + ctx.key + ": " + ctx.value);
},
m(target, anchor) {
@ -30,11 +31,11 @@ function create_fragment(ctx) {
p(changed, ctx) {
if (changed.style) {
div0.style.cssText = ctx.style;
attr(div0, "style", ctx.style);
}
if ((changed.key || changed.value) && div1_style_value !== (div1_style_value = "" + ctx.key + ": " + ctx.value)) {
div1.style.cssText = div1_style_value;
attr(div1, "style", div1_style_value);
}
},

@ -0,0 +1 @@
<button on:click= {foo}>Click</button>

@ -0,0 +1,39 @@
{
"html": {
"start": 0,
"end": 38,
"type": "Fragment",
"children": [
{
"start": 0,
"end": 38,
"type": "Element",
"name": "button",
"attributes": [
{
"start": 8,
"end": 23,
"type": "EventHandler",
"name": "click",
"modifiers": [],
"expression": {
"type": "Identifier",
"start": 19,
"end": 22,
"name": "foo"
}
}
],
"children": [
{
"start": 24,
"end": 29,
"type": "Text",
"raw": "Click",
"data": "Click"
}
]
}
]
}
}

@ -4,7 +4,7 @@ export default {
},
html: `
<editor><b>world</b></editor>
<editor contenteditable="true"><b>world</b></editor>
<p>hello <b>world</b></p>
`,
@ -19,24 +19,24 @@ export default {
el.innerHTML = 'every<span>body</span>';
// No updates to data yet
// No updates to data yet
assert.htmlEqual(target.innerHTML, `
<editor>every<span>body</span></editor>
<editor contenteditable="true">every<span>body</span></editor>
<p>hello <b>world</b></p>
`);
// Handle user input
const event = new window.Event('input');
// Handle user input
const event = new window.Event('input');
await el.dispatchEvent(event);
assert.htmlEqual(target.innerHTML, `
<editor>every<span>body</span></editor>
<editor contenteditable="true">every<span>body</span></editor>
<p>hello every<span>body</span></p>
`);
component.name = 'good<span>bye</span>';
assert.equal(el.innerHTML, 'good<span>bye</span>');
assert.htmlEqual(target.innerHTML, `
<editor>good<span>bye</span></editor>
<editor contenteditable="true">good<span>bye</span></editor>
<p>hello good<span>bye</span></p>
`);
},

@ -4,7 +4,7 @@ export default {
},
html: `
<editor>world</editor>
<editor contenteditable="true">world</editor>
<p>hello world</p>
`,
@ -23,14 +23,14 @@ export default {
await el.dispatchEvent(event);
assert.htmlEqual(target.innerHTML, `
<editor>everybody</editor>
<editor contenteditable="true">everybody</editor>
<p>hello everybody</p>
`);
component.name = 'goodbye';
assert.equal(el.textContent, 'goodbye');
assert.htmlEqual(target.innerHTML, `
<editor>goodbye</editor>
<editor contenteditable="true">goodbye</editor>
<p>hello goodbye</p>
`);
},

@ -0,0 +1,19 @@
export default {
html: `<div>&nbsp;hello</div>
<div>&nbsp;hello&nbsp;&nbsp;</div>
<div>&nbsp;hello&nbsp; &nbsp;hello</div>`,
test({ assert, component, target }) {
var divList = target.querySelectorAll('div')
assert.equal( divList[0].textContent.charCodeAt( 0 ), 160 );
assert.equal( divList[1].textContent.charCodeAt( 0 ), 160 );
assert.equal( divList[1].textContent.charCodeAt( 6 ), 160 );
assert.equal( divList[1].textContent.charCodeAt( 7 ), 160 );
assert.equal( divList[2].textContent.charCodeAt( 0 ), 160 );
assert.equal( divList[2].textContent.charCodeAt( 6 ), 160 );
assert.equal( divList[2].textContent.charCodeAt( 7 ), 32 );//normal space
assert.equal( divList[2].textContent.charCodeAt( 8 ), 160 );
}
};

@ -0,0 +1,7 @@
<script>
let name = 'hello';
</script>
<div>&nbsp;{name}</div>
<div>&nbsp;{name}&nbsp;&nbsp;</div>
<div>&nbsp;{name}&nbsp; &nbsp;{name}</div>

@ -1,5 +1,5 @@
export default {
html: '<div></div>',
html: `<div draggable='false'></div>`,
ssrHtml: '<div foo=1></div>'
ssrHtml: `<div foo='1' draggable='false'></div>`,
};

@ -3,10 +3,11 @@
export let foo = 1;
export let bar;
export let _class;
onMount(() => {
foo = undefined;
});
</script>
<div {foo} {bar}></div>
<div {foo} {bar} class={_class} draggable='false'></div>

@ -1,2 +0,0 @@
div.svelte-bzh57p{color:red}
div.svelte-4yw8vx{color:green}

@ -0,0 +1,10 @@
{
"extends": "../tsconfig.json",
"include": ["."],
"compilerOptions": {
"allowJs": true,
"checkJs": true,
"noEmit": true
}
}

@ -1,33 +1,30 @@
{
"include": [],
"compilerOptions": {
"target": "es2015",
"module": "es6",
"rootDir": "src",
// target node v8+ (https://node.green/)
// the only missing feature is Array.prototype.values
"lib": ["es2017"],
"target": "es2017",
"declaration": true,
"declarationDir": "types",
"noImplicitThis": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noEmitOnError": true,
"lib": [
"es5",
"es6",
"dom",
"es2015"
],
"importHelpers": true,
"noErrorTruncation": true,
// rollup takes care of these
"module": "esnext",
"moduleResolution": "node",
"baseUrl": ".",
"paths": {
"svelte/internal": ["./src/runtime/internal/index"],
"svelte/easing": ["./src/runtime/easing/index"],
"svelte/motion": ["./src/runtime/motion/index"],
"svelte/store": ["./src/runtime/store/index"]
},
"typeRoots": [
"node_modules/@types"
]
},
"include": [
"src/**/*"
]
"resolveJsonModule": true,
"allowSyntheticDefaultImports": true,
// TODO: error all the things
//"strict": true,
"noImplicitThis": true,
"noUnusedLocals": true,
"noUnusedParameters": true
}
}

Loading…
Cancel
Save