get a few more tests passing

pull/1746/head
Rich Harris 7 years ago
parent fa19cb3b42
commit 54045f43c8

@ -110,6 +110,8 @@ export default class Block {
const dupes = new Set();
this.wrappers.forEach(wrapper => {
if (wrapper.parent && wrapper.parent.canUseInnerHTML) return;
if (seen.has(wrapper.var)) {
dupes.add(wrapper.var);
}
@ -121,7 +123,7 @@ export default class Block {
this.wrappers.forEach(wrapper => {
if (dupes.has(wrapper.var)) {
const i = counts.get(wrapper.var);
const i = counts.get(wrapper.var) || 0;
wrapper.var = this.getUniqueName(wrapper.var + i);
counts.set(wrapper.var, i + 1);
} else {

@ -10,21 +10,25 @@ export default class AttributeWrapper {
constructor(node: Attribute, parent: ElementWrapper) {
this.node = node;
this.parent = parent;
if (node.dependencies.size > 0) {
parent.cannotUseInnerHTML();
}
}
render(block: Block) {
const element = this.parent;
const name = fixAttributeCasing(this.node.name);
let metadata = element.namespace ? null : attributeLookup[name];
let metadata = element.node.namespace ? null : attributeLookup[name];
if (metadata && metadata.appliesTo && !~metadata.appliesTo.indexOf(element.node.name))
metadata = null;
const isIndirectlyBoundValue =
name === 'value' &&
(element.name === 'option' || // TODO check it's actually bound
(element.name === 'input' &&
element.bindings.find(
(element.node.name === 'option' || // TODO check it's actually bound
(element.node.name === 'input' &&
element.node.bindings.find(
(binding: Binding) =>
/checked|group/.test(binding.name)
)));
@ -36,7 +40,7 @@ export default class AttributeWrapper {
// xlink is a special case... we could maybe extend this to generic
// namespaced attributes but I'm not sure that's applicable in
// HTML5?
const method = /-/.test(element.name)
const method = /-/.test(element.node.name)
? '@setCustomElementData'
: name.slice(0, 6) === 'xlink:'
? '@setXlinkAttribute'
@ -44,7 +48,7 @@ export default class AttributeWrapper {
const isLegacyInputType = element.renderer.component.options.legacy && name === 'type' && this.parent.name === 'input';
const isDataSet = /^data-/.test(name) && !element.renderer.component.options.legacy && !element.namespace;
const isDataSet = /^data-/.test(name) && !element.renderer.component.options.legacy && !element.node.namespace;
const camelCaseName = isDataSet ? name.replace('data-', '').replace(/(-\w)/g, function (m) {
return m[1].toUpperCase();
}) : name;
@ -75,7 +79,7 @@ export default class AttributeWrapper {
}
const isSelectValueAttribute =
name === 'value' && element.name === 'select';
name === 'value' && element.node.name === 'select';
const shouldCache = this.shouldCache || isSelectValueAttribute;
@ -183,6 +187,19 @@ export default class AttributeWrapper {
if (this.node.isDynamic) block.builders.update.addLine(updateValue);
}
}
stringify() {
const value = this.node.chunks;
if (value === true) return '';
if (value.length === 0) return `=""`;
return `="${value.map(chunk => {
return chunk.type === 'Text'
? chunk.data.replace(/"/g, '\\"')
: `\${${chunk.snippet}}`
})}"`;
}
}
// source: https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes

@ -14,10 +14,6 @@ export default class StyleAttributeWrapper extends AttributeWrapper {
node: Attribute;
parent: ElementWrapper;
constructor(node: Attribute, parent: ElementWrapper) {
super(node, parent);
}
render(block: Block) {
const styleProps = optimizeStyle(this.node.chunks);
if (!styleProps) return super.render(block);

@ -7,7 +7,7 @@ import { CompileOptions } from '../../../../interfaces';
import { quotePropIfNecessary, quoteNameIfNecessary } from '../../../../utils/quoteIfNecessary';
import isVoidElementName from '../../../../utils/isVoidElementName';
import FragmentWrapper from '../Fragment';
import { stringify, escapeHTML } from '../../../../utils/stringify';
import { stringify, escapeHTML, escape } from '../../../../utils/stringify';
import TextWrapper from '../Text';
import fixAttributeCasing from '../../../../utils/fixAttributeCasing';
import deindent from '../../../../utils/deindent';
@ -108,7 +108,7 @@ export default class ElementWrapper extends Wrapper {
);
} else {
block.builders.create.addLine(
`${node}.innerHTML = ${stringify(this.fragment.nodes.map(toHTML).join(''))};`
`${node}.innerHTML = \`${escape(this.fragment.nodes.map(toHTML).join(''))}\`;`
);
}
} else {
@ -193,8 +193,8 @@ export default class ElementWrapper extends Wrapper {
let open = `<${wrapper.node.name}`;
(<ElementWrapper>wrapper).node.attributes.forEach((attr: Node) => {
open += ` ${fixAttributeCasing(attr.name)}${stringifyAttributeValue(attr.chunks)}`
(<ElementWrapper>wrapper).attributes.forEach((attr: AttributeWrapper) => {
open += ` ${fixAttributeCasing(attr.node.name)}${attr.stringify()}`
});
if (isVoidElementName(wrapper.node.name)) return open + '>';
@ -748,12 +748,4 @@ export default class ElementWrapper extends Wrapper {
);
}
}
}
function stringifyAttributeValue(value: Node[] | true) {
if (value === true) return '';
if (value.length === 0) return `=""`;
const data = value[0].data;
return `=${JSON.stringify(data)}`;
}

@ -32,6 +32,7 @@ function shouldSkip(node: Text) {
export default class TextWrapper extends Wrapper {
node: Text;
skip: boolean;
var: string;
constructor(
@ -41,10 +42,14 @@ export default class TextWrapper extends Wrapper {
node: Text
) {
super(renderer, block, parent, node);
this.var = 'text';
this.skip = shouldSkip(this.node);
this.var = this.skip ? null : 'text';
}
render(block: Block, parentNode: string, parentNodes: string) {
if (this.skip) return;
block.addElement(
this.var,
`@createText(${stringify(this.node.data)})`,

@ -25,7 +25,7 @@ function getName(filename) {
return base[0].toUpperCase() + base.slice(1);
}
describe("runtime", () => {
describe.only("runtime", () => {
before(() => {
svelte = loadSvelte(false);
svelte$ = loadSvelte(true);

Loading…
Cancel
Save