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

6
package-lock.json generated

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

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

@ -2,7 +2,7 @@
import { walk, childKeys } from 'estree-walker';
import { getLocator } from 'locate-character';
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 create_module from './create_module';
import {
@ -24,7 +24,7 @@ import TemplateScope from './nodes/shared/TemplateScope';
import fuzzymatch from '../utils/fuzzymatch';
import get_object from './utils/get_object';
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 check_graph_for_cycles from './utils/check_graph_for_cycles';
import { print, x } from 'code-red';
@ -285,24 +285,44 @@ export default class Component {
const program: any = { type: 'Program', body: result };
walk(program, {
enter: (node) => {
enter: (node, parent, key) => {
if (node.type === 'Identifier' && !('name' in node)) {
console.log(node);
throw new Error('wtf');
}
if (node.type === 'Identifier' && node.name[0] === '@') {
// TODO temp
if (!/@\w+$/.test(node.name)) {
throw new Error(`wut "${node.name}"`);
if (node.type === 'Identifier') {
if (node.name[0] === '@') {
// TODO temp
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] === '_') {
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;
else if (node.name[0] !== '#' && !is_valid(node.name)) {
// this hack allows x`foo.${bar}` where bar could be invalid
const literal: Literal = { type: 'Literal', value: node.name };
if (parent.type === 'Property' && key === 'key') {
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`
function ${add_css}() {
var style = @element("style");
style.id = '${component.stylesheet.id}-style';
style.textContent = ${styles};
style.id = "${component.stylesheet.id}-style";
style.textContent = "${styles}";
@append(@_document.head, style);
}
`);
@ -84,7 +84,7 @@ export default function dom(
${$$props} => {
${uses_props && component.invalidate('$$props', x`$$props = @assign(@assign({}, $$props), $$new_props)`)}
${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 &&
b`if ('$$scope' in ${$$props}) ${component.invalidate('$$scope', x`$$scope = ${$$props}.$$scope`)};`}
@ -160,7 +160,7 @@ export default function dom(
if (expected.length) {
dev_props_check = b`
const { ctx } = this.$$;
const { ctx: #ctx } = this.$$;
const props = ${options.customElement ? `this.attributes` : `options.props || {}`};
${expected.map(prop => b`
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`
() => {
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`
() => {
@ -184,7 +184,7 @@ export default function dom(
${$$props} => {
${uses_props && component.invalidate('$$props', x`$$props = @assign(@assign({}, $$props), $$new_props)`)}
${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`
@ -327,13 +327,14 @@ export default function dom(
const dependencies = Array.from(d.dependencies);
const uses_props = !!dependencies.find(n => n === '$$props');
const condition = !uses_props && dependencies
.filter(n => {
const variable = component.var_lookup.get(n);
return variable && (variable.writable || variable.mutated);
})
const writable = dependencies.filter(n => {
const variable = component.var_lookup.get(n);
return variable && (variable.writable || variable.mutated);
});
const condition = !uses_props && writable.length > 0 && (writable
.map(n => x`$$dirty.${n}`)
.reduce((lhs, rhs) => x`${lhs} || ${rhs}`);
.reduce((lhs, rhs) => x`${lhs} || ${rhs}`));
let statement = d.node;
if (condition) statement = b`if (${condition}) { ${statement} }`[0];
@ -405,7 +406,7 @@ export default function dom(
${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}

@ -395,7 +395,7 @@ export default class EachBlockWrapper extends Wrapper {
${this.block.has_outros && b`@group_outros();`}
${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.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;
@ -529,7 +529,7 @@ export default class EachBlockWrapper extends Wrapper {
`;
} else {
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);
}
${!fixed_length && b`${view_length} = ${data_length};`}

@ -3,7 +3,7 @@ import Attribute from '../../../nodes/Attribute';
import Block from '../../Block';
import AttributeWrapper from './Attribute';
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 Expression from '../../../nodes/shared/Expression';
import Text from '../../../nodes/Text';
@ -32,12 +32,10 @@ export default class StyleAttributeWrapper extends AttributeWrapper {
value = prop.value
.map(chunk => {
if (chunk.type === 'Text') {
return stringify(chunk.data);
return string_literal(chunk.data);
} else {
const snippet = chunk.manipulate(block);
add_to_set(prop_dependencies, chunk.dynamic_dependencies());
return snippet;
return chunk.manipulate(block);
}
})
.reduce((lhs, rhs) => x`${lhs} + ${rhs}`)
@ -61,11 +59,11 @@ export default class StyleAttributeWrapper extends AttributeWrapper {
block.chunks.update.push(update);
}
} else {
value = stringify((prop.value[0] as Text).data);
value = string_literal((prop.value[0] as Text).data);
}
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}`;
}
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`
function ${handler}(${contextual_dependencies.size > 0 ? `{ ${Array.from(contextual_dependencies).join(', ')} }` : ``}) {
function ${handler}(${arg}) {
${group.bindings.map(b => b.handler.mutation)}
${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`
@fix_position(${this.var});
${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);

@ -27,7 +27,7 @@ export default class RawMustacheTagWrapper extends Tag {
const can_use_innerhtml = !in_head && parent_node && !this.prev && !this.next;
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(
block,

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

@ -104,7 +104,7 @@ export function is_void(name: string) {
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;
while (i < str.length) {

Loading…
Cancel
Save