Upgrade svelte eslint config

pull/5440/head
Ben McCann 5 years ago
parent e867a4de33
commit 48c2db07f6

4
package-lock.json generated

@ -144,8 +144,8 @@
}
},
"@sveltejs/eslint-config": {
"version": "github:sveltejs/eslint-config#848ce6464a9ae9c2f3a3095474701dfe9ab851df",
"from": "github:sveltejs/eslint-config#v5.0.0",
"version": "github:sveltejs/eslint-config#ad995ff0965e084ea1b43912266070903e107962",
"from": "github:sveltejs/eslint-config#v5.1.0",
"dev": true
},
"@tootallnate/once": {

@ -37,7 +37,7 @@
"posttest": "agadoo internal/index.mjs",
"prepublishOnly": "npm run lint && PUBLISH=true npm test",
"tsd": "tsc -p src/compiler --emitDeclarationOnly && tsc -p src/runtime --emitDeclarationOnly",
"lint": "eslint \"{src,test}/**/*.{ts,js}\""
"lint": "eslint '{src,test}/**/*.{ts,js}'"
},
"repository": {
"type": "git",
@ -63,7 +63,7 @@
"@rollup/plugin-sucrase": "^3.0.0",
"@rollup/plugin-typescript": "^2.0.1",
"@rollup/plugin-virtual": "^2.0.0",
"@sveltejs/eslint-config": "github:sveltejs/eslint-config#v5.0.0",
"@sveltejs/eslint-config": "github:sveltejs/eslint-config#v5.1.0",
"@types/mocha": "^7.0.0",
"@types/node": "^8.10.53",
"@typescript-eslint/eslint-plugin": "^3.0.2",

@ -155,7 +155,7 @@ export default class Component {
) || { start: 0, end: 0 };
this.warn(svelteOptions, {
code: 'custom-element-no-tag',
message: `No custom element 'tag' option was specified. To automatically register a custom element, specify a name with a hyphen in it, e.g. <svelte:options tag="my-thing"/>. To hide this warning, use <svelte:options tag={null}/>`
message: 'No custom element \'tag\' option was specified. To automatically register a custom element, specify a name with a hyphen in it, e.g. <svelte:options tag="my-thing"/>. To hide this warning, use <svelte:options tag={null}/>'
});
}
this.tag = this.component_options.tag || compile_options.tag;
@ -235,7 +235,7 @@ export default class Component {
const { compile_options, name } = this;
const { format = 'esm' } = compile_options;
const banner = `${this.file ? `${this.file} ` : ``}generated by Svelte v${'__VERSION__'}`;
const banner = `${this.file ? `${this.file} ` : ''}generated by Svelte v${'__VERSION__'}`;
const program: any = { type: 'Program', body: result.js };
@ -452,16 +452,16 @@ export default class Component {
extract_exports(node) {
if (node.type === 'ExportDefaultDeclaration') {
this.error(node, {
code: `default-export`,
message: `A component cannot have a default export`
code: 'default-export',
message: 'A component cannot have a default export'
});
}
if (node.type === 'ExportNamedDeclaration') {
if (node.source) {
this.error(node, {
code: `not-implemented`,
message: `A component currently cannot have an export ... from`
code: 'not-implemented',
message: 'A component currently cannot have an export ... from'
});
}
if (node.declaration) {
@ -472,7 +472,7 @@ export default class Component {
variable.export_name = name;
if (variable.writable && !(variable.referenced || variable.referenced_from_script || variable.subscribable)) {
this.warn(declarator, {
code: `unused-export-let`,
code: 'unused-export-let',
message: `${this.name.name} has unused export property '${name}'. If it is for external reference only, please consider using \`export const ${name}\``
});
}
@ -495,7 +495,7 @@ export default class Component {
if (variable.writable && !(variable.referenced || variable.referenced_from_script || variable.subscribable)) {
this.warn(specifier, {
code: `unused-export-let`,
code: 'unused-export-let',
message: `${this.name.name} has unused export property '${specifier.exported.name}'. If it is for external reference only, please consider using \`export const ${specifier.exported.name}\``
});
}
@ -544,7 +544,7 @@ export default class Component {
if (name[0] === '$') {
this.error(node as any, {
code: 'illegal-declaration',
message: `The $ prefix is reserved, and cannot be used for variable and import names`
message: 'The $ prefix is reserved, and cannot be used for variable and import names'
});
}
@ -562,7 +562,7 @@ export default class Component {
if (name[0] === '$') {
this.error(node as any, {
code: 'illegal-subscription',
message: `Cannot reference store value inside <script context="module">`
message: 'Cannot reference store value inside <script context="module">'
});
} else {
this.add_var({
@ -623,7 +623,7 @@ export default class Component {
if (name[0] === '$') {
this.error(node as any, {
code: 'illegal-declaration',
message: `The $ prefix is reserved, and cannot be used for variable and import names`
message: 'The $ prefix is reserved, and cannot be used for variable and import names'
});
}
@ -859,8 +859,8 @@ export default class Component {
if (name[1] !== '$' && scope.has(name.slice(1)) && scope.find_owner(name.slice(1)) !== this.instance_scope) {
this.error(node, {
code: `contextual-store`,
message: `Stores must be declared at the top level of the component (this may change in a future version of Svelte)`
code: 'contextual-store',
message: 'Stores must be declared at the top level of the component (this may change in a future version of Svelte)'
});
}
}
@ -927,7 +927,7 @@ export default class Component {
// TODO is this still true post-#3539?
component.error(declarator as any, {
code: 'destructured-prop',
message: `Cannot declare props in destructured declaration`
message: 'Cannot declare props in destructured declaration'
});
}
@ -1371,7 +1371,7 @@ function process_component_options(component: Component, nodes) {
switch (name) {
case 'tag': {
const code = 'invalid-tag-attribute';
const message = `'tag' must be a string literal`;
const message = '\'tag\' must be a string literal';
const tag = get_value(attribute, code, message);
if (typeof tag !== 'string' && tag !== null)
@ -1379,15 +1379,15 @@ function process_component_options(component: Component, nodes) {
if (tag && !/^[a-zA-Z][a-zA-Z0-9]*-[a-zA-Z0-9-]+$/.test(tag)) {
component.error(attribute, {
code: `invalid-tag-property`,
message: `tag name must be two or more words joined by the '-' character`
code: 'invalid-tag-property',
message: 'tag name must be two or more words joined by the \'-\' character'
});
}
if (tag && !component.compile_options.customElement) {
component.warn(attribute, {
code: 'missing-custom-element-compile-options',
message: `The 'tag' option is used when generating a custom element. Did you forget the 'customElement: true' compile option?`
message: 'The \'tag\' option is used when generating a custom element. Did you forget the \'customElement: true\' compile option?'
});
}
@ -1397,7 +1397,7 @@ function process_component_options(component: Component, nodes) {
case 'namespace': {
const code = 'invalid-namespace-attribute';
const message = `The 'namespace' attribute must be a string literal representing a valid namespace`;
const message = 'The \'namespace\' attribute must be a string literal representing a valid namespace';
const ns = get_value(attribute, code, message);
if (typeof ns !== 'string')
@ -1407,12 +1407,12 @@ function process_component_options(component: Component, nodes) {
const match = fuzzymatch(ns, valid_namespaces);
if (match) {
component.error(attribute, {
code: `invalid-namespace-property`,
code: 'invalid-namespace-property',
message: `Invalid namespace '${ns}' (did you mean '${match}'?)`
});
} else {
component.error(attribute, {
code: `invalid-namespace-property`,
code: 'invalid-namespace-property',
message: `Invalid namespace '${ns}'`
});
}
@ -1438,14 +1438,14 @@ function process_component_options(component: Component, nodes) {
default:
component.error(attribute, {
code: `invalid-options-attribute`,
message: `<svelte:options> unknown attribute`
code: 'invalid-options-attribute',
message: '<svelte:options> unknown attribute'
});
}
} else {
component.error(attribute, {
code: `invalid-options-attribute`,
message: `<svelte:options> can only have static 'tag', 'namespace', 'accessors', 'immutable' and 'preserveWhitespace' attributes`
code: 'invalid-options-attribute',
message: '<svelte:options> can only have static \'tag\', \'namespace\', \'accessors\', \'immutable\' and \'preserveWhitespace\' attributes'
});
}
});

@ -110,8 +110,8 @@ export default class Selector {
const selector = block.selectors[i];
if (selector.type === 'PseudoClassSelector' && selector.name === 'global') {
component.error(selector, {
code: `css-invalid-global`,
message: `:global(...) must be the first element in a compound selector`
code: 'css-invalid-global',
message: ':global(...) must be the first element in a compound selector'
});
}
}
@ -131,8 +131,8 @@ export default class Selector {
for (let i = start; i < end; i += 1) {
if (this.blocks[i].global) {
component.error(this.blocks[i].selectors[0], {
code: `css-invalid-global`,
message: `:global(...) can be at the start or end of a selector sequence, but not in the middle`
code: 'css-invalid-global',
message: ':global(...) can be at the start or end of a selector sequence, but not in the middle'
});
}
}
@ -267,7 +267,7 @@ function test_attribute(operator, expected_value, case_insensitive, value) {
case '^=': return value.startsWith(expected_value);
case '$=': return value.endsWith(expected_value);
case '*=': return value.includes(expected_value);
default: throw new Error(`this shouldn't happen`);
default: throw new Error('this shouldn\'t happen');
}
}
@ -370,7 +370,7 @@ function attribute_matches(node: CssNode, name: string, expected_value: string,
function unquote(value: CssNode) {
if (value.type === 'Identifier') return value.name;
const str = value.value;
if (str[0] === str[str.length - 1] && str[0] === "'" || str[0] === '"') {
if (str[0] === str[str.length - 1] && str[0] === '\'' || str[0] === '"') {
return str.slice(1, str.length - 1);
}
return str;

@ -5,7 +5,7 @@ import Element from '../nodes/Element';
import { Ast, TemplateNode } from '../../interfaces';
import Component from '../Component';
import { CssNode } from './interfaces';
import hash from "../utils/hash";
import hash from '../utils/hash';
function remove_css_prefix(name: string): string {
return name.replace(/^-((webkit)|(moz)|(o)|(ms))-/, '');
@ -434,7 +434,7 @@ export default class Stylesheet {
this.children.forEach(child => {
child.warn_on_unused_selector((selector: Selector) => {
component.warn(selector.node, {
code: `css-unused-selector`,
code: 'css-unused-selector',
message: `Unused CSS selector "${this.source.slice(selector.node.start, selector.node.end)}"`
});
});

@ -47,9 +47,9 @@ function validate_options(options: CompileOptions, warnings: Warning[]) {
}
if (name && /^[a-z]/.test(name)) {
const message = `options.name should be capitalised`;
const message = 'options.name should be capitalised';
warnings.push({
code: `options-lowercase-name`,
code: 'options-lowercase-name',
message,
filename,
toString: () => message
@ -59,7 +59,7 @@ function validate_options(options: CompileOptions, warnings: Warning[]) {
if (loopGuardTimeout && !dev) {
const message = 'options.loopGuardTimeout is for options.dev = true only';
warnings.push({
code: `options-loop-guard-timeout`,
code: 'options-loop-guard-timeout',
message,
filename,
toString: () => message

@ -17,8 +17,8 @@ export default class Animation extends Node {
if (parent.animation) {
component.error(this, {
code: `duplicate-animation`,
message: `An element can only have one 'animate' directive`
code: 'duplicate-animation',
message: 'An element can only have one \'animate\' directive'
});
}
@ -26,8 +26,8 @@ export default class Animation extends Node {
if (!block || block.type !== 'EachBlock' || !block.key) {
// TODO can we relax the 'immediate child' rule?
component.error(this, {
code: `invalid-animation`,
message: `An element that use the animate directive must be the immediate child of a keyed each block`
code: 'invalid-animation',
message: 'An element that use the animate directive must be the immediate child of a keyed each block'
});
}

@ -3,7 +3,7 @@ import get_object from '../utils/get_object';
import Expression from './shared/Expression';
import Component from '../Component';
import TemplateScope from './shared/TemplateScope';
import {dimensions} from "../../utils/patterns";
import {dimensions} from '../../utils/patterns';
import { Node as ESTreeNode } from 'estree';
// TODO this should live in a specific binding

@ -60,8 +60,8 @@ export default class EachBlock extends AbstractBlock {
if (this.children.length !== 1) {
const child = this.children.find(child => !!(child as Element).animation);
component.error((child as Element).animation, {
code: `invalid-animation`,
message: `An element that use the animate directive must be the sole child of a keyed each block`
code: 'invalid-animation',
message: 'An element that use the animate directive must be the sole child of a keyed each block'
});
}
}

@ -62,14 +62,14 @@ const a11y_no_onchange = new Set([
]);
const a11y_labelable = new Set([
"button",
"input",
"keygen",
"meter",
"output",
"progress",
"select",
"textarea"
'button',
'input',
'keygen',
'meter',
'output',
'progress',
'select',
'textarea'
]);
const invisible_elements = new Set(['meta', 'html', 'script', 'style']);
@ -134,8 +134,8 @@ export default class Element extends Node {
const value_attribute = info.attributes.find(node => node.name === 'value');
if (value_attribute) {
component.error(value_attribute, {
code: `textarea-duplicate-value`,
message: `A <textarea> can have either a value attribute or (equivalently) child content, but not both`
code: 'textarea-duplicate-value',
message: 'A <textarea> can have either a value attribute or (equivalently) child content, but not both'
});
}
@ -242,7 +242,7 @@ export default class Element extends Node {
if (a11y_distracting_elements.has(this.name)) {
// no-distracting-elements
this.component.warn(this, {
code: `a11y-distracting-elements`,
code: 'a11y-distracting-elements',
message: `A11y: Avoid <${this.name}> elements`
});
}
@ -264,8 +264,8 @@ export default class Element extends Node {
if (!is_figure_parent) {
this.component.warn(this, {
code: `a11y-structure`,
message: `A11y: <figcaption> must be an immediate child of <figure>`
code: 'a11y-structure',
message: 'A11y: <figcaption> must be an immediate child of <figure>'
});
}
}
@ -281,8 +281,8 @@ export default class Element extends Node {
if (index !== -1 && (index !== 0 && index !== children.length - 1)) {
this.component.warn(children[index], {
code: `a11y-structure`,
message: `A11y: <figcaption> must be first or last child of <figure>`
code: 'a11y-structure',
message: 'A11y: <figcaption> must be first or last child of <figure>'
});
}
}
@ -309,7 +309,7 @@ export default class Element extends Node {
if (invisible_elements.has(this.name)) {
// aria-unsupported-elements
component.warn(attribute, {
code: `a11y-aria-attributes`,
code: 'a11y-aria-attributes',
message: `A11y: <${this.name}> should not have aria-* attributes`
});
}
@ -321,14 +321,14 @@ export default class Element extends Node {
if (match) message += ` (did you mean '${match}'?)`;
component.warn(attribute, {
code: `a11y-unknown-aria-attribute`,
code: 'a11y-unknown-aria-attribute',
message
});
}
if (name === 'aria-hidden' && /^h[1-6]$/.test(this.name)) {
component.warn(attribute, {
code: `a11y-hidden`,
code: 'a11y-hidden',
message: `A11y: <${this.name}> element should not be hidden`
});
}
@ -339,7 +339,7 @@ export default class Element extends Node {
if (invisible_elements.has(this.name)) {
// aria-unsupported-elements
component.warn(attribute, {
code: `a11y-misplaced-role`,
code: 'a11y-misplaced-role',
message: `A11y: <${this.name}> should not have role attribute`
});
}
@ -353,7 +353,7 @@ export default class Element extends Node {
if (match) message += ` (did you mean '${match}'?)`;
component.warn(attribute, {
code: `a11y-unknown-role`,
code: 'a11y-unknown-role',
message
});
}
@ -362,24 +362,24 @@ export default class Element extends Node {
// no-access-key
if (name === 'accesskey') {
component.warn(attribute, {
code: `a11y-accesskey`,
message: `A11y: Avoid using accesskey`
code: 'a11y-accesskey',
message: 'A11y: Avoid using accesskey'
});
}
// no-autofocus
if (name === 'autofocus') {
component.warn(attribute, {
code: `a11y-autofocus`,
message: `A11y: Avoid using autofocus`
code: 'a11y-autofocus',
message: 'A11y: Avoid using autofocus'
});
}
// scope
if (name === 'scope' && this.name !== 'th') {
component.warn(attribute, {
code: `a11y-misplaced-scope`,
message: `A11y: The scope attribute should only be used with <th> elements`
code: 'a11y-misplaced-scope',
message: 'A11y: The scope attribute should only be used with <th> elements'
});
}
@ -389,8 +389,8 @@ export default class Element extends Node {
// @ts-ignore todo is tabindex=true correct case?
if (!isNaN(value) && +value > 0) {
component.warn(attribute, {
code: `a11y-positive-tabindex`,
message: `A11y: avoid tabindex values above zero`
code: 'a11y-positive-tabindex',
message: 'A11y: avoid tabindex values above zero'
});
}
}
@ -398,7 +398,7 @@ export default class Element extends Node {
if (/(^[0-9-.])|[\^$@%&#?!|()[\]{}^*+~;]/.test(name)) {
component.error(attribute, {
code: `illegal-attribute`,
code: 'illegal-attribute',
message: `'${name}' is not a valid attribute name`
});
}
@ -406,14 +406,14 @@ export default class Element extends Node {
if (name === 'slot') {
if (!attribute.is_static) {
component.error(attribute, {
code: `invalid-slot-attribute`,
message: `slot attribute cannot have a dynamic value`
code: 'invalid-slot-attribute',
message: 'slot attribute cannot have a dynamic value'
});
}
if (component.slot_outlets.has(name)) {
component.error(attribute, {
code: `duplicate-slot-attribute`,
code: 'duplicate-slot-attribute',
message: `Duplicate '${name}' slot`
});
@ -422,8 +422,8 @@ export default class Element extends Node {
if (!(parent.type === 'InlineComponent' || within_custom_element(parent))) {
component.error(attribute, {
code: `invalid-slotted-content`,
message: `Element with a slot='...' attribute must be a child of a component or a descendant of a custom element`
code: 'invalid-slotted-content',
message: 'Element with a slot=\'...\' attribute must be a child of a component or a descendant of a custom element'
});
}
}
@ -431,7 +431,7 @@ 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`
message: 'The \'is\' attribute is not supported cross-browser and should be avoided'
});
}
@ -462,7 +462,7 @@ export default class Element extends Node {
if (href_value === '' || href_value === '#' || /^\W*javascript:/i.test(href_value)) {
component.warn(href_attribute, {
code: `a11y-invalid-attribute`,
code: 'a11y-invalid-attribute',
message: `A11y: '${href_value}' is not a valid ${href_attribute.name} attribute`
});
}
@ -472,8 +472,8 @@ export default class Element extends Node {
if (!id_attribute_valid && !name_attribute_valid) {
component.warn(this, {
code: `a11y-missing-attribute`,
message: `A11y: <a> element should have an href attribute`
code: 'a11y-missing-attribute',
message: 'A11y: <a> element should have an href attribute'
});
}
}
@ -511,8 +511,8 @@ export default class Element extends Node {
if (/\b(image|picture|photo)\b/i.test(alt_value)) {
component.warn(this, {
code: `a11y-img-redundant-alt`,
message: `A11y: Screenreaders already announce <img> elements as an image.`
code: 'a11y-img-redundant-alt',
message: 'A11y: Screenreaders already announce <img> elements as an image.'
});
}
}
@ -522,8 +522,8 @@ export default class Element extends Node {
const has_input_child = this.children.some(i => (i instanceof Element && a11y_labelable.has(i.name) ));
if (!attribute_map.has('for') && !has_input_child) {
component.warn(this, {
code: `a11y-label-has-associated-control`,
message: `A11y: A form label must be associated with a control.`
code: 'a11y-label-has-associated-control',
message: 'A11y: A form label must be associated with a control.'
});
}
}
@ -541,8 +541,8 @@ export default class Element extends Node {
if (!has_caption) {
component.warn(this, {
code: `a11y-media-has-caption`,
message: `A11y: Media elements must have a <track kind="captions">`
code: 'a11y-media-has-caption',
message: 'A11y: Media elements must have a <track kind="captions">'
});
}
}
@ -550,8 +550,8 @@ export default class Element extends Node {
if (a11y_no_onchange.has(this.name)) {
if (handlers_map.has('change') && !handlers_map.has('blur')) {
component.warn(this, {
code: `a11y-no-onchange`,
message: `A11y: on:blur must be used instead of on:change, unless absolutely necessary and it causes no negative consequences for keyboard only or screen reader users.`
code: 'a11y-no-onchange',
message: 'A11y: on:blur must be used instead of on:change, unless absolutely necessary and it causes no negative consequences for keyboard only or screen reader users.'
});
}
}
@ -569,8 +569,8 @@ export default class Element extends Node {
if (!attribute.is_static) {
component.error(attribute, {
code: `invalid-type`,
message: `'type' attribute cannot be dynamic if input uses two-way binding`
code: 'invalid-type',
message: '\'type\' attribute cannot be dynamic if input uses two-way binding'
});
}
@ -578,8 +578,8 @@ export default class Element extends Node {
if (value === true) {
component.error(attribute, {
code: `missing-type`,
message: `'type' attribute must be specified`
code: 'missing-type',
message: '\'type\' attribute must be specified'
});
}
@ -596,7 +596,7 @@ export default class Element extends Node {
this.name !== 'select'
) {
component.error(binding, {
code: `invalid-binding`,
code: 'invalid-binding',
message: `'value' is not a valid binding on <${this.name}> elements`
});
}
@ -608,8 +608,8 @@ export default class Element extends Node {
if (attribute && !attribute.is_static) {
component.error(attribute, {
code: `dynamic-multiple-attribute`,
message: `'multiple' attribute cannot be dynamic if select uses two-way binding`
code: 'dynamic-multiple-attribute',
message: '\'multiple\' attribute cannot be dynamic if select uses two-way binding'
});
}
} else {
@ -618,7 +618,7 @@ export default class Element extends Node {
} else if (name === 'checked' || name === 'indeterminate') {
if (this.name !== 'input') {
component.error(binding, {
code: `invalid-binding`,
code: 'invalid-binding',
message: `'${name}' is not a valid binding on <${this.name}> elements`
});
}
@ -627,13 +627,13 @@ export default class Element extends Node {
if (type !== 'checkbox') {
let message = `'${name}' binding can only be used with <input type="checkbox">`;
if (type === 'radio') message += ` — for <input type="radio">, use 'group' binding`;
component.error(binding, { code: `invalid-binding`, message });
if (type === 'radio') message += ' — for <input type="radio">, use \'group\' binding';
component.error(binding, { code: 'invalid-binding', message });
}
} else if (name === 'group') {
if (this.name !== 'input') {
component.error(binding, {
code: `invalid-binding`,
code: 'invalid-binding',
message: `'group' is not a valid binding on <${this.name}> elements`
});
}
@ -642,14 +642,14 @@ export default class Element extends Node {
if (type !== 'checkbox' && type !== 'radio') {
component.error(binding, {
code: `invalid-binding`,
message: `'group' binding can only be used with <input type="checkbox"> or <input type="radio">`
code: 'invalid-binding',
message: '\'group\' binding can only be used with <input type="checkbox"> or <input type="radio">'
});
}
} else if (name === 'files') {
if (this.name !== 'input') {
component.error(binding, {
code: `invalid-binding`,
code: 'invalid-binding',
message: `'files' is not a valid binding on <${this.name}> elements`
});
}
@ -658,15 +658,15 @@ export default class Element extends Node {
if (type !== 'file') {
component.error(binding, {
code: `invalid-binding`,
message: `'files' binding can only be used with <input type="file">`
code: 'invalid-binding',
message: '\'files\' binding can only be used with <input type="file">'
});
}
} else if (name === 'open') {
if (this.name !== 'details') {
component.error(binding, {
code: `invalid-binding`,
code: 'invalid-binding',
message: `'${name}' binding can only be used with <details>`
});
}
@ -685,7 +685,7 @@ export default class Element extends Node {
) {
if (this.name !== 'audio' && this.name !== 'video') {
component.error(binding, {
code: `invalid-binding`,
code: 'invalid-binding',
message: `'${name}' binding can only be used with <audio> or <video>`
});
}
@ -695,7 +695,7 @@ export default class Element extends Node {
) {
if (this.name !== 'video') {
component.error(binding, {
code: `invalid-binding`,
code: 'invalid-binding',
message: `'${name}' binding can only be used with <video>`
});
}
@ -726,18 +726,18 @@ export default class Element extends Node {
if (!contenteditable) {
component.error(binding, {
code: `missing-contenteditable-attribute`,
message: `'contenteditable' attribute is required for textContent and innerHTML two-way bindings`
code: 'missing-contenteditable-attribute',
message: '\'contenteditable\' attribute is required for textContent and innerHTML two-way bindings'
});
} else if (contenteditable && !contenteditable.is_static) {
component.error(contenteditable, {
code: `dynamic-contenteditable-attribute`,
message: `'contenteditable' attribute cannot be dynamic if element uses two-way binding`
code: 'dynamic-contenteditable-attribute',
message: '\'contenteditable\' attribute cannot be dynamic if element uses two-way binding'
});
}
} else if (name !== 'this') {
component.error(binding, {
code: `invalid-binding`,
code: 'invalid-binding',
message: `'${binding.name}' is not a valid binding`
});
}
@ -753,7 +753,7 @@ export default class Element extends Node {
if (this.children.length === 0) {
this.component.warn(this, {
code: `a11y-missing-content`,
code: 'a11y-missing-content',
message: `A11y: <${this.name}> element should have child content`
});
}
@ -766,7 +766,7 @@ export default class Element extends Node {
if (handler.modifiers.has('passive') && handler.modifiers.has('preventDefault')) {
component.error(handler, {
code: 'invalid-event-modifier',
message: `The 'passive' and 'preventDefault' modifiers cannot be used together`
message: 'The \'passive\' and \'preventDefault\' modifiers cannot be used together'
});
}
@ -783,13 +783,13 @@ export default class Element extends Node {
if (handler.can_make_passive) {
component.warn(handler, {
code: 'redundant-event-modifier',
message: `Touch event handlers that don't use the 'event' object are passive by default`
message: 'Touch event handlers that don\'t use the \'event\' object are passive by default'
});
}
} else {
component.warn(handler, {
code: 'redundant-event-modifier',
message: `The passive modifier only works with wheel and touch events`
message: 'The passive modifier only works with wheel and touch events'
});
}
}
@ -860,7 +860,7 @@ function should_have_attribute(
attributes[0];
node.component.warn(node, {
code: `a11y-missing-attribute`,
code: 'a11y-missing-attribute',
message: `A11y: <${name}> element should have ${article} ${sequence} attribute`
});
}

@ -12,8 +12,8 @@ export default class Head extends Node {
if (info.attributes.length) {
component.error(info.attributes[0], {
code: `invalid-attribute`,
message: `<svelte:head> should not have any attributes or directives`
code: 'invalid-attribute',
message: '<svelte:head> should not have any attributes or directives'
});
}

@ -40,15 +40,15 @@ export default class InlineComponent extends Node {
switch (node.type) {
case 'Action':
component.error(node, {
code: `invalid-action`,
message: `Actions can only be applied to DOM elements, not components`
code: 'invalid-action',
message: 'Actions can only be applied to DOM elements, not components'
});
case 'Attribute':
if (node.name === 'slot') {
component.error(node, {
code: `invalid-prop`,
message: `'slot' is reserved for future use in named slots`
code: 'invalid-prop',
message: '\'slot\' is reserved for future use in named slots'
});
}
// fallthrough
@ -62,8 +62,8 @@ export default class InlineComponent extends Node {
case 'Class':
component.error(node, {
code: `invalid-class`,
message: `Classes can only be applied to DOM elements, not components`
code: 'invalid-class',
message: 'Classes can only be applied to DOM elements, not components'
});
case 'EventHandler':
@ -76,8 +76,8 @@ export default class InlineComponent extends Node {
case 'Transition':
component.error(node, {
code: `invalid-transition`,
message: `Transitions can only be applied to DOM elements, not components`
code: 'invalid-transition',
message: 'Transitions can only be applied to DOM elements, not components'
});
default:
@ -105,7 +105,7 @@ export default class InlineComponent extends Node {
if (modifier !== 'once') {
component.error(handler, {
code: 'invalid-event-modifier',
message: `Event modifiers other than 'once' can only be used on DOM elements`
message: 'Event modifiers other than \'once\' can only be used on DOM elements'
});
}
});

@ -26,7 +26,7 @@ export default class Let extends Node {
if (!applicable.has(node.type)) {
component.error(node as any, {
code: 'invalid-let',
message: `let directive value must be an identifier or an object/array pattern`
message: 'let directive value must be an identifier or an object/array pattern'
});
}

@ -17,24 +17,24 @@ export default class Slot extends Element {
info.attributes.forEach(attr => {
if (attr.type !== 'Attribute') {
component.error(attr, {
code: `invalid-slot-directive`,
message: `<slot> cannot have directives`
code: 'invalid-slot-directive',
message: '<slot> cannot have directives'
});
}
if (attr.name === 'name') {
if (attr.value.length !== 1 || attr.value[0].type !== 'Text') {
component.error(attr, {
code: `dynamic-slot-name`,
message: `<slot> name cannot be dynamic`
code: 'dynamic-slot-name',
message: '<slot> name cannot be dynamic'
});
}
this.slot_name = attr.value[0].data;
if (this.slot_name === 'default') {
component.error(attr, {
code: `invalid-slot-name`,
message: `default is a reserved word — it cannot be used as a slot name`
code: 'invalid-slot-name',
message: 'default is a reserved word — it cannot be used as a slot name'
});
}
}

@ -37,7 +37,7 @@ export default class Text extends Node {
// svg namespace exclusions
if (/svg$/.test(parent_element.namespace)) {
if (this.prev && this.prev.type === "Element" && this.prev.name === "tspan") return false;
if (this.prev && this.prev.type === 'Element' && this.prev.name === 'tspan') return false;
}
return parent_element.namespace || elements_without_text.has(parent_element.name);

@ -13,8 +13,8 @@ export default class Title extends Node {
if (info.attributes.length > 0) {
component.error(info.attributes[0], {
code: `illegal-attribute`,
message: `<title> cannot have attributes`
code: 'illegal-attribute',
message: '<title> cannot have attributes'
});
}
@ -22,7 +22,7 @@ export default class Title extends Node {
if (child.type !== 'Text' && child.type !== 'MustacheTag') {
component.error(child, {
code: 'illegal-structure',
message: `<title> can only contain text and {tags}`
message: '<title> can only contain text and {tags}'
});
}
});

@ -28,7 +28,7 @@ export default class Transition extends Node {
: `An element cannot have both ${describe(parent_transition)} directive and ${describe(this)} directive`;
component.error(info, {
code: `duplicate-transition`,
code: 'duplicate-transition',
message
});
}
@ -41,6 +41,6 @@ export default class Transition extends Node {
function describe(transition: Transition) {
return transition.directive === 'transition'
? `a 'transition'`
? 'a \'transition\''
: `an '${transition.directive}'`;
}

@ -36,7 +36,7 @@ export default class Window extends Node {
// TODO is this constraint necessary?
component.error(node.expression, {
code: `invalid-binding`,
code: 'invalid-binding',
message: `Bindings on <svelte:window> must be to top-level properties, e.g. '${parts[parts.length - 1]}' rather than '${parts.join('.')}'`
});
}
@ -52,12 +52,12 @@ export default class Window extends Node {
if (match) {
component.error(node, {
code: `invalid-binding`,
code: 'invalid-binding',
message: `${message} (did you mean '${match}'?)`
});
} else {
component.error(node, {
code: `invalid-binding`,
code: 'invalid-binding',
message: `${message} — valid bindings are ${list(valid_bindings)}`
});
}

@ -85,8 +85,8 @@ export default class Expression {
const store_name = name.slice(1);
if (template_scope.names.has(store_name) || scope.has(store_name)) {
component.error(node, {
code: `contextual-store`,
message: `Stores must be declared at the top level of the component (this may change in a future version of Svelte)`
code: 'contextual-store',
message: 'Stores must be declared at the top level of the component (this may change in a future version of Svelte)'
});
}
}

@ -235,7 +235,7 @@ export default class Renderer {
if (!member) return;
if (member.index.value === -1) {
throw new Error(`unset index`);
throw new Error('unset index');
}
const value = member.index.value as number;

@ -81,7 +81,7 @@ export default function dom(
const uses_props = component.var_lookup.has('$$props');
const uses_rest = component.var_lookup.has('$$restProps');
const $$props = uses_props || uses_rest ? `$$new_props` : `$$props`;
const $$props = uses_props || uses_rest ? '$$new_props' : '$$props';
const props = component.vars.filter(variable => !variable.module && variable.export_name);
const writable_props = props.filter(variable => variable.writable);
@ -524,7 +524,7 @@ export default function dom(
const declaration = b`
class ${name} extends ${superclass} {
constructor(options) {
super(${options.dev && `options`});
super(${options.dev && 'options'});
${should_add_css && b`if (!@_document.getElementById("${component.stylesheet.id}-style")) ${add_css}();`}
@init(this, options, ${definition}, ${has_create_fragment ? 'create_fragment': 'null'}, ${not_equal}, ${prop_indexes}, ${dirty});
${options.dev && b`@dispatch_dev("SvelteRegisterComponent", { component: this, tagName: "${name.name}", options, id: create_fragment.name });`}

@ -177,8 +177,8 @@ export default class AwaitBlockWrapper extends Wrapper {
const snippet = this.node.expression.manipulate(block);
const info = block.get_unique_name(`info`);
const promise = block.get_unique_name(`promise`);
const info = block.get_unique_name('info');
const promise = block.get_unique_name('promise');
block.add_variable(promise);

@ -29,7 +29,7 @@ export class ElseBlockWrapper extends Wrapper {
this.block = block.child({
comment: create_debugging_comment(node, this.renderer.component),
name: this.renderer.component.get_unique_name(`create_else_block`),
name: this.renderer.component.get_unique_name('create_else_block'),
type: 'else'
});
@ -436,11 +436,11 @@ export default class EachBlockWrapper extends Wrapper {
const destroy = this.node.has_animation
? (this.block.has_outros
? `@fix_and_outro_and_destroy_block`
: `@fix_and_destroy_block`)
? '@fix_and_outro_and_destroy_block'
: '@fix_and_destroy_block')
: this.block.has_outros
? `@outro_and_destroy_block`
: `@destroy_block`;
? '@outro_and_destroy_block'
: '@destroy_block';
if (this.dependencies.size) {
this.updates.push(b`
@ -558,7 +558,7 @@ export default class EachBlockWrapper extends Wrapper {
}
`;
const start = this.block.has_update_method ? 0 : `#old_length`;
const start = this.block.has_update_method ? 0 : '#old_length';
let remove_old_blocks;

@ -187,7 +187,7 @@ export default class AttributeWrapper extends BaseAttributeWrapper {
if (this.is_input_value) {
const type = element.node.get_static_attribute_value('type');
if (type === null || type === "" || type === "text" || type === "email" || type === "password") {
if (type === null || type === '' || type === 'text' || type === 'email' || type === 'password') {
condition = x`${condition} && ${element.var}.${property_name} !== ${should_cache ? last : value}`;
}
}
@ -277,7 +277,7 @@ export default class AttributeWrapper extends BaseAttributeWrapper {
if (this.node.is_true) return '';
const value = this.node.chunks;
if (value.length === 0) return `=""`;
if (value.length === 0) return '=""';
return `="${value.map(chunk => {
return chunk.type === 'Text'

@ -88,20 +88,20 @@ export default class BindingWrapper {
update_conditions.push(block.renderer.dirty(dependency_array));
}
if (parent.node.name === "input") {
const type = parent.node.get_static_attribute_value("type");
if (parent.node.name === 'input') {
const type = parent.node.get_static_attribute_value('type');
if (
type === null ||
type === "" ||
type === "text" ||
type === "email" ||
type === "password"
type === '' ||
type === 'text' ||
type === 'email' ||
type === 'password'
) {
update_conditions.push(
x`${parent.var}.${this.node.name} !== ${this.snippet}`
);
} else if (type === "number") {
} else if (type === 'number') {
update_conditions.push(
x`@to_number(${parent.var}.${this.node.name}) !== ${this.snippet}`
);
@ -118,7 +118,7 @@ export default class BindingWrapper {
{
const { binding_group, is_context, contexts, index } = get_binding_group(parent.renderer, this.node, block);
block.renderer.add_to_context(`$$binding_groups`);
block.renderer.add_to_context('$$binding_groups');
if (is_context) {
if (contexts.length > 1) {

@ -1,3 +1,3 @@
import { BaseAttributeWrapper } from "./Attribute";
import { BaseAttributeWrapper } from './Attribute';
export default class SpreadAttributeWrapper extends BaseAttributeWrapper {}

@ -128,7 +128,7 @@ function get_style_value(chunks: Array<Text | Expression>) {
escaped = true;
} else if (char === quote_mark) {
quote_mark = null;
} else if (char === '"' || char === "'") {
} else if (char === '"' || char === '\'') {
quote_mark = char;
} else if (char === ')' && in_url) {
in_url = false;

@ -1,13 +1,13 @@
import AttributeWrapper from "./Attribute";
import BindingWrapper from "./Binding";
import ElementWrapper from "./index";
import AttributeWrapper from './Attribute';
import BindingWrapper from './Binding';
import ElementWrapper from './index';
export default function handle_select_value_binding(
attr: AttributeWrapper | BindingWrapper,
dependencies: Set<string>
) {
const { parent } = attr;
if (parent.node.name === "select") {
if (parent.node.name === 'select') {
(parent as ElementWrapper).select_binding_dependencies = dependencies;
dependencies.forEach((prop: string) => {
parent.renderer.component.indirect_dependencies.set(prop, new Set());

@ -727,7 +727,7 @@ export default class ElementWrapper extends Wrapper {
`);
} else if (this.node.name === 'input' && this.attributes.find(attr => attr.node.name === 'value')) {
const type = this.node.get_static_attribute_value('type');
if (type === null || type === "" || type === "text" || type === "email" || type === "password") {
if (type === null || type === '' || type === 'text' || type === 'email' || type === 'password') {
block.chunks.mount.push(b`
${this.var}.value = ${data}.value;
`);
@ -998,7 +998,7 @@ function to_html(wrappers: Array<ElementWrapper | TextWrapper | MustacheTagWrapp
}
});
state.quasi.value.raw += `"`;
state.quasi.value.raw += '"';
});
if (!wrapper.void) {

@ -67,7 +67,7 @@ export default class FragmentWrapper {
const child = nodes[i];
if (!child.type) {
throw new Error(`missing type`);
throw new Error('missing type');
}
if (!(child.type in wrappers)) {

@ -55,7 +55,7 @@ class IfBlockBranch extends Wrapper {
});
if (should_cache) {
this.condition = block.get_unique_name(`show_if`);
this.condition = block.get_unique_name('show_if');
this.snippet = (expression.manipulate(block) as Node);
} else {
this.condition = expression.manipulate(block);
@ -65,7 +65,7 @@ class IfBlockBranch extends Wrapper {
this.block = block.child({
comment: create_debugging_comment(node, parent.renderer.component),
name: parent.renderer.component.get_unique_name(
is_else ? `create_else_block` : `create_if_block`
is_else ? 'create_else_block' : 'create_if_block'
),
type: (node as IfBlock).expression ? 'if' : 'else'
});
@ -257,8 +257,8 @@ export default class IfBlockWrapper extends Wrapper {
{ name, anchor, has_else, if_exists_condition, has_transitions },
detaching
) {
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 select_block_type = this.renderer.component.get_unique_name('select_block_type');
const current_block_type = block.get_unique_name('current_block_type');
const get_block = has_else
? x`${current_block_type}(#ctx)`
: x`${current_block_type} && ${current_block_type}(#ctx)`;
@ -364,11 +364,11 @@ export default class IfBlockWrapper extends Wrapper {
{ name, anchor, has_else, has_transitions, if_exists_condition },
detaching
) {
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 previous_block_index = block.get_unique_name(`previous_block_index`);
const if_block_creators = block.get_unique_name(`if_block_creators`);
const if_blocks = block.get_unique_name(`if_blocks`);
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 previous_block_index = block.get_unique_name('previous_block_index');
const if_block_creators = block.get_unique_name('if_block_creators');
const if_blocks = block.get_unique_name('if_blocks');
const if_current_block_type_index = has_else
? nodes => nodes

@ -78,7 +78,7 @@ export default class InlineComponentWrapper extends Wrapper {
const default_slot = block.child({
comment: create_debugging_comment(node, renderer.component),
name: renderer.component.get_unique_name(`create_default_slot`),
name: renderer.component.get_unique_name('create_default_slot'),
type: 'slot'
});

@ -36,7 +36,7 @@ export default class SlotWrapper extends Wrapper {
if (this.node.children.length) {
this.fallback = block.child({
comment: create_debugging_comment(this.node.children[0], this.renderer.component),
name: this.renderer.component.get_unique_name(`fallback_block`),
name: this.renderer.component.get_unique_name('fallback_block'),
type: 'fallback'
});
renderer.blocks.push(this.fallback);

@ -59,7 +59,7 @@ export default class TitleWrapper extends Wrapper {
}
const last = this.node.should_cache && block.get_unique_name(
`title_value`
'title_value'
);
if (this.node.should_cache) block.add_variable(last);

@ -72,9 +72,9 @@ export default class WindowWrapper extends Wrapper {
});
});
const scrolling = block.get_unique_name(`scrolling`);
const clear_scrolling = block.get_unique_name(`clear_scrolling`);
const scrolling_timeout = block.get_unique_name(`scrolling_timeout`);
const scrolling = block.get_unique_name('scrolling');
const clear_scrolling = block.get_unique_name('clear_scrolling');
const scrolling_timeout = block.get_unique_name('scrolling_timeout');
Object.keys(events).forEach(event => {
const id = block.get_unique_name(`onwindow${event}`);
@ -156,7 +156,7 @@ export default class WindowWrapper extends Wrapper {
// another special case. (I'm starting to think these are all special cases.)
if (bindings.online) {
const id = block.get_unique_name(`onlinestatuschanged`);
const id = block.get_unique_name('onlinestatuschanged');
const name = bindings.online;
renderer.add_to_context(id.name);

@ -1,7 +1,7 @@
import EachBlock from "../../../nodes/EachBlock";
import InlineComponentWrapper from "../InlineComponent";
import ElementWrapper from "../Element";
import Binding from "../../../nodes/Binding";
import EachBlock from '../../../nodes/EachBlock';
import InlineComponentWrapper from '../InlineComponent';
import ElementWrapper from '../Element';
import Binding from '../../../nodes/Binding';
export default function mark_each_block_bindings(
parent: ElementWrapper | InlineComponentWrapper,
@ -16,7 +16,7 @@ export default function mark_each_block_bindings(
}
});
if (binding.name === "group") {
if (binding.name === 'group') {
// for `<input bind:group={} >`, we make sure that all the each blocks creates context with `index`
for (const name of binding.expression.contextual_dependencies) {
const each_block = parent.node.scope.get_owner(name);

@ -84,20 +84,20 @@ export default function(node: Element, renderer: Renderer, options: RenderOption
attribute.chunks[0].type !== 'Text'
) {
// a boolean attribute with one non-Text chunk
renderer.add_string(` `);
renderer.add_string(' ');
renderer.add_expression(x`${(attribute.chunks[0] as Expression).node} ? "${attribute.name}" : ""`);
} else if (name === 'class' && class_expression) {
add_class_attribute = false;
renderer.add_string(` ${attribute.name}="`);
renderer.add_expression(x`[${get_class_attribute_value(attribute)}, ${class_expression}].join(' ').trim()`);
renderer.add_string(`"`);
renderer.add_string('"');
} else if (attribute.chunks.length === 1 && attribute.chunks[0].type !== 'Text') {
const snippet = (attribute.chunks[0] as Expression).node;
renderer.add_expression(x`@add_attribute("${attribute.name}", ${snippet}, ${boolean_attributes.has(name) ? 1 : 0})`);
} else {
renderer.add_string(` ${attribute.name}="`);
renderer.add_expression((name === 'class' ? get_class_attribute_value : get_attribute_value)(attribute));
renderer.add_string(`"`);
renderer.add_string('"');
}
});
if (add_class_attribute) {

@ -104,6 +104,6 @@ function is_empty_template_literal(template_literal) {
return (
template_literal.expressions.length === 0 &&
template_literal.quasis.length === 1 &&
template_literal.quasis[0].value.raw === ""
template_literal.quasis[0].value.raw === ''
);
}

@ -5,11 +5,11 @@ import { x } from 'code-red';
export default function(node: Title, renderer: Renderer, options: RenderOptions) {
renderer.push();
renderer.add_string(`<title>`);
renderer.add_string('<title>');
renderer.render(node.children, options);
renderer.add_string(`</title>`);
renderer.add_string('</title>');
const result = renderer.pop();
renderer.add_expression(x`$$result.title = ${result}, ""`);

@ -1,13 +1,13 @@
import { Node, Literal, Identifier, MemberExpression } from "estree";
import { Node, Literal, Identifier, MemberExpression } from 'estree';
export function compare_node(a: Node | void, b: Node | void) {
if (a === b) return true;
if (!a || !b) return false;
if (a.type !== b.type) return false;
switch (a.type) {
case "Identifier":
case 'Identifier':
return a.name === (b as Identifier).name;
case "MemberExpression":
case 'MemberExpression':
return (
compare_node(a.object, (b as MemberExpression).object) &&
compare_node(a.property, (b as MemberExpression).property) &&

@ -13,7 +13,7 @@ export default function get_name_from_filename(filename: string) {
const base = parts.pop()
.replace(/%/g, 'u')
.replace(/\.[^.]+$/, "")
.replace(/\.[^.]+$/, '')
.replace(/[^a-zA-Z_$0-9]+/g, '_')
.replace(/^_/, '')
.replace(/_$/, '')

@ -1,6 +1,6 @@
// https://github.com/darkskyapp/string-hash/blob/master/index.js
export default function hash(str: string): string {
str = str.replace(/\r/g, "");
str = str.replace(/\r/g, '');
let hash = 5381;
let i = str.length;

@ -1,4 +1,4 @@
export const reserved_keywords = new Set(["$$props", "$$restProps", "$$slots"]);
export const reserved_keywords = new Set(['$$props', '$$restProps', '$$slots']);
export function is_reserved_keyword(name) {
return reserved_keywords.has(name);

@ -1,16 +1,16 @@
import { MemberExpression, Identifier } from "estree";
import { MemberExpression, Identifier } from 'estree';
export function string_to_member_expression(name: string) {
const parts = name.split(".");
const parts = name.split('.');
let node: MemberExpression | Identifier = {
type: "Identifier",
type: 'Identifier',
name: parts[0]
};
for (let i = 1; i < parts.length; i++) {
node = {
type: "MemberExpression",
type: 'MemberExpression',
object: node,
property: { type: "Identifier", name: parts[i] }
property: { type: 'Identifier', name: parts[i] }
} as MemberExpression;
}
return node;

@ -13,7 +13,7 @@ export function escape(data: string, { only_escape_at_symbol = false } = {}) {
const escaped = {
'"': '&quot;',
"'": '&#39;',
'\'': '&#39;',
'&': '&amp;',
'<': '&lt;',
'>': '&gt;'

@ -1,4 +1,4 @@
import { Node, Program } from "estree";
import { Node, Program } from 'estree';
import { SourceMap } from 'magic-string';
interface BaseNode {

@ -66,7 +66,7 @@ export class Parser {
if (state !== fragment) {
this.error({
code: `unexpected-eof`,
code: 'unexpected-eof',
message: 'Unexpected end of input'
});
}
@ -91,7 +91,7 @@ export class Parser {
acorn_error(err: any) {
this.error({
code: `parse-error`,
code: 'parse-error',
message: err.message.replace(/ \(\d+:\d+\)$/, '')
}, err.pos);
}
@ -169,7 +169,7 @@ export class Parser {
if (!allow_reserved && reserved.has(identifier)) {
this.error({
code: `unexpected-reserved-word`,
code: 'unexpected-reserved-word',
message: `'${identifier}' is a reserved word in JavaScript and cannot be used here`
}, start);
}
@ -180,7 +180,7 @@ export class Parser {
read_until(pattern: RegExp) {
if (this.index >= this.template.length)
this.error({
code: `unexpected-eof`,
code: 'unexpected-eof',
message: 'Unexpected end of input'
});
@ -199,8 +199,8 @@ export class Parser {
require_whitespace() {
if (!whitespace.test(this.template[this.index])) {
this.error({
code: `missing-whitespace`,
message: `Expected whitespace`
code: 'missing-whitespace',
message: 'Expected whitespace'
});
}
@ -228,15 +228,15 @@ export default function parse(
if (instance_scripts.length > 1) {
parser.error({
code: `invalid-script`,
message: `A component can only have one instance-level <script> element`
code: 'invalid-script',
message: 'A component can only have one instance-level <script> element'
}, instance_scripts[1].start);
}
if (module_scripts.length > 1) {
parser.error({
code: `invalid-script`,
message: `A component can only have one <script context="module"> element`
code: 'invalid-script',
message: 'A component can only have one <script context="module"> element'
}, module_scripts[1].start);
}

@ -1,14 +1,14 @@
import { Parser } from "../index";
import { isIdentifierStart } from "acorn";
import full_char_code_at from "../../utils/full_char_code_at";
import { Parser } from '../index';
import { isIdentifierStart } from 'acorn';
import full_char_code_at from '../../utils/full_char_code_at';
import {
is_bracket_open,
is_bracket_close,
is_bracket_pair,
get_bracket_close
} from "../utils/bracket";
import { parse_expression_at } from "../acorn";
import { Pattern } from "estree";
} from '../utils/bracket';
import { parse_expression_at } from '../acorn';
import { Pattern } from 'estree';
export default function read_context(
parser: Parser
@ -19,7 +19,7 @@ export default function read_context(
const code = full_char_code_at(parser.template, i);
if (isIdentifierStart(code, true)) {
return {
type: "Identifier",
type: 'Identifier',
name: parser.read_identifier(),
start,
end: parser.index
@ -28,8 +28,8 @@ export default function read_context(
if (!is_bracket_open(code)) {
parser.error({
code: "unexpected-token",
message: "Expected identifier or destructure pattern"
code: 'unexpected-token',
message: 'Expected identifier or destructure pattern'
});
}
@ -43,7 +43,7 @@ export default function read_context(
} else if (is_bracket_close(code)) {
if (!is_bracket_pair(bracket_stack[bracket_stack.length - 1], code)) {
parser.error({
code: "unexpected-token",
code: 'unexpected-token',
message: `Expected ${String.fromCharCode(
get_bracket_close(bracket_stack[bracket_stack.length - 1])
)}`

@ -12,7 +12,7 @@ function get_context(parser: Parser, attributes: any[], start: number): string {
if (context.value.length !== 1 || context.value[0].type !== 'Text') {
parser.error({
code: 'invalid-script',
message: `context attribute must be static`
message: 'context attribute must be static'
}, start);
}
@ -20,8 +20,8 @@ function get_context(parser: Parser, attributes: any[], start: number): string {
if (value !== 'module') {
parser.error({
code: `invalid-script`,
message: `If the context attribute is supplied, its value must be "module"`
code: 'invalid-script',
message: 'If the context attribute is supplied, its value must be "module"'
}, context.start);
}
@ -33,8 +33,8 @@ export default function read_script(parser: Parser, start: number, attributes: N
const script_end = parser.template.indexOf(script_closing_tag, script_start);
if (script_end === -1) parser.error({
code: `unclosed-script`,
message: `<script> must have a closing tag`
code: 'unclosed-script',
message: '<script> must have a closing tag'
});
const source = parser.template.slice(0, script_start).replace(/[^\n]/g, ' ') +

@ -19,7 +19,7 @@ export default function read_style(parser: Parser, start: number, attributes: No
} catch (err) {
if (err.name === 'CssSyntaxError') {
parser.error({
code: `css-syntax-error`,
code: 'css-syntax-error',
message: err.message
}, err.offset);
} else {
@ -40,7 +40,7 @@ export default function read_style(parser: Parser, start: number, attributes: No
if (is_ref_selector(a, b)) {
parser.error({
code: `invalid-ref-selector`,
code: 'invalid-ref-selector',
message: 'ref selectors are no longer supported'
}, a.loc.start.offset);
}
@ -49,15 +49,15 @@ export default function read_style(parser: Parser, start: number, attributes: No
if (node.type === 'Declaration' && node.value.type === 'Value' && node.value.children.length === 0) {
parser.error({
code: `invalid-declaration`,
message: `Declaration cannot be empty`
code: 'invalid-declaration',
message: 'Declaration cannot be empty'
}, node.start);
}
if (node.type === 'PseudoClassSelector' && node.name === 'global' && node.children === null) {
parser.error({
code: `css-syntax-error`,
message: `:global() must contain a selector`
code: 'css-syntax-error',
message: ':global() must contain a selector'
}, node.loc.start.offset);
}

@ -65,8 +65,8 @@ export default function mustache(parser: Parser) {
expected = 'await';
} else {
parser.error({
code: `unexpected-block-close`,
message: `Unexpected block closing tag`
code: 'unexpected-block-close',
message: 'Unexpected block closing tag'
});
}
@ -98,7 +98,7 @@ export default function mustache(parser: Parser) {
if (parser.eat('if')) {
parser.error({
code: 'invalid-elseif',
message: `'elseif' should be 'else if'`
message: '\'elseif\' should be \'else if\''
});
}
@ -109,10 +109,10 @@ export default function mustache(parser: Parser) {
const block = parser.current();
if (block.type !== 'IfBlock') {
parser.error({
code: `invalid-elseif-placement`,
code: 'invalid-elseif-placement',
message: parser.stack.some(block => block.type === 'IfBlock')
? `Expected to close ${to_string(block)} before seeing {:else if ...} block`
: `Cannot have an {:else if ...} block outside an {#if ...} block`
: 'Cannot have an {:else if ...} block outside an {#if ...} block'
});
}
@ -147,10 +147,10 @@ export default function mustache(parser: Parser) {
const block = parser.current();
if (block.type !== 'IfBlock' && block.type !== 'EachBlock') {
parser.error({
code: `invalid-else-placement`,
code: 'invalid-else-placement',
message: parser.stack.some(block => block.type === 'IfBlock' || block.type === 'EachBlock')
? `Expected to close ${to_string(block)} before seeing {:else} block`
: `Cannot have an {:else} block outside an {#if ...} or {#each ...} block`
: 'Cannot have an {:else} block outside an {#if ...} or {#each ...} block'
});
}
@ -173,19 +173,19 @@ export default function mustache(parser: Parser) {
if (is_then) {
if (block.type !== 'PendingBlock') {
parser.error({
code: `invalid-then-placement`,
code: 'invalid-then-placement',
message: parser.stack.some(block => block.type === 'PendingBlock')
? `Expected to close ${to_string(block)} before seeing {:then} block`
: `Cannot have an {:then} block outside an {#await ...} block`
: 'Cannot have an {:then} block outside an {#await ...} block'
});
}
} else {
if (block.type !== 'ThenBlock' && block.type !== 'PendingBlock') {
parser.error({
code: `invalid-catch-placement`,
code: 'invalid-catch-placement',
message: parser.stack.some(block => block.type === 'ThenBlock' || block.type === 'PendingBlock')
? `Expected to close ${to_string(block)} before seeing {:catch} block`
: `Cannot have an {:catch} block outside an {#await ...} block`
: 'Cannot have an {:catch} block outside an {#await ...} block'
});
}
}
@ -223,8 +223,8 @@ export default function mustache(parser: Parser) {
type = 'AwaitBlock';
} else {
parser.error({
code: `expected-block-type`,
message: `Expected if, each or await`
code: 'expected-block-type',
message: 'Expected if, each or await'
});
}
@ -285,8 +285,8 @@ export default function mustache(parser: Parser) {
parser.allow_whitespace();
block.index = parser.read_identifier();
if (!block.index) parser.error({
code: `expected-name`,
message: `Expected name`
code: 'expected-name',
message: 'Expected name'
});
parser.allow_whitespace();

@ -124,7 +124,7 @@ export default function tag(parser: Parser) {
if (is_closing_tag) {
if (is_void(name)) {
parser.error({
code: `invalid-void-content`,
code: 'invalid-void-content',
message: `<${name}> is a void element and cannot have children, or a closing tag`
}, start);
}
@ -138,7 +138,7 @@ export default function tag(parser: Parser) {
? `</${name}> attempted to close <${name}> that was already automatically closed by <${parser.last_auto_closed_tag.reason}>`
: `</${name}> attempted to close an element that was not open`;
parser.error({
code: `invalid-closing-tag`,
code: 'invalid-closing-tag',
message
}, start);
}
@ -179,16 +179,16 @@ export default function tag(parser: Parser) {
const index = element.attributes.findIndex(attr => attr.type === 'Attribute' && attr.name === 'this');
if (!~index) {
parser.error({
code: `missing-component-definition`,
message: `<svelte:component> must have a 'this' attribute`
code: 'missing-component-definition',
message: '<svelte:component> must have a \'this\' attribute'
}, start);
}
const definition = element.attributes.splice(index, 1)[0];
if (definition.value === true || definition.value.length !== 1 || definition.value[0].type === 'Text') {
parser.error({
code: `invalid-component-definition`,
message: `invalid component definition`
code: 'invalid-component-definition',
message: 'invalid component definition'
}, definition.start);
}
@ -262,8 +262,8 @@ function read_tag_name(parser: Parser) {
if (!legal) {
parser.error({
code: `invalid-self-placement`,
message: `<svelte:self> components can only exist inside {#if} blocks, {#each} blocks, or slots passed to components`
code: 'invalid-self-placement',
message: '<svelte:self> components can only exist inside {#if} blocks, {#each} blocks, or slots passed to components'
}, start);
}
@ -290,8 +290,8 @@ function read_tag_name(parser: Parser) {
if (!valid_tag_name.test(name)) {
parser.error({
code: `invalid-tag-name`,
message: `Expected valid tag name`
code: 'invalid-tag-name',
message: 'Expected valid tag name'
}, start);
}
@ -304,7 +304,7 @@ function read_attribute(parser: Parser, unique_names: Set<string>) {
function check_unique(name: string) {
if (unique_names.has(name)) {
parser.error({
code: `duplicate-attribute`,
code: 'duplicate-attribute',
message: 'Attributes need to be unique'
}, start);
}
@ -373,8 +373,8 @@ function read_attribute(parser: Parser, unique_names: Set<string>) {
end = parser.index;
} else if (parser.match_regex(/["']/)) {
parser.error({
code: `unexpected-token`,
message: `Expected =`
code: 'unexpected-token',
message: 'Expected ='
}, parser.index);
}
@ -389,7 +389,7 @@ function read_attribute(parser: Parser, unique_names: Set<string>) {
if (type === 'Ref') {
parser.error({
code: `invalid-ref-directive`,
code: 'invalid-ref-directive',
message: `The ref directive is no longer supported — use \`bind:this={${directive_name}}\` instead`
}, start);
}
@ -397,8 +397,8 @@ function read_attribute(parser: Parser, unique_names: Set<string>) {
if (value[0]) {
if ((value as any[]).length > 1 || value[0].type === 'Text') {
parser.error({
code: `invalid-directive-value`,
message: `Directive value must be a JavaScript expression enclosed in curly braces`
code: 'invalid-directive-value',
message: 'Directive value must be a JavaScript expression enclosed in curly braces'
}, value[0].start);
}
}
@ -453,11 +453,11 @@ function get_directive_type(name: string): DirectiveType {
}
function read_attribute_value(parser: Parser) {
const quote_mark = parser.eat(`'`) ? `'` : parser.eat(`"`) ? `"` : null;
const quote_mark = parser.eat('\'') ? '\'' : parser.eat('"') ? '"' : null;
const regex = (
quote_mark === `'` ? /'/ :
quote_mark === `"` ? /"/ :
quote_mark === '\'' ? /'/ :
quote_mark === '"' ? /"/ :
/(\/>|[\s"'=<>`])/
);
@ -520,7 +520,7 @@ function read_sequence(parser: Parser, done: () => boolean): TemplateNode[] {
}
parser.error({
code: `unexpected-eof`,
message: `Unexpected end of input`
code: 'unexpected-eof',
message: 'Unexpected end of input'
});
}

@ -1,7 +1,7 @@
const SQUARE_BRACKET_OPEN = "[".charCodeAt(0);
const SQUARE_BRACKET_CLOSE = "]".charCodeAt(0);
const CURLY_BRACKET_OPEN = "{".charCodeAt(0);
const CURLY_BRACKET_CLOSE = "}".charCodeAt(0);
const SQUARE_BRACKET_OPEN = '['.charCodeAt(0);
const SQUARE_BRACKET_CLOSE = ']'.charCodeAt(0);
const CURLY_BRACKET_OPEN = '{'.charCodeAt(0);
const CURLY_BRACKET_CLOSE = '}'.charCodeAt(0);
export function is_bracket_open(code) {
return code === SQUARE_BRACKET_OPEN || code === CURLY_BRACKET_OPEN;

@ -26,7 +26,7 @@ function parse_attributes(str: string) {
if (p === -1) {
attrs[attr] = true;
} else {
attrs[attr.slice(0, p)] = `'"`.includes(attr[p + 1]) ?
attrs[attr.slice(0, p)] = '\'"'.includes(attr[p + 1]) ?
attr.slice(p + 2, -1) :
attr.slice(p + 1);
}

@ -6,17 +6,17 @@ export function dispatch_dev<T=any>(type: string, detail?: T) {
}
export function append_dev(target: Node, node: Node) {
dispatch_dev("SvelteDOMInsert", { target, node });
dispatch_dev('SvelteDOMInsert', { target, node });
append(target, node);
}
export function insert_dev(target: Node, node: Node, anchor?: Node) {
dispatch_dev("SvelteDOMInsert", { target, node, anchor });
dispatch_dev('SvelteDOMInsert', { target, node, anchor });
insert(target, node, anchor);
}
export function detach_dev(node: Node) {
dispatch_dev("SvelteDOMRemove", { node });
dispatch_dev('SvelteDOMRemove', { node });
detach(node);
}
@ -39,15 +39,15 @@ export function detach_after_dev(before: Node) {
}
export function listen_dev(node: Node, event: string, handler: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions | EventListenerOptions, has_prevent_default?: boolean, has_stop_propagation?: boolean) {
const modifiers = options === true ? [ "capture" ] : options ? Array.from(Object.keys(options)) : [];
const modifiers = options === true ? [ 'capture' ] : options ? Array.from(Object.keys(options)) : [];
if (has_prevent_default) modifiers.push('preventDefault');
if (has_stop_propagation) modifiers.push('stopPropagation');
dispatch_dev("SvelteDOMAddEventListener", { node, event, handler, modifiers });
dispatch_dev('SvelteDOMAddEventListener', { node, event, handler, modifiers });
const dispose = listen(node, event, handler, options);
return () => {
dispatch_dev("SvelteDOMRemoveEventListener", { node, event, handler, modifiers });
dispatch_dev('SvelteDOMRemoveEventListener', { node, event, handler, modifiers });
dispose();
};
}
@ -55,27 +55,27 @@ export function listen_dev(node: Node, event: string, handler: EventListenerOrEv
export function attr_dev(node: Element, attribute: string, value?: string) {
attr(node, attribute, value);
if (value == null) dispatch_dev("SvelteDOMRemoveAttribute", { node, attribute });
else dispatch_dev("SvelteDOMSetAttribute", { node, attribute, value });
if (value == null) dispatch_dev('SvelteDOMRemoveAttribute', { node, attribute });
else dispatch_dev('SvelteDOMSetAttribute', { node, attribute, value });
}
export function prop_dev(node: Element, property: string, value?: any) {
node[property] = value;
dispatch_dev("SvelteDOMSetProperty", { node, property, value });
dispatch_dev('SvelteDOMSetProperty', { node, property, value });
}
export function dataset_dev(node: HTMLElement, property: string, value?: any) {
node.dataset[property] = value;
dispatch_dev("SvelteDOMSetDataset", { node, property, value });
dispatch_dev('SvelteDOMSetDataset', { node, property, value });
}
export function set_data_dev(text, data) {
data = '' + data;
if (text.wholeText === data) return;
dispatch_dev("SvelteDOMSetData", { node: text, data });
dispatch_dev('SvelteDOMSetData', { node: text, data });
text.data = data;
}
@ -115,7 +115,7 @@ export class SvelteComponentDev extends SvelteComponent {
$$inline?: boolean;
}) {
if (!options || (!options.target && !options.$$inline)) {
throw new Error(`'target' is a required option`);
throw new Error('\'target\' is a required option');
}
super();
@ -124,7 +124,7 @@ export class SvelteComponentDev extends SvelteComponent {
$destroy() {
super.$destroy();
this.$destroy = () => {
console.warn(`Component was already destroyed`); // eslint-disable-line no-console
console.warn('Component was already destroyed'); // eslint-disable-line no-console
};
}
@ -137,7 +137,7 @@ export function loop_guard(timeout) {
const start = Date.now();
return () => {
if (Date.now() - start > timeout) {
throw new Error(`Infinite loop detected`);
throw new Error('Infinite loop detected');
}
};
}

@ -1,4 +1,4 @@
import { has_prop } from "./utils";
import { has_prop } from './utils';
export function append(target: Node, node: Node) {
target.appendChild(node);
@ -269,7 +269,7 @@ export function add_resize_listener(node: HTMLElement, fn: () => void) {
const iframe = element('iframe');
iframe.setAttribute('style',
`display: block; position: absolute; top: 0; left: 0; width: 100%; height: 100%; ` +
'display: block; position: absolute; top: 0; left: 0; width: 100%; height: 100%; ' +
`overflow: hidden; border: 0; opacity: 0; pointer-events: none; z-index: ${z_index};`
);
iframe.setAttribute('aria-hidden', 'true');
@ -280,7 +280,7 @@ export function add_resize_listener(node: HTMLElement, fn: () => void) {
let unsubscribe: () => void;
if (crossorigin) {
iframe.src = `data:text/html,<script>onresize=function(){parent.postMessage(0,'*')}</script>`;
iframe.src = 'data:text/html,<script>onresize=function(){parent.postMessage(0,\'*\')}</script>';
unsubscribe = listen(window, 'message', (event: MessageEvent) => {
if (event.source === iframe.contentWindow) fn();
});

@ -113,7 +113,7 @@ export function validate_each_keys(ctx, list, get_context, get_key) {
for (let i = 0; i < list.length; i++) {
const key = get_key(get_context(ctx, list, i));
if (keys.has(key)) {
throw new Error(`Cannot have duplicate keys in a keyed each`);
throw new Error('Cannot have duplicate keys in a keyed each');
}
keys.add(key);
}

@ -7,7 +7,7 @@ export function set_current_component(component) {
}
export function get_current_component() {
if (!current_component) throw new Error(`Function called outside component initialization`);
if (!current_component) throw new Error('Function called outside component initialization');
return current_component;
}

@ -21,9 +21,9 @@ export function spread(args, classes_to_add) {
if (invalid_attribute_name_character.test(name)) return;
const value = attributes[name];
if (value === true) str += " " + name;
if (value === true) str += ' ' + name;
else if (boolean_attributes.has(name.toLowerCase())) {
if (value) str += " " + name;
if (value) str += ' ' + name;
} else if (value != null) {
str += ` ${name}="${String(value).replace(/"/g, '&#34;').replace(/'/g, '&#39;')}"`;
}
@ -34,7 +34,7 @@ export function spread(args, classes_to_add) {
export const escaped = {
'"': '&quot;',
"'": '&#39;',
'\'': '&#39;',
'&': '&amp;',
'<': '&lt;',
'>': '&gt;'
@ -133,5 +133,5 @@ export function add_attribute(name, value, boolean) {
}
export function add_classes(classes) {
return classes ? ` class="${classes}"` : ``;
return classes ? ` class="${classes}"` : '';
}

@ -40,7 +40,7 @@ export function create_rule(node: Element & ElementCSSInlineStyle, a: number, b:
}
const animation = node.style.animation || '';
node.style.animation = `${animation ? `${animation}, ` : ``}${name} ${duration}ms linear ${delay}ms 1 both`;
node.style.animation = `${animation ? `${animation}, ` : ''}${name} ${duration}ms linear ${delay}ms 1 both`;
active += 1;
return name;

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

@ -120,7 +120,7 @@ export function slide(node: Element, {
duration,
easing,
css: t =>
`overflow: hidden;` +
'overflow: hidden;' +
`opacity: ${Math.min(t * 20, 1) * opacity};` +
`height: ${t * height}px;` +
`padding-top: ${t * padding_top}px;` +

@ -1,7 +1,7 @@
export default {
warnings: [{
filename: "SvelteComponent.svelte",
code: `css-unused-selector`,
filename: 'SvelteComponent.svelte',
code: 'css-unused-selector',
message: 'Unused CSS selector ".x"',
start: {
line: 4,

@ -1,6 +1,6 @@
export default {
warnings: [{
code: `css-unused-selector`,
code: 'css-unused-selector',
message: 'Unused CSS selector "div > p"',
start: {
line: 8,

@ -1,7 +1,7 @@
export default {
warnings: [
{
code: "css-unused-selector",
code: 'css-unused-selector',
message: 'Unused CSS selector "article > *"',
frame: `
1: <style>
@ -14,7 +14,7 @@ export default {
end: { character: 21, column: 12, line: 2 }
},
{
code: "css-unused-selector",
code: 'css-unused-selector',
message: 'Unused CSS selector "article *"',
frame: `
4: }
@ -28,7 +28,7 @@ export default {
end: { character: 58, column: 10, line: 6 }
},
{
code: "css-unused-selector",
code: 'css-unused-selector',
message: 'Unused CSS selector ".article > *"',
frame: `
8: }

@ -1,8 +1,8 @@
export default {
warnings: [
{
filename: "SvelteComponent.svelte",
code: `css-unused-selector`,
filename: 'SvelteComponent.svelte',
code: 'css-unused-selector',
message: 'Unused CSS selector ".foo"',
start: {
line: 4,
@ -25,8 +25,8 @@ export default {
},
{
filename: "SvelteComponent.svelte",
code: `css-unused-selector`,
filename: 'SvelteComponent.svelte',
code: 'css-unused-selector',
message: 'Unused CSS selector ".baz"',
start: {
line: 4,

@ -4,8 +4,8 @@ export default {
},
warnings: [{
filename: "SvelteComponent.svelte",
code: `css-unused-selector`,
filename: 'SvelteComponent.svelte',
code: 'css-unused-selector',
message: 'Unused CSS selector ".maybeactive"',
start: {
line: 16,

@ -1,7 +1,7 @@
export default {
warnings: [{
filename: "SvelteComponent.svelte",
code: `css-unused-selector`,
filename: 'SvelteComponent.svelte',
code: 'css-unused-selector',
message: 'Unused CSS selector ".bar"',
start: {
line: 8,

@ -1,7 +1,7 @@
export default {
warnings: [{
code: "avoid-is",
message: "The 'is' attribute is not supported cross-browser and should be avoided",
code: 'avoid-is',
message: 'The \'is\' attribute is not supported cross-browser and should be avoided',
pos: 98,
start: {
character: 98,

@ -8,10 +8,10 @@ export default async function (target) {
const button = counter.shadowRoot.querySelector('button');
assert.equal(counter.count, 0);
assert.equal(counter.shadowRoot.innerHTML, `<button>count: 0</button>`);
assert.equal(counter.shadowRoot.innerHTML, '<button>count: 0</button>');
await button.dispatchEvent(new MouseEvent('click'));
assert.equal(counter.count, 1);
assert.equal(counter.shadowRoot.innerHTML, `<button>count: 1</button>`);
assert.equal(counter.shadowRoot.innerHTML, '<button>count: 1</button>');
}

@ -12,7 +12,7 @@ export default function (target) {
target.innerHTML = '<my-app foo=yes />';
assert.deepEqual(warnings, [
`<my-app> was created without expected prop 'bar'`
'<my-app> was created without expected prop \'bar\''
]);
console.warn = warn;

@ -1,7 +1,7 @@
export default {
warnings: [{
code: "custom-element-no-tag",
message: "No custom element 'tag' option was specified. To automatically register a custom element, specify a name with a hyphen in it, e.g. <svelte:options tag=\"my-thing\"/>. To hide this warning, use <svelte:options tag={null}/>",
code: 'custom-element-no-tag',
message: 'No custom element \'tag\' option was specified. To automatically register a custom element, specify a name with a hyphen in it, e.g. <svelte:options tag="my-thing"/>. To hide this warning, use <svelte:options tag={null}/>',
pos: 0,
start: {
character: 0,

@ -3,7 +3,7 @@ import CustomElement from './main.svelte';
export default function (target) {
customElements.define('no-tag', CustomElement);
target.innerHTML = `<no-tag name="world"></no-tag>`;
target.innerHTML = '<no-tag name="world"></no-tag>';
const el = target.querySelector('no-tag');
const h1 = el.shadowRoot.querySelector('h1');

@ -1,7 +1,7 @@
export default {
warnings: [{
code: "custom-element-no-tag",
message: "No custom element 'tag' option was specified. To automatically register a custom element, specify a name with a hyphen in it, e.g. <svelte:options tag=\"my-thing\"/>. To hide this warning, use <svelte:options tag={null}/>",
code: 'custom-element-no-tag',
message: 'No custom element \'tag\' option was specified. To automatically register a custom element, specify a name with a hyphen in it, e.g. <svelte:options tag="my-thing"/>. To hide this warning, use <svelte:options tag={null}/>',
pos: 0,
start: {
character: 0,

@ -3,7 +3,7 @@ import CustomElement from './main.svelte';
export default function (target) {
customElements.define('no-tag', CustomElement);
target.innerHTML = `<no-tag name="world"></no-tag>`;
target.innerHTML = '<no-tag name="world"></no-tag>';
const el = target.querySelector('no-tag');
const h1 = el.shadowRoot.querySelector('h1');

@ -3,7 +3,7 @@ import CustomElement from './main.svelte';
export default function (target) {
customElements.define('no-tag', CustomElement);
target.innerHTML = `<no-tag name="world"></no-tag>`;
target.innerHTML = '<no-tag name="world"></no-tag>';
const el = target.querySelector('no-tag');
const h1 = el.shadowRoot.querySelector('h1');

@ -19,6 +19,6 @@ export default {
component.foo = false;
component.bar = true;
assert.htmlEqual(target.innerHTML, `<p>bar!</p>`);
assert.htmlEqual(target.innerHTML, '<p>bar!</p>');
}
};

@ -2,7 +2,7 @@ export default {
skip: true, // existing nodes are blown away
props: {
raw: `<p>this is some html</p> <p>and so is this</p>`
raw: '<p>this is some html</p> <p>and so is this</p>'
},
snapshot(target) {

@ -1,13 +1,13 @@
// this file will replace all the expected.js files with their _actual
// equivalents. Only use it when you're sure that you haven't
// broken anything!
const fs = require("fs");
const glob = require("tiny-glob/sync.js");
const fs = require('fs');
const glob = require('tiny-glob/sync.js');
glob("samples/*/_actual.js", { cwd: __dirname }).forEach(file => {
const actual = fs.readFileSync(`${__dirname}/${file}`, "utf-8");
glob('samples/*/_actual.js', { cwd: __dirname }).forEach(file => {
const actual = fs.readFileSync(`${__dirname}/${file}`, 'utf-8');
fs.writeFileSync(
`${__dirname}/${file.replace("_actual.js", "expected.js")}`,
`${__dirname}/${file.replace('_actual.js', 'expected.js')}`,
actual
);
});

@ -1,13 +1,13 @@
// this file will replace all the output.json files with their _actual.json
// equivalents. Only use it when you're sure that you haven't
// broken anything!
const fs = require("fs");
const glob = require("tiny-glob/sync.js");
const fs = require('fs');
const glob = require('tiny-glob/sync.js');
glob("samples/*/_actual.json", { cwd: __dirname }).forEach(file => {
const actual = fs.readFileSync(`${__dirname}/${file}`, "utf-8");
glob('samples/*/_actual.json', { cwd: __dirname }).forEach(file => {
const actual = fs.readFileSync(`${__dirname}/${file}`, 'utf-8');
fs.writeFileSync(
`${__dirname}/${file.replace("_actual.json", "output.json")}`,
`${__dirname}/${file.replace('_actual.json', 'output.json')}`,
actual
);
});

@ -1,11 +1,11 @@
import * as assert from "assert";
import * as assert from 'assert';
export default {
preprocess: {
script: ({ content, attributes }) => {
assert.equal(content, "");
assert.equal(content, '');
return {
code: `console.log("${attributes["the-answer"]}");`
code: `console.log("${attributes['the-answer']}");`
};
}
}

@ -1,9 +1,9 @@
import * as assert from "assert";
import * as assert from 'assert';
export default {
preprocess: {
style: ({ content, attributes: { color } }) => {
assert.equal(content, "");
assert.equal(content, '');
return {
code: `div { color: ${color}; }`
};

@ -1,5 +1,5 @@
export default {
html: `<input>`,
html: '<input>',
test({ assert, component, target, window }) {
const input = target.querySelector('input');

@ -3,9 +3,9 @@ export default {
const button = target.querySelector('button');
const click = new window.MouseEvent('click');
assert.htmlEqual(target.innerHTML, `<button>1</button>`);
assert.htmlEqual(target.innerHTML, '<button>1</button>');
await button.dispatchEvent(click);
await Promise.resolve();
assert.htmlEqual(target.innerHTML, `<button>2</button>`);
assert.htmlEqual(target.innerHTML, '<button>2</button>');
}
};

@ -1,3 +1,3 @@
export default {
html: `<div>a</div> <div>b</div> <div>c</div>`
html: '<div>a</div> <div>b</div> <div>c</div>'
};

@ -1,3 +1,3 @@
export default {
html: `<input readonly>`
html: '<input readonly>'
};

@ -1,5 +1,5 @@
export default {
html: `<textarea></textarea>`,
html: '<textarea></textarea>',
test({ assert, component, target }) {
const textarea = target.querySelector('textarea');
assert.ok(textarea.readOnly === false);

@ -1,5 +1,5 @@
export default {
html: `<textarea readonly></textarea>`,
html: '<textarea readonly></textarea>',
test({ assert, component, target }) {
const textarea = target.querySelector('textarea');
assert.ok(textarea.readOnly);

@ -1,3 +1,3 @@
export default {
html: `<input>`
html: '<input>'
};

@ -1,3 +1,3 @@
export default {
html: `<span title='"foo"'>foo</span>`
html: '<span title=\'"foo"\'>foo</span>'
};

@ -1,8 +1,8 @@
export default {
html: `<div id="foo"></div>`,
html: '<div id="foo"></div>',
test({ assert, component, target }) {
component.id = 'bar';
assert.equal( target.innerHTML, `<div id="bar"></div>` );
assert.equal( target.innerHTML, '<div id="bar"></div>' );
}
};

@ -6,7 +6,7 @@ export default {
inputValue: 42
},
html: `<input type="text">`,
html: '<input type="text">',
test({ assert, component, target }) {
const input = target.querySelector('input');

@ -1,5 +1,5 @@
export default {
html: `<div style="color: red;">red</div>`,
html: '<div style="color: red;">red</div>',
test({ assert, component, target }) {
const div = target.querySelector( 'div' );
@ -7,7 +7,7 @@ export default {
assert.equal( div.style.color, 'red' );
component.color = 'blue';
assert.equal( target.innerHTML, `<div style="color: blue;">blue</div>` );
assert.equal( target.innerHTML, '<div style="color: blue;">blue</div>' );
assert.equal( div.style.color, 'blue' );
}
};

@ -1,3 +1,3 @@
export default {
html: `<div class=""></div>`
html: '<div class=""></div>'
};

@ -1,3 +1,3 @@
export default {
html: `<div class="false"></div>`
html: '<div class="false"></div>'
};

@ -1,9 +1,9 @@
export default {
props: {
testName: "testClassName"
testName: 'testClassName'
},
html: `<div class="testClassName"></div>`,
html: '<div class="testClassName"></div>',
test({ assert, component, target }) {
const div = target.querySelector('div');

@ -1,5 +1,5 @@
export default {
html: `<div class=" svelte-x1o6ra"></div>`,
html: '<div class=" svelte-x1o6ra"></div>',
test({ assert, component, target }) {
const div = target.querySelector('div');

@ -1,10 +1,10 @@
export default {
props: {
testName1: "test1",
testName2: "test2"
testName1: 'test1',
testName2: 'test2'
},
html: `<div class="test1test2"></div>`,
html: '<div class="test1test2"></div>',
test({ assert, component, target }) {
const div = target.querySelector('div');
@ -15,11 +15,11 @@ export default {
assert.equal(div.className, '0');
component.testName1 = null;
component.testName2 = "test";
component.testName2 = 'test';
assert.equal(div.className, 'nulltest');
component.testName1 = undefined;
component.testName2 = "test";
component.testName2 = 'test';
assert.equal(div.className, 'undefinedtest');
component.testName1 = undefined;

@ -1,10 +1,10 @@
export default {
props: {
testName1: "test1",
testName2: "test2"
testName1: 'test1',
testName2: 'test2'
},
html: `<div class="test1test2 svelte-x1o6ra"></div>`,
html: '<div class="test1test2 svelte-x1o6ra"></div>',
test({ assert, component, target }) {
const div = target.querySelector('div');
@ -15,11 +15,11 @@ export default {
assert.equal(div.className, '0 svelte-x1o6ra');
component.testName1 = null;
component.testName2 = "test";
component.testName2 = 'test';
assert.equal(div.className, 'nulltest svelte-x1o6ra');
component.testName1 = undefined;
component.testName2 = "test";
component.testName2 = 'test';
assert.equal(div.className, 'undefinedtest svelte-x1o6ra');
component.testName1 = undefined;

@ -1,9 +1,9 @@
export default {
props: {
testName: "testClassName"
testName: 'testClassName'
},
html: `<div class="testClassName"></div>`,
html: '<div class="testClassName"></div>',
test({ assert, component, target }) {
const div = target.querySelector('div');

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

Loading…
Cancel
Save