mirror of https://github.com/sveltejs/svelte
`{@strict text}` will only update the text node if the text node's value is not equal. This is only needed (from what I can tell) in contenteditable situations where the user can update the text and the text must catch up. See https://v3.svelte.technology/repl?version=3.0.0-beta.22&gist=93c7a0c8399348d8e9a86964aef9f8fb for a bit more about this.pull/2341/head
parent
a824a6dd6f
commit
fad119e3ac
@ -0,0 +1,3 @@
|
|||||||
|
import Tag from './shared/Tag';
|
||||||
|
|
||||||
|
export default class StrictMustacheTag extends Tag {}
|
@ -0,0 +1,28 @@
|
|||||||
|
import Renderer from '../Renderer';
|
||||||
|
import Block from '../Block';
|
||||||
|
import Node from '../../nodes/shared/Node';
|
||||||
|
import Tag from './shared/Tag';
|
||||||
|
import Wrapper from './shared/Wrapper';
|
||||||
|
|
||||||
|
export default class StrictMustacheTagWrapper extends Tag {
|
||||||
|
var = 't';
|
||||||
|
|
||||||
|
constructor(renderer: Renderer, block: Block, parent: Wrapper, node: Node) {
|
||||||
|
super(renderer, block, parent, node);
|
||||||
|
this.cannot_use_innerhtml();
|
||||||
|
}
|
||||||
|
|
||||||
|
render(block: Block, parent_node: string, parent_nodes: string) {
|
||||||
|
const { init } = this.rename_this_method(
|
||||||
|
block,
|
||||||
|
value => `@set_data_strict(${this.var}, ${value});`
|
||||||
|
);
|
||||||
|
|
||||||
|
block.add_element(
|
||||||
|
this.var,
|
||||||
|
`@text(${init})`,
|
||||||
|
parent_nodes && `@claim_text(${parent_nodes}, ${init})`,
|
||||||
|
parent_node
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,49 @@
|
|||||||
|
export default {
|
||||||
|
skip_if_ssr: true,
|
||||||
|
|
||||||
|
props: {
|
||||||
|
text: 'test'
|
||||||
|
},
|
||||||
|
|
||||||
|
html: '<div>beforetestafter</div>',
|
||||||
|
|
||||||
|
test({ assert, component, target }) {
|
||||||
|
const text = component.container.childNodes[1];
|
||||||
|
text.data += 'ing';
|
||||||
|
|
||||||
|
assert.equal(target.innerHTML, '<div>beforetestingafter</div>');
|
||||||
|
|
||||||
|
// Track when .data is set on text
|
||||||
|
let get, set, proto = text.__proto__;
|
||||||
|
while (proto) {
|
||||||
|
const descriptor = Object.getOwnPropertyDescriptor(proto, 'data');
|
||||||
|
if (descriptor) {
|
||||||
|
get = descriptor.get;
|
||||||
|
set = descriptor.set;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
proto = proto.__proto__;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!get || !set) throw new Error('Could not get the getter/setter for data');
|
||||||
|
let setValue;
|
||||||
|
|
||||||
|
Object.defineProperty(text, 'data', {
|
||||||
|
get,
|
||||||
|
set(value) {
|
||||||
|
console.log('SETTING VALUE:', value);
|
||||||
|
setValue = value;
|
||||||
|
set.call(this, value);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
component.text += 'ing';
|
||||||
|
assert.equal(setValue, undefined);
|
||||||
|
|
||||||
|
component.text += '!';
|
||||||
|
assert.equal(setValue, 'testing!');
|
||||||
|
|
||||||
|
component.$destroy();
|
||||||
|
assert.equal(target.innerHTML, '');
|
||||||
|
}
|
||||||
|
};
|
@ -0,0 +1,8 @@
|
|||||||
|
<script>
|
||||||
|
export let text;
|
||||||
|
export let container = null;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div bind:this={container}>
|
||||||
|
before{@strict text}after
|
||||||
|
</div>
|
Loading…
Reference in new issue