pull/3539/head
Richard Harris 6 years ago
parent ec238d746a
commit f30e02adf7

6
package-lock.json generated

@ -507,9 +507,9 @@
"dev": true "dev": true
}, },
"code-red": { "code-red": {
"version": "0.0.11", "version": "0.0.12",
"resolved": "https://registry.npmjs.org/code-red/-/code-red-0.0.11.tgz", "resolved": "https://registry.npmjs.org/code-red/-/code-red-0.0.12.tgz",
"integrity": "sha512-GY5N9XC10+FZclzAGdrGFF47alu+I1xCcpM/eoYmpQZmAvOp1HkOgMLsxCtmuB94q84I693yN7SGGtu9sfOslA==", "integrity": "sha512-5R8zbm2z5CmHp2iSmV/kSDhXcdISJwBr898jIPeASEdsGrjFpT4Jhky0J659jLsZL9gzDBGn32rvR0YWDXzAvw==",
"dev": true, "dev": true,
"requires": { "requires": {
"acorn": "^7.0.0", "acorn": "^7.0.0",

@ -63,7 +63,7 @@
"acorn": "^7.0.0", "acorn": "^7.0.0",
"agadoo": "^1.0.1", "agadoo": "^1.0.1",
"c8": "^5.0.1", "c8": "^5.0.1",
"code-red": "0.0.11", "code-red": "0.0.12",
"codecov": "^3.5.0", "codecov": "^3.5.0",
"css-tree": "1.0.0-alpha22", "css-tree": "1.0.0-alpha22",
"eslint": "^6.3.0", "eslint": "^6.3.0",

@ -2,7 +2,7 @@
import { walk, childKeys } from 'estree-walker'; import { walk, childKeys } from 'estree-walker';
import { getLocator } from 'locate-character'; import { getLocator } from 'locate-character';
import Stats from '../Stats'; import Stats from '../Stats';
import { globals, reserved } from '../utils/names'; import { globals, reserved, is_valid } from '../utils/names';
import { namespaces, valid_namespaces } from '../utils/namespaces'; import { namespaces, valid_namespaces } from '../utils/namespaces';
import create_module from './create_module'; import create_module from './create_module';
import { import {
@ -24,7 +24,7 @@ import TemplateScope from './nodes/shared/TemplateScope';
import fuzzymatch from '../utils/fuzzymatch'; import fuzzymatch from '../utils/fuzzymatch';
import get_object from './utils/get_object'; import get_object from './utils/get_object';
import Slot from './nodes/Slot'; import Slot from './nodes/Slot';
import { Node, ImportDeclaration, Identifier, Program, ExpressionStatement, AssignmentExpression } from 'estree'; import { Node, ImportDeclaration, Identifier, Program, ExpressionStatement, AssignmentExpression, Literal } from 'estree';
import add_to_set from './utils/add_to_set'; import add_to_set from './utils/add_to_set';
import check_graph_for_cycles from './utils/check_graph_for_cycles'; import check_graph_for_cycles from './utils/check_graph_for_cycles';
import { print, x } from 'code-red'; import { print, x } from 'code-red';
@ -285,24 +285,44 @@ export default class Component {
const program: any = { type: 'Program', body: result }; const program: any = { type: 'Program', body: result };
walk(program, { walk(program, {
enter: (node) => { enter: (node, parent, key) => {
if (node.type === 'Identifier' && !('name' in node)) { if (node.type === 'Identifier' && !('name' in node)) {
console.log(node); console.log(node);
throw new Error('wtf'); throw new Error('wtf');
} }
if (node.type === 'Identifier' && node.name[0] === '@') { if (node.type === 'Identifier') {
// TODO temp if (node.name[0] === '@') {
if (!/@\w+$/.test(node.name)) { // TODO temp
throw new Error(`wut "${node.name}"`); if (!/@\w+$/.test(node.name)) {
throw new Error(`wut "${node.name}"`);
}
if (node.name[1] === '_') {
const alias = this.global(node.name.slice(2));
node.name = alias.name;
} else {
const alias = this.helper(node.name.slice(1));
node.name = alias.name;
}
} }
if (node.name[1] === '_') { else if (node.name[0] !== '#' && !is_valid(node.name)) {
const alias = this.global(node.name.slice(2)); // this hack allows x`foo.${bar}` where bar could be invalid
node.name = alias.name; const literal: Literal = { type: 'Literal', value: node.name };
} else {
const alias = this.helper(node.name.slice(1)); if (parent.type === 'Property' && key === 'key') {
node.name = alias.name; parent.key = literal;
}
else if (parent.type === 'MemberExpression' && key === 'property') {
parent.property = literal;
parent.computed = true;
}
else {
console.log(node);
}
} }
} }
} }

@ -41,8 +41,8 @@ export default function dom(
body.push(b` body.push(b`
function ${add_css}() { function ${add_css}() {
var style = @element("style"); var style = @element("style");
style.id = '${component.stylesheet.id}-style'; style.id = "${component.stylesheet.id}-style";
style.textContent = ${styles}; style.textContent = "${styles}";
@append(@_document.head, style); @append(@_document.head, style);
} }
`); `);
@ -84,7 +84,7 @@ export default function dom(
${$$props} => { ${$$props} => {
${uses_props && component.invalidate('$$props', x`$$props = @assign(@assign({}, $$props), $$new_props)`)} ${uses_props && component.invalidate('$$props', x`$$props = @assign(@assign({}, $$props), $$new_props)`)}
${writable_props.map(prop => ${writable_props.map(prop =>
b`if ('${prop.export_name}' in ${$$props}) ${component.invalidate(prop.name, `${prop.name} = ${$$props}.${prop.export_name}`)};` b`if ('${prop.export_name}' in ${$$props}) ${component.invalidate(prop.name, x`${prop.name} = ${$$props}.${prop.export_name}`)};`
)} )}
${component.slots.size > 0 && ${component.slots.size > 0 &&
b`if ('$$scope' in ${$$props}) ${component.invalidate('$$scope', x`$$scope = ${$$props}.$$scope`)};`} b`if ('$$scope' in ${$$props}) ${component.invalidate('$$scope', x`$$scope = ${$$props}.$$scope`)};`}
@ -160,7 +160,7 @@ export default function dom(
if (expected.length) { if (expected.length) {
dev_props_check = b` dev_props_check = b`
const { ctx } = this.$$; const { ctx: #ctx } = this.$$;
const props = ${options.customElement ? `this.attributes` : `options.props || {}`}; const props = ${options.customElement ? `this.attributes` : `options.props || {}`};
${expected.map(prop => b` ${expected.map(prop => b`
if (#ctx.${prop.name} === undefined && !('${prop.export_name}' in props)) { if (#ctx.${prop.name} === undefined && !('${prop.export_name}' in props)) {
@ -171,7 +171,7 @@ export default function dom(
capture_state = (uses_props || writable_props.length > 0) ? x` capture_state = (uses_props || writable_props.length > 0) ? x`
() => { () => {
return { ${component.vars.filter(prop => prop.writable).map(prop => prop.name).join(", ")} }; return { ${component.vars.filter(prop => prop.writable).map(prop => p`${prop.name}`)} };
} }
` : x` ` : x`
() => { () => {
@ -184,7 +184,7 @@ export default function dom(
${$$props} => { ${$$props} => {
${uses_props && component.invalidate('$$props', x`$$props = @assign(@assign({}, $$props), $$new_props)`)} ${uses_props && component.invalidate('$$props', x`$$props = @assign(@assign({}, $$props), $$new_props)`)}
${writable_vars.map(prop => b` ${writable_vars.map(prop => b`
if ('${prop.name}' in $$props) ${component.invalidate(prop.name, `${prop.name} = ${$$props}.${prop.name}`)}; if ('${prop.name}' in $$props) ${component.invalidate(prop.name, x`${prop.name} = ${$$props}.${prop.name}`)};
`)} `)}
} }
` : x` ` : x`
@ -327,13 +327,14 @@ export default function dom(
const dependencies = Array.from(d.dependencies); const dependencies = Array.from(d.dependencies);
const uses_props = !!dependencies.find(n => n === '$$props'); const uses_props = !!dependencies.find(n => n === '$$props');
const condition = !uses_props && dependencies const writable = dependencies.filter(n => {
.filter(n => { const variable = component.var_lookup.get(n);
const variable = component.var_lookup.get(n); return variable && (variable.writable || variable.mutated);
return variable && (variable.writable || variable.mutated); });
})
const condition = !uses_props && writable.length > 0 && (writable
.map(n => x`$$dirty.${n}`) .map(n => x`$$dirty.${n}`)
.reduce((lhs, rhs) => x`${lhs} || ${rhs}`); .reduce((lhs, rhs) => x`${lhs} || ${rhs}`));
let statement = d.node; let statement = d.node;
if (condition) statement = b`if (${condition}) { ${statement} }`[0]; if (condition) statement = b`if (${condition}) { ${statement} }`[0];
@ -405,7 +406,7 @@ export default function dom(
${component.slots.size && b`let { $$slots = {}, $$scope } = $$props;`} ${component.slots.size && b`let { $$slots = {}, $$scope } = $$props;`}
${renderer.binding_groups.length > 0 && `const $$binding_groups = [${renderer.binding_groups.map(_ => `[]`).join(', ')}];`} ${renderer.binding_groups.length > 0 && b`const $$binding_groups = [${renderer.binding_groups.map(_ => x`[]`)}];`}
${component.partly_hoisted} ${component.partly_hoisted}

@ -395,7 +395,7 @@ export default class EachBlockWrapper extends Wrapper {
${this.block.has_outros && b`@group_outros();`} ${this.block.has_outros && b`@group_outros();`}
${this.node.has_animation && b`for (let #i = 0; #i < ${view_length}; #i += 1) ${iterations}[#i].r();`} ${this.node.has_animation && b`for (let #i = 0; #i < ${view_length}; #i += 1) ${iterations}[#i].r();`}
${iterations} = @update_keyed_each(${iterations}, #changed, ${get_key}, ${dynamic ? '1' : '0'}, #ctx, ${this.vars.each_block_value}, ${lookup}, ${update_mount_node}, ${destroy}, ${create_each_block}, ${update_anchor_node}, ${this.vars.get_each_context}); ${iterations} = @update_keyed_each(${iterations}, #changed, ${get_key}, ${dynamic ? 1 : 0}, #ctx, ${this.vars.each_block_value}, ${lookup}, ${update_mount_node}, ${destroy}, ${create_each_block}, ${update_anchor_node}, ${this.vars.get_each_context});
${this.node.has_animation && b`for (let #i = 0; #i < ${view_length}; #i += 1) ${iterations}[#i].a();`} ${this.node.has_animation && b`for (let #i = 0; #i < ${view_length}; #i += 1) ${iterations}[#i].a();`}
${this.block.has_outros && b`@check_outros();`} ${this.block.has_outros && b`@check_outros();`}
`); `);
@ -508,7 +508,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; let remove_old_blocks;
@ -529,7 +529,7 @@ export default class EachBlockWrapper extends Wrapper {
`; `;
} else { } else {
remove_old_blocks = b` remove_old_blocks = b`
for (${this.block.has_update_method ? `` : x`#i = ${data_length}`}; #i < ${this.block.has_update_method ? view_length : '#old_length'}; #i += 1) { for (${this.block.has_update_method ? null : x`#i = ${data_length}`}; #i < ${this.block.has_update_method ? view_length : '#old_length'}; #i += 1) {
${iterations}[#i].d(1); ${iterations}[#i].d(1);
} }
${!fixed_length && b`${view_length} = ${data_length};`} ${!fixed_length && b`${view_length} = ${data_length};`}

@ -3,7 +3,7 @@ import Attribute from '../../../nodes/Attribute';
import Block from '../../Block'; import Block from '../../Block';
import AttributeWrapper from './Attribute'; import AttributeWrapper from './Attribute';
import ElementWrapper from '../Element'; import ElementWrapper from '../Element';
import { stringify } from '../../../utils/stringify'; import { string_literal } from '../../../utils/stringify';
import add_to_set from '../../../utils/add_to_set'; import add_to_set from '../../../utils/add_to_set';
import Expression from '../../../nodes/shared/Expression'; import Expression from '../../../nodes/shared/Expression';
import Text from '../../../nodes/Text'; import Text from '../../../nodes/Text';
@ -32,12 +32,10 @@ export default class StyleAttributeWrapper extends AttributeWrapper {
value = prop.value value = prop.value
.map(chunk => { .map(chunk => {
if (chunk.type === 'Text') { if (chunk.type === 'Text') {
return stringify(chunk.data); return string_literal(chunk.data);
} else { } else {
const snippet = chunk.manipulate(block);
add_to_set(prop_dependencies, chunk.dynamic_dependencies()); add_to_set(prop_dependencies, chunk.dynamic_dependencies());
return snippet; return chunk.manipulate(block);
} }
}) })
.reduce((lhs, rhs) => x`${lhs} + ${rhs}`) .reduce((lhs, rhs) => x`${lhs} + ${rhs}`)
@ -61,11 +59,11 @@ export default class StyleAttributeWrapper extends AttributeWrapper {
block.chunks.update.push(update); block.chunks.update.push(update);
} }
} else { } else {
value = stringify((prop.value[0] as Text).data); value = string_literal((prop.value[0] as Text).data);
} }
block.chunks.hydrate.push( block.chunks.hydrate.push(
b`@set_style(${this.parent.var}, "${prop.key}", ${value}, ${prop.important ? 1 : ''});` b`@set_style(${this.parent.var}, "${prop.key}", ${value}, ${prop.important ? 1 : null});`
); );
}); });
} }

@ -480,8 +480,21 @@ export default class ElementWrapper extends Wrapper {
callee = x`#ctx.${handler}`; callee = x`#ctx.${handler}`;
} }
const arg = contextual_dependencies.size > 0 && {
type: 'ObjectPattern',
properties: Array.from(contextual_dependencies).map(name => {
const id = { type: 'Identifier', name };
return {
type: 'Property',
kind: 'init',
key: id,
value: id
};
})
};
this.renderer.component.partly_hoisted.push(b` this.renderer.component.partly_hoisted.push(b`
function ${handler}(${contextual_dependencies.size > 0 ? `{ ${Array.from(contextual_dependencies).join(', ')} }` : ``}) { function ${handler}(${arg}) {
${group.bindings.map(b => b.handler.mutation)} ${group.bindings.map(b => b.handler.mutation)}
${Array.from(dependencies).filter(dep => dep[0] !== '$').map(dep => b`${this.renderer.component.invalidate(dep)};`)} ${Array.from(dependencies).filter(dep => dep[0] !== '$').map(dep => b`${this.renderer.component.invalidate(dep)};`)}
} }
@ -774,10 +787,10 @@ export default class ElementWrapper extends Wrapper {
block.chunks.fix.push(b` block.chunks.fix.push(b`
@fix_position(${this.var}); @fix_position(${this.var});
${stop_animation}(); ${stop_animation}();
${outro && `@add_transform(${this.var}, ${rect});`} ${outro && b`@add_transform(${this.var}, ${rect});`}
`); `);
const params = this.node.animation.expression ? this.node.animation.expression.manipulate(block) : '{}'; const params = this.node.animation.expression ? this.node.animation.expression.manipulate(block) : x`{}`;
const name = component.qualify(this.node.animation.name); const name = component.qualify(this.node.animation.name);

@ -27,7 +27,7 @@ export default class RawMustacheTagWrapper extends Tag {
const can_use_innerhtml = !in_head && parent_node && !this.prev && !this.next; const can_use_innerhtml = !in_head && parent_node && !this.prev && !this.next;
if (can_use_innerhtml) { if (can_use_innerhtml) {
const insert = content => b`${parent_node}.innerHTML = ${content};`; const insert = content => b`${parent_node}.innerHTML = ${content};`[0];
const { init } = this.rename_this_method( const { init } = this.rename_this_method(
block, block,

@ -25,14 +25,14 @@ export default function bind_this(component: Component, block: Block, binding: B
const { snippet } = block.bindings.get(name); const { snippet } = block.bindings.get(name);
lhs = snippet; lhs = snippet;
body = `${lhs} = $$value`; // TODO we need to invalidate... something body = b`${lhs} = $$value`; // TODO we need to invalidate... something
} else { } else {
object = flatten_reference(binding.expression.node).name; object = flatten_reference(binding.expression.node).name;
lhs = component.source.slice(binding.expression.node.start, binding.expression.node.end).trim(); lhs = component.source.slice(binding.expression.node.start, binding.expression.node.end).trim();
body = binding.expression.node.type === 'Identifier' body = binding.expression.node.type === 'Identifier'
? b` ? b`
${component.invalidate(object, `${lhs} = $$value`)}; ${component.invalidate(object, x`${lhs} = $$value`)};
` `
: b` : b`
${lhs} = $$value; ${lhs} = $$value;

@ -104,7 +104,7 @@ export function is_void(name: string) {
return void_element_names.test(name) || name.toLowerCase() === '!doctype'; return void_element_names.test(name) || name.toLowerCase() === '!doctype';
} }
function is_valid(str: string): boolean { export function is_valid(str: string): boolean {
let i = 0; let i = 0;
while (i < str.length) { while (i < str.length) {

Loading…
Cancel
Save