Merge pull request #3808 from tanhauhau/tanhauhau/mustache-tag-can-use-inner-html

feat: allow innerHtml if no dynamic dependencies
pull/3810/head
Rich Harris 5 years ago committed by GitHub
commit 67bcc05740
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -6,6 +6,7 @@ import { is_void, sanitize } from '../../../../utils/names';
import FragmentWrapper from '../Fragment'; import FragmentWrapper from '../Fragment';
import { escape_html, string_literal } from '../../../utils/stringify'; import { escape_html, string_literal } from '../../../utils/stringify';
import TextWrapper from '../Text'; import TextWrapper from '../Text';
import TagWrapper from '../shared/Tag';
import fix_attribute_casing from './fix_attribute_casing'; import fix_attribute_casing from './fix_attribute_casing';
import { b, x, p } from 'code-red'; import { b, x, p } from 'code-red';
import { namespaces } from '../../../../utils/namespaces'; import { namespaces } from '../../../../utils/namespaces';
@ -849,7 +850,7 @@ export default class ElementWrapper extends Wrapper {
} }
} }
function to_html(wrappers: Array<ElementWrapper | TextWrapper>, block: Block, literal: any, state: any) { function to_html(wrappers: Array<ElementWrapper | TextWrapper | TagWrapper>, block: Block, literal: any, state: any) {
wrappers.forEach(wrapper => { wrappers.forEach(wrapper => {
if (wrapper.node.type === 'Text') { if (wrapper.node.type === 'Text') {
if ((wrapper as TextWrapper).use_space()) state.quasi.value.raw += ' '; if ((wrapper as TextWrapper).use_space()) state.quasi.value.raw += ' ';
@ -867,6 +868,15 @@ function to_html(wrappers: Array<ElementWrapper | TextWrapper>, block: Block, li
.replace(/\$/g, '\\$'); .replace(/\$/g, '\\$');
} }
else if (wrapper.node.type === 'MustacheTag' || wrapper.node.type === 'RawMustacheTag' ) {
literal.quasis.push(state.quasi);
literal.expressions.push(wrapper.node.expression.manipulate(block));
state.quasi = {
type: 'TemplateElement',
value: { raw: '' }
};
}
else if (wrapper.node.name === 'noscript') { else if (wrapper.node.name === 'noscript') {
// do nothing // do nothing
} }

@ -12,7 +12,6 @@ export default class MustacheTagWrapper extends Tag {
constructor(renderer: Renderer, block: Block, parent: Wrapper, node: MustacheTag | RawMustacheTag) { constructor(renderer: Renderer, block: Block, parent: Wrapper, node: MustacheTag | RawMustacheTag) {
super(renderer, block, parent, node); super(renderer, block, parent, node);
this.cannot_use_innerhtml();
} }
render(block: Block, parent_node: Identifier, parent_nodes: Identifier) { render(block: Block, parent_node: Identifier, parent_nodes: Identifier) {

@ -11,11 +11,17 @@ export default class Tag extends Wrapper {
constructor(renderer: Renderer, block: Block, parent: Wrapper, node: MustacheTag | RawMustacheTag) { constructor(renderer: Renderer, block: Block, parent: Wrapper, node: MustacheTag | RawMustacheTag) {
super(renderer, block, parent, node); super(renderer, block, parent, node);
this.cannot_use_innerhtml(); if (!this.is_dependencies_static()) {
this.cannot_use_innerhtml();
}
block.add_dependencies(node.expression.dependencies); block.add_dependencies(node.expression.dependencies);
} }
is_dependencies_static() {
return this.node.expression.contextual_dependencies.size === 0 && this.node.expression.dynamic_dependencies().length === 0;
}
rename_this_method( rename_this_method(
block: Block, block: Block,
update: ((value: Node) => (Node | Node[])) update: ((value: Node) => (Node | Node[]))

@ -1,28 +1,23 @@
import { import {
SvelteComponent, SvelteComponent,
append,
detach, detach,
element, element,
init, init,
insert, insert,
noop, noop,
safe_not_equal, safe_not_equal
text
} from "svelte/internal"; } from "svelte/internal";
function create_fragment(ctx) { function create_fragment(ctx) {
let b; let b;
let t_value = get_answer() + "";
let t;
return { return {
c() { c() {
b = element("b"); b = element("b");
t = text(t_value); b.innerHTML = `${get_answer()}`;
}, },
m(target, anchor) { m(target, anchor) {
insert(target, b, anchor); insert(target, b, anchor);
append(b, t);
}, },
p: noop, p: noop,
i: noop, i: noop,

@ -1,28 +1,23 @@
import { import {
SvelteComponent, SvelteComponent,
append,
detach, detach,
element, element,
init, init,
insert, insert,
noop, noop,
safe_not_equal, safe_not_equal
text
} from "svelte/internal"; } from "svelte/internal";
function create_fragment(ctx) { function create_fragment(ctx) {
let b; let b;
let t_value = get_answer() + "";
let t;
return { return {
c() { c() {
b = element("b"); b = element("b");
t = text(t_value); b.innerHTML = `${get_answer()}`;
}, },
m(target, anchor) { m(target, anchor) {
insert(target, b, anchor); insert(target, b, anchor);
append(b, t);
}, },
p: noop, p: noop,
i: noop, i: noop,

@ -1,33 +1,23 @@
import { import {
SvelteComponent, SvelteComponent,
append,
detach, detach,
element, element,
init, init,
insert, insert,
noop, noop,
safe_not_equal, safe_not_equal
text
} from "svelte/internal"; } from "svelte/internal";
function create_fragment(ctx) { function create_fragment(ctx) {
let h1; let h1;
let t0;
let t1;
let t2;
return { return {
c() { c() {
h1 = element("h1"); h1 = element("h1");
t0 = text("Hello "); h1.innerHTML = `Hello ${name}!`;
t1 = text(name);
t2 = text("!");
}, },
m(target, anchor) { m(target, anchor) {
insert(target, h1, anchor); insert(target, h1, anchor);
append(h1, t0);
append(h1, t1);
append(h1, t2);
}, },
p: noop, p: noop,
i: noop, i: noop,

@ -0,0 +1,78 @@
import {
SvelteComponent,
append,
detach,
element,
init,
insert,
noop,
safe_not_equal,
set_data,
space,
text
} from "svelte/internal";
function create_fragment(ctx) {
let div0;
let t7;
let div1;
let p3;
let t8;
let t9;
return {
c() {
div0 = element("div");
div0.innerHTML = `<p>Hello world</p>
<p>Hello ${world1}</p>
<p>Hello ${world2}</p>`;
t7 = space();
div1 = element("div");
p3 = element("p");
t8 = text("Hello ");
t9 = text(ctx.world3);
},
m(target, anchor) {
insert(target, div0, anchor);
insert(target, t7, anchor);
insert(target, div1, anchor);
append(div1, p3);
append(p3, t8);
append(p3, t9);
},
p(changed, ctx) {
if (changed.world3) set_data(t9, ctx.world3);
},
i: noop,
o: noop,
d(detaching) {
if (detaching) detach(div0);
if (detaching) detach(t7);
if (detaching) detach(div1);
}
};
}
let world1 = "world";
let world2 = "world";
function instance($$self, $$props, $$invalidate) {
const world3 = "world";
function foo() {
$$invalidate("world3", world3 = "svelte");
}
return { world3 };
}
class Component extends SvelteComponent {
constructor(options) {
super();
init(this, options, instance, create_fragment, safe_not_equal, []);
}
}
export default Component;

@ -0,0 +1,17 @@
<script>
let world1 = 'world';
let world2 = 'world';
const world3 = 'world';
function foo() {
world3 = 'svelte';
}
</script>
<div>
<p>Hello world</p>
<p>Hello {world1}</p>
<p>Hello {world2}</p>
</div>
<div>
<p>Hello {world3}</p>
</div>

@ -166,7 +166,8 @@ describe("runtime", () => {
mod, mod,
target, target,
window, window,
raf raf,
compileOptions
})).then(() => { })).then(() => {
component.$destroy(); component.$destroy();

@ -3,26 +3,47 @@ import order from './order.js';
export default { export default {
skip_if_ssr: true, skip_if_ssr: true,
test({ assert, component, target }) { test({ assert, component, target, compileOptions }) {
assert.deepEqual(order, [ if (compileOptions.hydratable) {
'0: beforeUpdate', assert.deepEqual(order, [
'0: render', '0: beforeUpdate',
'1: beforeUpdate', '0: render',
'1: render', '1: beforeUpdate',
'2: beforeUpdate', '1: render',
'2: render', '2: beforeUpdate',
'3: beforeUpdate', '2: render',
'3: render', '3: beforeUpdate',
'1: onMount', '3: render',
'1: afterUpdate', '1: onMount',
'2: onMount', '1: afterUpdate',
'2: afterUpdate', '2: onMount',
'3: onMount', '2: afterUpdate',
'3: afterUpdate', '3: onMount',
'0: onMount', '3: afterUpdate',
'0: afterUpdate' '0: onMount',
]); '0: afterUpdate',
]);
} else {
assert.deepEqual(order, [
'0: beforeUpdate',
'0: render',
'1: beforeUpdate',
'2: beforeUpdate',
'3: beforeUpdate',
'1: render',
'2: render',
'3: render',
'1: onMount',
'1: afterUpdate',
'2: onMount',
'2: afterUpdate',
'3: onMount',
'3: afterUpdate',
'0: onMount',
'0: afterUpdate',
]);
}
order.length = 0; order.length = 0;
} },
}; };

Loading…
Cancel
Save