From c9304554d3893459e2dee382861394edcfbb4528 Mon Sep 17 00:00:00 2001
From: suxin2017 <1107178482@qq.com>
Date: Fri, 29 Jan 2021 14:24:58 +0800
Subject: [PATCH 01/14] fix: same-text-no-update
---
src/compiler/compile/render_dom/index.ts | 1 -
src/runtime/internal/dev.ts | 2 +-
src/runtime/internal/dom.ts | 2 +-
3 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/src/compiler/compile/render_dom/index.ts b/src/compiler/compile/render_dom/index.ts
index 3b1f873ba501..99e5f112abcc 100644
--- a/src/compiler/compile/render_dom/index.ts
+++ b/src/compiler/compile/render_dom/index.ts
@@ -549,7 +549,6 @@ export default function dom(
body.push(declaration);
}
-
return { js: flatten(body, []), css };
}
diff --git a/src/runtime/internal/dev.ts b/src/runtime/internal/dev.ts
index 53f6ef3bf1ba..cd61ec98d62d 100644
--- a/src/runtime/internal/dev.ts
+++ b/src/runtime/internal/dev.ts
@@ -73,7 +73,7 @@ export function dataset_dev(node: HTMLElement, property: string, value?: any) {
export function set_data_dev(text, data) {
data = '' + data;
- if (text.wholeText === data) return;
+ if (text === data) return;
dispatch_dev('SvelteDOMSetData', { node: text, data });
text.data = data;
diff --git a/src/runtime/internal/dom.ts b/src/runtime/internal/dom.ts
index 8d99234c9de2..663cc27ca062 100644
--- a/src/runtime/internal/dom.ts
+++ b/src/runtime/internal/dom.ts
@@ -193,7 +193,7 @@ export function claim_space(nodes) {
export function set_data(text, data) {
data = '' + data;
- if (text.wholeText !== data) text.data = data;
+ if (text !== data) text.data = data;
}
export function set_input_value(input, value) {
From fbf0ed926b82104ef680a7c17808d503af9c20d6 Mon Sep 17 00:00:00 2001
From: suxin2017 <1107178482@qq.com>
Date: Fri, 29 Jan 2021 20:56:22 +0800
Subject: [PATCH 02/14] fix: same-text-no-update
---
src/runtime/internal/dev.ts | 9 +++++++--
src/runtime/internal/dom.ts | 2 +-
2 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/src/runtime/internal/dev.ts b/src/runtime/internal/dev.ts
index cd61ec98d62d..bc7f39a8d603 100644
--- a/src/runtime/internal/dev.ts
+++ b/src/runtime/internal/dev.ts
@@ -73,8 +73,13 @@ export function dataset_dev(node: HTMLElement, property: string, value?: any) {
export function set_data_dev(text, data) {
data = '' + data;
- if (text === data) return;
-
+ // In particular, when the property is contentEditable, ' 'TEXT_NODE is inserted into the text
+ if (text.textContent === '' && text.wholeText !== '') {
+ if (text.wholeText === data) return;
+ } else {
+ if (text.textContent === data) return;
+ }
+
dispatch_dev('SvelteDOMSetData', { node: text, data });
text.data = data;
}
diff --git a/src/runtime/internal/dom.ts b/src/runtime/internal/dom.ts
index 663cc27ca062..8d99234c9de2 100644
--- a/src/runtime/internal/dom.ts
+++ b/src/runtime/internal/dom.ts
@@ -193,7 +193,7 @@ export function claim_space(nodes) {
export function set_data(text, data) {
data = '' + data;
- if (text !== data) text.data = data;
+ if (text.wholeText !== data) text.data = data;
}
export function set_input_value(input, value) {
From 6bbacfbd15c65d8a63c92a2fecb431d8e9269f1e Mon Sep 17 00:00:00 2001
From: suxin2017 <1107178482@qq.com>
Date: Fri, 29 Jan 2021 20:57:17 +0800
Subject: [PATCH 03/14] chore: a problem
---
src/runtime/internal/dom.ts | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/runtime/internal/dom.ts b/src/runtime/internal/dom.ts
index 8d99234c9de2..234eca90a48b 100644
--- a/src/runtime/internal/dom.ts
+++ b/src/runtime/internal/dom.ts
@@ -193,6 +193,7 @@ export function claim_space(nodes) {
export function set_data(text, data) {
data = '' + data;
+ // ??? I'm not sure if I need to change this
if (text.wholeText !== data) text.data = data;
}
From c257ff124296e2ce14fd2e626c58743ad0a216f6 Mon Sep 17 00:00:00 2001
From: suxin2017 <1107178482@qq.com>
Date: Fri, 29 Jan 2021 20:59:50 +0800
Subject: [PATCH 04/14] fix: empty fix
---
src/compiler/compile/render_dom/index.ts | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/compiler/compile/render_dom/index.ts b/src/compiler/compile/render_dom/index.ts
index 99e5f112abcc..c19a5c3cdd08 100644
--- a/src/compiler/compile/render_dom/index.ts
+++ b/src/compiler/compile/render_dom/index.ts
@@ -549,6 +549,7 @@ export default function dom(
body.push(declaration);
}
+
return { js: flatten(body, []), css };
}
From 3caa3a7f295c850a027757491080eb14451bfe93 Mon Sep 17 00:00:00 2001
From: suxin2017 <1107178482@qq.com>
Date: Sat, 30 Jan 2021 09:00:05 +0800
Subject: [PATCH 05/14] feat: add reactive-values-text-node test case
---
src/runtime/internal/dom.ts | 9 +++++++--
.../runtime/samples/reactive-values-text-node/_config.js | 9 +++++++++
.../samples/reactive-values-text-node/main.svelte | 8 ++++++++
3 files changed, 24 insertions(+), 2 deletions(-)
create mode 100644 test/runtime/samples/reactive-values-text-node/_config.js
create mode 100644 test/runtime/samples/reactive-values-text-node/main.svelte
diff --git a/src/runtime/internal/dom.ts b/src/runtime/internal/dom.ts
index 234eca90a48b..1ac39aff5152 100644
--- a/src/runtime/internal/dom.ts
+++ b/src/runtime/internal/dom.ts
@@ -193,8 +193,13 @@ export function claim_space(nodes) {
export function set_data(text, data) {
data = '' + data;
- // ??? I'm not sure if I need to change this
- if (text.wholeText !== data) text.data = data;
+ // In particular, when the property is contentEditable, ' 'TEXT_NODE is inserted into the text
+ if (text.textContent === '' && text.wholeText !== '') {
+ if (text.wholeText === data) return;
+ } else {
+ if (text.textContent === data) return;
+ }
+ text.data = data;
}
export function set_input_value(input, value) {
diff --git a/test/runtime/samples/reactive-values-text-node/_config.js b/test/runtime/samples/reactive-values-text-node/_config.js
new file mode 100644
index 000000000000..9e0cb2d5d306
--- /dev/null
+++ b/test/runtime/samples/reactive-values-text-node/_config.js
@@ -0,0 +1,9 @@
+export default {
+ html:'
same text
',
+ async test({ assert, component, target }) {
+ await new Promise(f => setTimeout(f, 10));
+ assert.htmlEqual(target.innerHTML, `
+ same text text
+ `);
+ }
+};
diff --git a/test/runtime/samples/reactive-values-text-node/main.svelte b/test/runtime/samples/reactive-values-text-node/main.svelte
new file mode 100644
index 000000000000..1ca11d19f443
--- /dev/null
+++ b/test/runtime/samples/reactive-values-text-node/main.svelte
@@ -0,0 +1,8 @@
+
+
+{text} text
\ No newline at end of file
From a128e3c56fe512ad4f8e28f1bd9c7bfe27bd1597 Mon Sep 17 00:00:00 2001
From: baseballyama
Date: Sat, 18 Mar 2023 16:57:53 +0900
Subject: [PATCH 06/14] fix 5931
---
.../render_dom/wrappers/Element/index.ts | 37 ++++++++++---------
.../render_dom/wrappers/MustacheTag.ts | 30 +++++++++++++--
.../render_dom/wrappers/shared/Wrapper.ts | 2 +-
src/runtime/internal/dev.ts | 10 ++---
src/runtime/internal/dom.ts | 9 ++---
src/runtime/internal/utils.ts | 2 +
.../_config.js | 5 +--
.../_config.js | 12 ++++++
.../main.svelte | 6 +++
.../_config.js | 13 +++++++
.../main.svelte | 9 +++++
.../_config.js | 12 ++++++
.../main.svelte | 6 +++
.../reactive-values-text-node/_config.js | 2 +-
.../reactive-values-text-node/main.svelte | 8 ++--
15 files changed, 122 insertions(+), 41 deletions(-)
create mode 100644 test/runtime/samples/component-event-handler-contenteditable2/_config.js
create mode 100644 test/runtime/samples/component-event-handler-contenteditable2/main.svelte
create mode 100644 test/runtime/samples/component-event-handler-contenteditable3/_config.js
create mode 100644 test/runtime/samples/component-event-handler-contenteditable3/main.svelte
create mode 100644 test/runtime/samples/component-event-handler-contenteditable4/_config.js
create mode 100644 test/runtime/samples/component-event-handler-contenteditable4/main.svelte
diff --git a/src/compiler/compile/render_dom/wrappers/Element/index.ts b/src/compiler/compile/render_dom/wrappers/Element/index.ts
index 1f80cee89cf0..b57d24ae9c5e 100644
--- a/src/compiler/compile/render_dom/wrappers/Element/index.ts
+++ b/src/compiler/compile/render_dom/wrappers/Element/index.ts
@@ -174,6 +174,8 @@ export default class ElementWrapper extends Wrapper {
child_dynamic_element_block?: Block = null;
child_dynamic_element?: ElementWrapper = null;
+ element_data_name = null;
+
constructor(
renderer: Renderer,
block: Block,
@@ -287,6 +289,8 @@ export default class ElementWrapper extends Wrapper {
}
this.fragment = new FragmentWrapper(renderer, block, node.children, this, strip_whitespace, next_sibling);
+
+ this.element_data_name = block.get_unique_name(`${this.var.name}_data`);
}
render(block: Block, parent_node: Identifier, parent_nodes: Identifier) {
@@ -516,7 +520,8 @@ export default class ElementWrapper extends Wrapper {
child.render(
block,
is_template ? x`${node}.content` : node,
- nodes
+ nodes,
+ { element_data_name: this.element_data_name }
);
});
}
@@ -824,7 +829,6 @@ export default class ElementWrapper extends Wrapper {
add_spread_attributes(block: Block) {
const levels = block.get_unique_name(`${this.var.name}_levels`);
- const data = block.get_unique_name(`${this.var.name}_data`);
const initial_props = [];
const updates = [];
@@ -855,9 +859,9 @@ export default class ElementWrapper extends Wrapper {
block.chunks.init.push(b`
let ${levels} = [${initial_props}];
- let ${data} = {};
+ let ${this.element_data_name} = {};
for (let #i = 0; #i < ${levels}.length; #i += 1) {
- ${data} = @assign(${data}, ${levels}[#i]);
+ ${this.element_data_name} = @assign(${this.element_data_name}, ${levels}[#i]);
}
`);
@@ -868,13 +872,13 @@ export default class ElementWrapper extends Wrapper {
? x`@set_dynamic_element_data(${this.node.tag_expr.manipulate(block)})`
: x`@set_attributes`;
- block.chunks.hydrate.push(
- b`${fn}(${this.var}, ${data});`
+ block.chunks.hydrate.unshift(
+ b`${fn}(${this.var}, ${this.element_data_name});`
);
if (this.has_dynamic_attribute) {
- block.chunks.update.push(b`
- ${fn}(${this.var}, ${data} = @get_spread_update(${levels}, [
+ block.chunks.update.unshift(b`
+ ${fn}(${this.var}, ${this.element_data_name} = @get_spread_update(${levels}, [
${updates}
]));
`);
@@ -890,23 +894,23 @@ export default class ElementWrapper extends Wrapper {
}
block.chunks.mount.push(b`
- 'value' in ${data} && (${data}.multiple ? @select_options : @select_option)(${this.var}, ${data}.value);
+ 'value' in ${this.element_data_name} && (${this.element_data_name}.multiple ? @select_options : @select_option)(${this.var}, ${this.element_data_name}.value);
`);
block.chunks.update.push(b`
- if (${block.renderer.dirty(Array.from(dependencies))} && 'value' in ${data}) (${data}.multiple ? @select_options : @select_option)(${this.var}, ${data}.value);
+ if (${block.renderer.dirty(Array.from(dependencies))} && 'value' in ${this.element_data_name}) (${this.element_data_name}.multiple ? @select_options : @select_option)(${this.var}, ${this.element_data_name}.value);
`);
} else if (this.node.name === 'input' && this.attributes.find(attr => attr.node.name === 'value')) {
const type = this.node.get_static_attribute_value('type');
if (type === null || type === '' || type === 'text' || type === 'email' || type === 'password') {
block.chunks.mount.push(b`
- if ('value' in ${data}) {
- ${this.var}.value = ${data}.value;
+ if ('value' in ${this.element_data_name}) {
+ ${this.var}.value = ${this.element_data_name}.value;
}
`);
block.chunks.update.push(b`
- if ('value' in ${data}) {
- ${this.var}.value = ${data}.value;
+ if ('value' in ${this.element_data_name}) {
+ ${this.var}.value = ${this.element_data_name}.value;
}
`);
}
@@ -1220,8 +1224,8 @@ export default class ElementWrapper extends Wrapper {
if (this.dynamic_style_dependencies.size > 0) {
maybe_create_style_changed_var();
// If all dependencies are same as the style attribute dependencies, then we can skip the dirty check
- condition =
- all_deps.size === this.dynamic_style_dependencies.size
+ condition =
+ all_deps.size === this.dynamic_style_dependencies.size
? style_changed_var
: x`${style_changed_var} || ${condition}`;
}
@@ -1232,7 +1236,6 @@ export default class ElementWrapper extends Wrapper {
}
`);
}
-
});
}
diff --git a/src/compiler/compile/render_dom/wrappers/MustacheTag.ts b/src/compiler/compile/render_dom/wrappers/MustacheTag.ts
index ea6634ec803c..cbea2e7bcaa4 100644
--- a/src/compiler/compile/render_dom/wrappers/MustacheTag.ts
+++ b/src/compiler/compile/render_dom/wrappers/MustacheTag.ts
@@ -5,7 +5,9 @@ import Wrapper from './shared/Wrapper';
import MustacheTag from '../../nodes/MustacheTag';
import RawMustacheTag from '../../nodes/RawMustacheTag';
import { x } from 'code-red';
-import { Identifier } from 'estree';
+import { Identifier, Expression } from 'estree';
+import ElementWrapper from './Element';
+import AttributeWrapper from './Element/Attribute';
export default class MustacheTagWrapper extends Tag {
var: Identifier = { type: 'Identifier', name: 't' };
@@ -14,10 +16,32 @@ export default class MustacheTagWrapper extends Tag {
super(renderer, block, parent, node);
}
- render(block: Block, parent_node: Identifier, parent_nodes: Identifier) {
+ render(block: Block, parent_node: Identifier, parent_nodes: Identifier, data: Record | undefined) {
+ const contenteditable =
+ this.parent instanceof ElementWrapper &&
+ this.parent.attributes.filter((a) => a.node.name === 'contenteditable');
+
+ const spread_attres =
+ this.parent instanceof ElementWrapper &&
+ this.parent.attributes.filter((a) => a.node.is_spread);
+
+ let is_contenteditable: Expression | undefined = undefined;
+ if (contenteditable.length > 0) {
+ const value = (contenteditable[0] as AttributeWrapper).get_value(block);
+ is_contenteditable = x`~@contenteditable_truly_values.indexOf(${value})`;
+ } else if (spread_attres.length > 0 && data.element_data_name) {
+ is_contenteditable = x`~@contenteditable_truly_values.indexOf(${data.element_data_name}['contenteditable'])`;
+ }
+
const { init } = this.rename_this_method(
block,
- value => x`@set_data(${this.var}, ${value})`
+ value => {
+ if (is_contenteditable) {
+ return x`@set_data(${this.var}, ${value}, ${is_contenteditable})`;
+ } else {
+ return x`@set_data(${this.var}, ${value})`;
+ }
+ }
);
block.add_element(
diff --git a/src/compiler/compile/render_dom/wrappers/shared/Wrapper.ts b/src/compiler/compile/render_dom/wrappers/shared/Wrapper.ts
index 4bf8c20bd876..53847d887071 100644
--- a/src/compiler/compile/render_dom/wrappers/shared/Wrapper.ts
+++ b/src/compiler/compile/render_dom/wrappers/shared/Wrapper.ts
@@ -85,7 +85,7 @@ export default class Wrapper {
);
}
- render(_block: Block, _parent_node: Identifier, _parent_nodes: Identifier) {
+ render(_block: Block, _parent_node: Identifier, _parent_nodes: Identifier, _data: Record = undefined) {
throw Error('Wrapper class is not renderable');
}
}
diff --git a/src/runtime/internal/dev.ts b/src/runtime/internal/dev.ts
index e092c27ee26c..51547229cd27 100644
--- a/src/runtime/internal/dev.ts
+++ b/src/runtime/internal/dev.ts
@@ -83,17 +83,15 @@ export function dataset_dev(node: HTMLElement, property: string, value?: any) {
dispatch_dev('SvelteDOMSetDataset', { node, property, value });
}
-export function set_data_dev(text, data) {
+export function set_data_dev(text: Text, data: unknown, is_contenteditable: boolean | undefined) {
data = '' + data;
- // In particular, when the property is contentEditable, ' 'TEXT_NODE is inserted into the text
- if (text.textContent === '' && text.wholeText !== '') {
+ if (is_contenteditable) {
if (text.wholeText === data) return;
} else {
- if (text.textContent === data) return;
+ if (text.data === data) return;
}
-
dispatch_dev('SvelteDOMSetData', { node: text, data });
- text.data = data;
+ text.data = (data as string);
}
export function validate_each_argument(arg) {
diff --git a/src/runtime/internal/dom.ts b/src/runtime/internal/dom.ts
index 775c278bbaba..9d220ba8cce2 100644
--- a/src/runtime/internal/dom.ts
+++ b/src/runtime/internal/dom.ts
@@ -581,15 +581,14 @@ export function claim_html_tag(nodes, is_svg: boolean) {
return new HtmlTagHydration(claimed_nodes, is_svg);
}
-export function set_data(text, data) {
+export function set_data(text: Text, data: unknown, is_contenteditable: boolean | undefined) {
data = '' + data;
- // In particular, when the property is contentEditable, ' 'TEXT_NODE is inserted into the text
- if (text.textContent === '' && text.wholeText !== '') {
+ if (is_contenteditable) {
if (text.wholeText === data) return;
} else {
- if (text.textContent === data) return;
+ if (text.data === data) return;
}
- text.data = data;
+ text.data = (data as string);
}
export function set_input_value(input, value) {
diff --git a/src/runtime/internal/utils.ts b/src/runtime/internal/utils.ts
index b1c27a355de1..31623eeaab7b 100644
--- a/src/runtime/internal/utils.ts
+++ b/src/runtime/internal/utils.ts
@@ -194,3 +194,5 @@ export function split_css_unit(value: number | string): [number, string] {
const split = typeof value === 'string' && value.match(/^\s*(-?[\d.]+)([^\s]*)\s*$/);
return split ? [parseFloat(split[1]), split[2] || 'px'] : [value as number, 'px'];
}
+
+export const contenteditable_truly_values = ['', true, 1, 'true', 'contenteditable'];
diff --git a/test/runtime/samples/component-event-handler-contenteditable/_config.js b/test/runtime/samples/component-event-handler-contenteditable/_config.js
index 1628e22d017b..cfd51e500591 100644
--- a/test/runtime/samples/component-event-handler-contenteditable/_config.js
+++ b/test/runtime/samples/component-event-handler-contenteditable/_config.js
@@ -1,7 +1,5 @@
export default {
- html: `
-
- `,
+ html: '',
async test({ assert, target, window }) {
const div = target.querySelector('div');
@@ -9,7 +7,6 @@ export default {
div.insertBefore(text, null);
const event = new window.InputEvent('input');
await div.dispatchEvent(event);
-
assert.equal(div.textContent, 'a');
}
};
diff --git a/test/runtime/samples/component-event-handler-contenteditable2/_config.js b/test/runtime/samples/component-event-handler-contenteditable2/_config.js
new file mode 100644
index 000000000000..10736ec1b2b1
--- /dev/null
+++ b/test/runtime/samples/component-event-handler-contenteditable2/_config.js
@@ -0,0 +1,12 @@
+export default {
+ html: '',
+
+ async test({ assert, target, window }) {
+ const div = target.querySelector('div');
+ const text = window.document.createTextNode('a');
+ div.insertBefore(text, null);
+ const event = new window.InputEvent('input');
+ await div.dispatchEvent(event);
+ assert.equal(div.textContent, 'a');
+ }
+};
diff --git a/test/runtime/samples/component-event-handler-contenteditable2/main.svelte b/test/runtime/samples/component-event-handler-contenteditable2/main.svelte
new file mode 100644
index 000000000000..e540ceff2571
--- /dev/null
+++ b/test/runtime/samples/component-event-handler-contenteditable2/main.svelte
@@ -0,0 +1,6 @@
+
+
+{text}
diff --git a/test/runtime/samples/component-event-handler-contenteditable3/_config.js b/test/runtime/samples/component-event-handler-contenteditable3/_config.js
new file mode 100644
index 000000000000..957be6388b49
--- /dev/null
+++ b/test/runtime/samples/component-event-handler-contenteditable3/_config.js
@@ -0,0 +1,13 @@
+export default {
+ html: '',
+ ssrHtml: '',
+
+ async test({ assert, target, window }) {
+ const div = target.querySelector('div');
+ const text = window.document.createTextNode('a');
+ div.insertBefore(text, null);
+ const event = new window.InputEvent('input');
+ await div.dispatchEvent(event);
+ assert.equal(div.textContent, 'a');
+ }
+};
diff --git a/test/runtime/samples/component-event-handler-contenteditable3/main.svelte b/test/runtime/samples/component-event-handler-contenteditable3/main.svelte
new file mode 100644
index 000000000000..34bc4300e08e
--- /dev/null
+++ b/test/runtime/samples/component-event-handler-contenteditable3/main.svelte
@@ -0,0 +1,9 @@
+
+
+{text}
diff --git a/test/runtime/samples/component-event-handler-contenteditable4/_config.js b/test/runtime/samples/component-event-handler-contenteditable4/_config.js
new file mode 100644
index 000000000000..bc9d65d1c315
--- /dev/null
+++ b/test/runtime/samples/component-event-handler-contenteditable4/_config.js
@@ -0,0 +1,12 @@
+export default {
+ html: '',
+
+ async test({ assert, target, component, window }) {
+ const div = target.querySelector('div');
+ const text = window.document.createTextNode('a');
+ div.insertBefore(text, null);
+ assert.equal(div.textContent, 'a');
+ component.text = 'bcde';
+ assert.equal(div.textContent, 'bcdea');
+ }
+};
diff --git a/test/runtime/samples/component-event-handler-contenteditable4/main.svelte b/test/runtime/samples/component-event-handler-contenteditable4/main.svelte
new file mode 100644
index 000000000000..955592548748
--- /dev/null
+++ b/test/runtime/samples/component-event-handler-contenteditable4/main.svelte
@@ -0,0 +1,6 @@
+
+
+{text}
diff --git a/test/runtime/samples/reactive-values-text-node/_config.js b/test/runtime/samples/reactive-values-text-node/_config.js
index 9e0cb2d5d306..fb859285ddda 100644
--- a/test/runtime/samples/reactive-values-text-node/_config.js
+++ b/test/runtime/samples/reactive-values-text-node/_config.js
@@ -1,6 +1,6 @@
export default {
html:'same text
',
- async test({ assert, component, target }) {
+ async test({ assert, target }) {
await new Promise(f => setTimeout(f, 10));
assert.htmlEqual(target.innerHTML, `
same text text
diff --git a/test/runtime/samples/reactive-values-text-node/main.svelte b/test/runtime/samples/reactive-values-text-node/main.svelte
index 1ca11d19f443..0982622b1a91 100644
--- a/test/runtime/samples/reactive-values-text-node/main.svelte
+++ b/test/runtime/samples/reactive-values-text-node/main.svelte
@@ -1,8 +1,8 @@
-{text} text
\ No newline at end of file
+{text} text
From 535623de61b9ea7da936be12535b11a7b5b40ff8 Mon Sep 17 00:00:00 2001
From: baseballyama
Date: Sun, 19 Mar 2023 00:47:43 +0900
Subject: [PATCH 07/14] refactor and split runtine function
---
.../compile/render_dom/wrappers/MustacheTag.ts | 12 ++++++------
src/runtime/internal/dev.ts | 15 +++++++++------
src/runtime/internal/dom.ts | 16 +++++++++-------
3 files changed, 24 insertions(+), 19 deletions(-)
diff --git a/src/compiler/compile/render_dom/wrappers/MustacheTag.ts b/src/compiler/compile/render_dom/wrappers/MustacheTag.ts
index cbea2e7bcaa4..34edf5378865 100644
--- a/src/compiler/compile/render_dom/wrappers/MustacheTag.ts
+++ b/src/compiler/compile/render_dom/wrappers/MustacheTag.ts
@@ -17,19 +17,19 @@ export default class MustacheTagWrapper extends Tag {
}
render(block: Block, parent_node: Identifier, parent_nodes: Identifier, data: Record | undefined) {
- const contenteditable =
+ const contenteditable_attributes =
this.parent instanceof ElementWrapper &&
this.parent.attributes.filter((a) => a.node.name === 'contenteditable');
- const spread_attres =
+ const spread_attributes =
this.parent instanceof ElementWrapper &&
this.parent.attributes.filter((a) => a.node.is_spread);
let is_contenteditable: Expression | undefined = undefined;
- if (contenteditable.length > 0) {
- const value = (contenteditable[0] as AttributeWrapper).get_value(block);
+ if (contenteditable_attributes.length > 0) {
+ const value = (contenteditable_attributes[0] as AttributeWrapper).get_value(block);
is_contenteditable = x`~@contenteditable_truly_values.indexOf(${value})`;
- } else if (spread_attres.length > 0 && data.element_data_name) {
+ } else if (spread_attributes.length > 0 && data.element_data_name) {
is_contenteditable = x`~@contenteditable_truly_values.indexOf(${data.element_data_name}['contenteditable'])`;
}
@@ -37,7 +37,7 @@ export default class MustacheTagWrapper extends Tag {
block,
value => {
if (is_contenteditable) {
- return x`@set_data(${this.var}, ${value}, ${is_contenteditable})`;
+ return x`@set_data_contenteditable(${this.var}, ${value}, ${is_contenteditable})`;
} else {
return x`@set_data(${this.var}, ${value})`;
}
diff --git a/src/runtime/internal/dev.ts b/src/runtime/internal/dev.ts
index 51547229cd27..8dec822a41ff 100644
--- a/src/runtime/internal/dev.ts
+++ b/src/runtime/internal/dev.ts
@@ -83,13 +83,16 @@ export function dataset_dev(node: HTMLElement, property: string, value?: any) {
dispatch_dev('SvelteDOMSetDataset', { node, property, value });
}
-export function set_data_dev(text: Text, data: unknown, is_contenteditable: boolean | undefined) {
+export function set_data_dev(text: Text, data: unknown) {
data = '' + data;
- if (is_contenteditable) {
- if (text.wholeText === data) return;
- } else {
- if (text.data === data) return;
- }
+ if (text.data === data) return;
+ dispatch_dev('SvelteDOMSetData', { node: text, data });
+ text.data = (data as string);
+}
+
+export function set_data_contenteditable_dev(text: Text, data: unknown) {
+ data = '' + data;
+ if (text.wholeText === data) return;
dispatch_dev('SvelteDOMSetData', { node: text, data });
text.data = (data as string);
}
diff --git a/src/runtime/internal/dom.ts b/src/runtime/internal/dom.ts
index 9d220ba8cce2..4b0b27f62845 100644
--- a/src/runtime/internal/dom.ts
+++ b/src/runtime/internal/dom.ts
@@ -581,14 +581,16 @@ export function claim_html_tag(nodes, is_svg: boolean) {
return new HtmlTagHydration(claimed_nodes, is_svg);
}
-export function set_data(text: Text, data: unknown, is_contenteditable: boolean | undefined) {
+export function set_data(text: Text, data: unknown) {
data = '' + data;
- if (is_contenteditable) {
- if (text.wholeText === data) return;
- } else {
- if (text.data === data) return;
- }
- text.data = (data as string);
+ if (text.data === data) return;
+ text.data = (data as string);
+}
+
+export function set_data_contenteditable(text: Text, data: unknown) {
+ data = '' + data;
+ if (text.wholeText === data) return;
+ text.data = (data as string);
}
export function set_input_value(input, value) {
From 370a8942c3c430515b1180e8dbb6d1f5659931e7 Mon Sep 17 00:00:00 2001
From: Simon Holthausen
Date: Sun, 19 Mar 2023 15:04:47 +0100
Subject: [PATCH 08/14] truthy
---
src/compiler/compile/render_dom/wrappers/MustacheTag.ts | 4 ++--
src/runtime/internal/utils.ts | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/compiler/compile/render_dom/wrappers/MustacheTag.ts b/src/compiler/compile/render_dom/wrappers/MustacheTag.ts
index 34edf5378865..886a964b72a0 100644
--- a/src/compiler/compile/render_dom/wrappers/MustacheTag.ts
+++ b/src/compiler/compile/render_dom/wrappers/MustacheTag.ts
@@ -28,9 +28,9 @@ export default class MustacheTagWrapper extends Tag {
let is_contenteditable: Expression | undefined = undefined;
if (contenteditable_attributes.length > 0) {
const value = (contenteditable_attributes[0] as AttributeWrapper).get_value(block);
- is_contenteditable = x`~@contenteditable_truly_values.indexOf(${value})`;
+ is_contenteditable = x`~@contenteditable_truthy_values.indexOf(${value})`;
} else if (spread_attributes.length > 0 && data.element_data_name) {
- is_contenteditable = x`~@contenteditable_truly_values.indexOf(${data.element_data_name}['contenteditable'])`;
+ is_contenteditable = x`~@contenteditable_truthy_values.indexOf(${data.element_data_name}['contenteditable'])`;
}
const { init } = this.rename_this_method(
diff --git a/src/runtime/internal/utils.ts b/src/runtime/internal/utils.ts
index 31623eeaab7b..192f40140e4c 100644
--- a/src/runtime/internal/utils.ts
+++ b/src/runtime/internal/utils.ts
@@ -195,4 +195,4 @@ export function split_css_unit(value: number | string): [number, string] {
return split ? [parseFloat(split[1]), split[2] || 'px'] : [value as number, 'px'];
}
-export const contenteditable_truly_values = ['', true, 1, 'true', 'contenteditable'];
+export const contenteditable_truthy_values = ['', true, 1, 'true', 'contenteditable'];
From 1a9f56660f29102019093cafb0e7e1e223c785e0 Mon Sep 17 00:00:00 2001
From: Simon Holthausen
Date: Mon, 20 Mar 2023 12:03:35 +0100
Subject: [PATCH 09/14] fix double elementwrapper output in rollup; fix code
---
src/compiler/compile/render_dom/wrappers/Fragment.ts | 2 +-
src/compiler/compile/render_dom/wrappers/MustacheTag.ts | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/compiler/compile/render_dom/wrappers/Fragment.ts b/src/compiler/compile/render_dom/wrappers/Fragment.ts
index 8c633aeb71fd..463c8db24a1b 100644
--- a/src/compiler/compile/render_dom/wrappers/Fragment.ts
+++ b/src/compiler/compile/render_dom/wrappers/Fragment.ts
@@ -4,7 +4,7 @@ import Body from './Body';
import DebugTag from './DebugTag';
import Document from './Document';
import EachBlock from './EachBlock';
-import Element from './Element/index';
+import Element from './Element';
import Head from './Head';
import IfBlock from './IfBlock';
import KeyBlock from './KeyBlock';
diff --git a/src/compiler/compile/render_dom/wrappers/MustacheTag.ts b/src/compiler/compile/render_dom/wrappers/MustacheTag.ts
index 886a964b72a0..cfece7bc5fd4 100644
--- a/src/compiler/compile/render_dom/wrappers/MustacheTag.ts
+++ b/src/compiler/compile/render_dom/wrappers/MustacheTag.ts
@@ -37,7 +37,7 @@ export default class MustacheTagWrapper extends Tag {
block,
value => {
if (is_contenteditable) {
- return x`@set_data_contenteditable(${this.var}, ${value}, ${is_contenteditable})`;
+ return x`${is_contenteditable} ? @set_data_contenteditable(${this.var}, ${value}) : @set_data(${this.var}, ${value})`
} else {
return x`@set_data(${this.var}, ${value})`;
}
From e6bdc5a4ffc938ccc2c4e80e0a55c068413ddd72 Mon Sep 17 00:00:00 2001
From: Simon Holthausen
Date: Mon, 20 Mar 2023 12:06:40 +0100
Subject: [PATCH 10/14] refactor into smaller compiler output
---
.../compile/render_dom/wrappers/MustacheTag.ts | 10 +++++-----
src/runtime/internal/dev.ts | 15 ++++++++++-----
src/runtime/internal/dom.ts | 14 +++++++++-----
3 files changed, 24 insertions(+), 15 deletions(-)
diff --git a/src/compiler/compile/render_dom/wrappers/MustacheTag.ts b/src/compiler/compile/render_dom/wrappers/MustacheTag.ts
index cfece7bc5fd4..f636f1028b3d 100644
--- a/src/compiler/compile/render_dom/wrappers/MustacheTag.ts
+++ b/src/compiler/compile/render_dom/wrappers/MustacheTag.ts
@@ -25,19 +25,19 @@ export default class MustacheTagWrapper extends Tag {
this.parent instanceof ElementWrapper &&
this.parent.attributes.filter((a) => a.node.is_spread);
- let is_contenteditable: Expression | undefined = undefined;
+ let contenteditable_attr_value: Expression | undefined = undefined;
if (contenteditable_attributes.length > 0) {
const value = (contenteditable_attributes[0] as AttributeWrapper).get_value(block);
- is_contenteditable = x`~@contenteditable_truthy_values.indexOf(${value})`;
+ contenteditable_attr_value = x`${value}`;
} else if (spread_attributes.length > 0 && data.element_data_name) {
- is_contenteditable = x`~@contenteditable_truthy_values.indexOf(${data.element_data_name}['contenteditable'])`;
+ contenteditable_attr_value = x`${data.element_data_name}['contenteditable']`;
}
const { init } = this.rename_this_method(
block,
value => {
- if (is_contenteditable) {
- return x`${is_contenteditable} ? @set_data_contenteditable(${this.var}, ${value}) : @set_data(${this.var}, ${value})`
+ if (contenteditable_attr_value) {
+ return x`@set_data_maybe_contenteditable(${this.var}, ${value}, ${contenteditable_attr_value})`
} else {
return x`@set_data(${this.var}, ${value})`;
}
diff --git a/src/runtime/internal/dev.ts b/src/runtime/internal/dev.ts
index 8dec822a41ff..ae50e365d2e9 100644
--- a/src/runtime/internal/dev.ts
+++ b/src/runtime/internal/dev.ts
@@ -1,6 +1,7 @@
import { custom_event, append, append_hydration, insert, insert_hydration, detach, listen, attr } from './dom';
import { SvelteComponent } from './Component';
import { is_void } from '../../shared/utils/names';
+import { contenteditable_truthy_values } from './utils';
export function dispatch_dev(type: string, detail?: T) {
document.dispatchEvent(custom_event(type, { version: '__VERSION__', ...detail }, { bubbles: true }));
@@ -90,11 +91,15 @@ export function set_data_dev(text: Text, data: unknown) {
text.data = (data as string);
}
-export function set_data_contenteditable_dev(text: Text, data: unknown) {
- data = '' + data;
- if (text.wholeText === data) return;
- dispatch_dev('SvelteDOMSetData', { node: text, data });
- text.data = (data as string);
+export function set_data_maybe_contenteditable_dev(text: Text, data: unknown, attr_value: string) {
+ if (~contenteditable_truthy_values.indexOf(attr_value)) {
+ data = '' + data;
+ if (text.wholeText === data) return;
+ dispatch_dev('SvelteDOMSetData', { node: text, data });
+ text.data = (data as string);
+ } else {
+ set_data_dev(text, data);
+ }
}
export function validate_each_argument(arg) {
diff --git a/src/runtime/internal/dom.ts b/src/runtime/internal/dom.ts
index 4b0b27f62845..2e54305c46f3 100644
--- a/src/runtime/internal/dom.ts
+++ b/src/runtime/internal/dom.ts
@@ -1,4 +1,4 @@
-import { has_prop } from './utils';
+import { contenteditable_truthy_values, has_prop } from './utils';
// Track which nodes are claimed during hydration. Unclaimed nodes can then be removed from the DOM
// at the end of hydration without touching the remaining nodes.
@@ -587,10 +587,14 @@ export function set_data(text: Text, data: unknown) {
text.data = (data as string);
}
-export function set_data_contenteditable(text: Text, data: unknown) {
- data = '' + data;
- if (text.wholeText === data) return;
- text.data = (data as string);
+export function set_data_maybe_contenteditable(text: Text, data: unknown, attr_value: string) {
+ if (~contenteditable_truthy_values.indexOf(attr_value)) {
+ data = '' + data;
+ if (text.wholeText === data) return;
+ text.data = (data as string);
+ } else {
+ set_data(text, data);
+ }
}
export function set_input_value(input, value) {
From e257fd105435e70e569778adc940dd622bb90066 Mon Sep 17 00:00:00 2001
From: Simon Holthausen
Date: Mon, 20 Mar 2023 12:47:15 +0100
Subject: [PATCH 11/14] can't wait for prettier to land in this repo
---
src/compiler/compile/render_dom/wrappers/MustacheTag.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/compiler/compile/render_dom/wrappers/MustacheTag.ts b/src/compiler/compile/render_dom/wrappers/MustacheTag.ts
index f636f1028b3d..08d2b9ee87d5 100644
--- a/src/compiler/compile/render_dom/wrappers/MustacheTag.ts
+++ b/src/compiler/compile/render_dom/wrappers/MustacheTag.ts
@@ -37,7 +37,7 @@ export default class MustacheTagWrapper extends Tag {
block,
value => {
if (contenteditable_attr_value) {
- return x`@set_data_maybe_contenteditable(${this.var}, ${value}, ${contenteditable_attr_value})`
+ return x`@set_data_maybe_contenteditable(${this.var}, ${value}, ${contenteditable_attr_value})`;
} else {
return x`@set_data(${this.var}, ${value})`;
}
From 866e52a72259eaa9de975cef65d8af252c699e6b Mon Sep 17 00:00:00 2001
From: Simon Holthausen
Date: Tue, 21 Mar 2023 13:38:30 +0100
Subject: [PATCH 12/14] - move tests to puppeteer because jsdom does not
support contenteditable - remove unnecessary test - adjust one test to
actually test a regression and skip it because it fails
---
.../render_dom/wrappers/Element/index.ts | 4 +--
.../_config.js | 1 +
.../main.svelte | 0
.../_config.js | 24 ++++++++++++++
.../main.svelte | 11 +++++++
.../_config.js | 33 +++++++++++++++++++
.../main.svelte | 0
.../_config.js | 12 -------
.../_config.js | 12 -------
.../main.svelte | 6 ----
.../_config.js | 13 --------
.../main.svelte | 9 -----
12 files changed, 71 insertions(+), 54 deletions(-)
rename test/{runtime/samples/component-event-handler-contenteditable4 => runtime-puppeteer/samples/component-event-handler-contenteditable-false}/_config.js (84%)
rename test/{runtime/samples/component-event-handler-contenteditable4 => runtime-puppeteer/samples/component-event-handler-contenteditable-false}/main.svelte (100%)
create mode 100644 test/runtime-puppeteer/samples/component-event-handler-contenteditable-spread/_config.js
create mode 100644 test/runtime-puppeteer/samples/component-event-handler-contenteditable-spread/main.svelte
create mode 100644 test/runtime-puppeteer/samples/component-event-handler-contenteditable/_config.js
rename test/{runtime => runtime-puppeteer}/samples/component-event-handler-contenteditable/main.svelte (100%)
delete mode 100644 test/runtime/samples/component-event-handler-contenteditable/_config.js
delete mode 100644 test/runtime/samples/component-event-handler-contenteditable2/_config.js
delete mode 100644 test/runtime/samples/component-event-handler-contenteditable2/main.svelte
delete mode 100644 test/runtime/samples/component-event-handler-contenteditable3/_config.js
delete mode 100644 test/runtime/samples/component-event-handler-contenteditable3/main.svelte
diff --git a/src/compiler/compile/render_dom/wrappers/Element/index.ts b/src/compiler/compile/render_dom/wrappers/Element/index.ts
index b57d24ae9c5e..7a0bdbaa060a 100644
--- a/src/compiler/compile/render_dom/wrappers/Element/index.ts
+++ b/src/compiler/compile/render_dom/wrappers/Element/index.ts
@@ -872,12 +872,12 @@ export default class ElementWrapper extends Wrapper {
? x`@set_dynamic_element_data(${this.node.tag_expr.manipulate(block)})`
: x`@set_attributes`;
- block.chunks.hydrate.unshift(
+ block.chunks.hydrate.push(
b`${fn}(${this.var}, ${this.element_data_name});`
);
if (this.has_dynamic_attribute) {
- block.chunks.update.unshift(b`
+ block.chunks.update.push(b`
${fn}(${this.var}, ${this.element_data_name} = @get_spread_update(${levels}, [
${updates}
]));
diff --git a/test/runtime/samples/component-event-handler-contenteditable4/_config.js b/test/runtime-puppeteer/samples/component-event-handler-contenteditable-false/_config.js
similarity index 84%
rename from test/runtime/samples/component-event-handler-contenteditable4/_config.js
rename to test/runtime-puppeteer/samples/component-event-handler-contenteditable-false/_config.js
index bc9d65d1c315..3763360fd82a 100644
--- a/test/runtime/samples/component-event-handler-contenteditable4/_config.js
+++ b/test/runtime-puppeteer/samples/component-event-handler-contenteditable-false/_config.js
@@ -1,3 +1,4 @@
+// A puppeteer test because JSDOM doesn't support contenteditable
export default {
html: '',
diff --git a/test/runtime/samples/component-event-handler-contenteditable4/main.svelte b/test/runtime-puppeteer/samples/component-event-handler-contenteditable-false/main.svelte
similarity index 100%
rename from test/runtime/samples/component-event-handler-contenteditable4/main.svelte
rename to test/runtime-puppeteer/samples/component-event-handler-contenteditable-false/main.svelte
diff --git a/test/runtime-puppeteer/samples/component-event-handler-contenteditable-spread/_config.js b/test/runtime-puppeteer/samples/component-event-handler-contenteditable-spread/_config.js
new file mode 100644
index 000000000000..de65bd662752
--- /dev/null
+++ b/test/runtime-puppeteer/samples/component-event-handler-contenteditable-spread/_config.js
@@ -0,0 +1,24 @@
+// A puppeteer test because JSDOM doesn't support contenteditable
+export default {
+ html: '',
+ ssrHtml: '',
+
+ async test({ assert, target, window }) {
+ // this tests that by going from contenteditable=true to false, the
+ // content is correctly updated before that. This relies on the order
+ // of the updates: first updating the content, then setting contenteditable
+ // to false, which means that `set_data_maybe_contenteditable` is used and not `set_data`.
+ // If the order is reversed, https://github.com/sveltejs/svelte/issues/5018
+ // would be happening. The caveat is that if we go from contenteditable=false to true
+ // then we will have the same issue. To fix this reliably we probably need to
+ // overhaul the way we handle text updates in general.
+ // If due to some refactoring this test fails, it's probably fine to ignore it since
+ // this is a very specific edge case and the behavior is unstable anyway.
+ const div = target.querySelector('div');
+ const text = window.document.createTextNode('a');
+ div.insertBefore(text, null);
+ const event = new window.InputEvent('input');
+ await div.dispatchEvent(event);
+ assert.equal(div.textContent, 'a');
+ }
+};
diff --git a/test/runtime-puppeteer/samples/component-event-handler-contenteditable-spread/main.svelte b/test/runtime-puppeteer/samples/component-event-handler-contenteditable-spread/main.svelte
new file mode 100644
index 000000000000..ed301e8d2037
--- /dev/null
+++ b/test/runtime-puppeteer/samples/component-event-handler-contenteditable-spread/main.svelte
@@ -0,0 +1,11 @@
+
+
+{text}
diff --git a/test/runtime-puppeteer/samples/component-event-handler-contenteditable/_config.js b/test/runtime-puppeteer/samples/component-event-handler-contenteditable/_config.js
new file mode 100644
index 000000000000..1b4b3b0271e8
--- /dev/null
+++ b/test/runtime-puppeteer/samples/component-event-handler-contenteditable/_config.js
@@ -0,0 +1,33 @@
+// A puppeteer test because JSDOM doesn't support contenteditable
+export default {
+ html: '',
+
+ // Failing test for https://github.com/sveltejs/svelte/issues/5018, fix pending
+ // It's hard to fix this because in order to do that, we would need to change the
+ // way the value is compared completely. Right now it compares the value of the
+ // first text node, but it should compare the value of the whole content
+ skip: true,
+
+ async test({ assert, target, window }) {
+ const div = target.querySelector('div');
+
+ let text = window.document.createTextNode('a');
+ div.insertBefore(text, null);
+ let event = new window.InputEvent('input');
+ await div.dispatchEvent(event);
+ assert.equal(div.textContent, 'a');
+
+ // When a user types a newline, the browser inserts a element
+ const inner_div = window.document.createElement('div');
+ div.insertBefore(inner_div, null);
+ event = new window.InputEvent('input');
+ await div.dispatchEvent(event);
+ assert.equal(div.textContent, 'a');
+
+ text = window.document.createTextNode('b');
+ inner_div.insertBefore(text, null);
+ event = new window.InputEvent('input');
+ await div.dispatchEvent(event);
+ assert.equal(div.textContent, 'ab');
+ }
+};
diff --git a/test/runtime/samples/component-event-handler-contenteditable/main.svelte b/test/runtime-puppeteer/samples/component-event-handler-contenteditable/main.svelte
similarity index 100%
rename from test/runtime/samples/component-event-handler-contenteditable/main.svelte
rename to test/runtime-puppeteer/samples/component-event-handler-contenteditable/main.svelte
diff --git a/test/runtime/samples/component-event-handler-contenteditable/_config.js b/test/runtime/samples/component-event-handler-contenteditable/_config.js
deleted file mode 100644
index cfd51e500591..000000000000
--- a/test/runtime/samples/component-event-handler-contenteditable/_config.js
+++ /dev/null
@@ -1,12 +0,0 @@
-export default {
- html: '
',
-
- async test({ assert, target, window }) {
- const div = target.querySelector('div');
- const text = window.document.createTextNode('a');
- div.insertBefore(text, null);
- const event = new window.InputEvent('input');
- await div.dispatchEvent(event);
- assert.equal(div.textContent, 'a');
- }
-};
diff --git a/test/runtime/samples/component-event-handler-contenteditable2/_config.js b/test/runtime/samples/component-event-handler-contenteditable2/_config.js
deleted file mode 100644
index 10736ec1b2b1..000000000000
--- a/test/runtime/samples/component-event-handler-contenteditable2/_config.js
+++ /dev/null
@@ -1,12 +0,0 @@
-export default {
- html: '
',
-
- async test({ assert, target, window }) {
- const div = target.querySelector('div');
- const text = window.document.createTextNode('a');
- div.insertBefore(text, null);
- const event = new window.InputEvent('input');
- await div.dispatchEvent(event);
- assert.equal(div.textContent, 'a');
- }
-};
diff --git a/test/runtime/samples/component-event-handler-contenteditable2/main.svelte b/test/runtime/samples/component-event-handler-contenteditable2/main.svelte
deleted file mode 100644
index e540ceff2571..000000000000
--- a/test/runtime/samples/component-event-handler-contenteditable2/main.svelte
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
{text}
diff --git a/test/runtime/samples/component-event-handler-contenteditable3/_config.js b/test/runtime/samples/component-event-handler-contenteditable3/_config.js
deleted file mode 100644
index 957be6388b49..000000000000
--- a/test/runtime/samples/component-event-handler-contenteditable3/_config.js
+++ /dev/null
@@ -1,13 +0,0 @@
-export default {
- html: '
',
- ssrHtml: '
',
-
- async test({ assert, target, window }) {
- const div = target.querySelector('div');
- const text = window.document.createTextNode('a');
- div.insertBefore(text, null);
- const event = new window.InputEvent('input');
- await div.dispatchEvent(event);
- assert.equal(div.textContent, 'a');
- }
-};
diff --git a/test/runtime/samples/component-event-handler-contenteditable3/main.svelte b/test/runtime/samples/component-event-handler-contenteditable3/main.svelte
deleted file mode 100644
index 34bc4300e08e..000000000000
--- a/test/runtime/samples/component-event-handler-contenteditable3/main.svelte
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
{text}
From 55209c44f5ad684db1cb777c6287516f132a561d Mon Sep 17 00:00:00 2001
From: Simon Holthausen
Date: Tue, 21 Mar 2023 13:56:28 +0100
Subject: [PATCH 13/14] optimize for static contenteditable value
---
.../compile/render_dom/wrappers/MustacheTag.ts | 16 ++++++++++++----
src/runtime/internal/dev.ts | 12 ++++++++----
src/runtime/internal/dom.ts | 10 +++++++---
3 files changed, 27 insertions(+), 11 deletions(-)
diff --git a/src/compiler/compile/render_dom/wrappers/MustacheTag.ts b/src/compiler/compile/render_dom/wrappers/MustacheTag.ts
index 08d2b9ee87d5..0bfa0198aea8 100644
--- a/src/compiler/compile/render_dom/wrappers/MustacheTag.ts
+++ b/src/compiler/compile/render_dom/wrappers/MustacheTag.ts
@@ -25,10 +25,14 @@ export default class MustacheTagWrapper extends Tag {
this.parent instanceof ElementWrapper &&
this.parent.attributes.filter((a) => a.node.is_spread);
- let contenteditable_attr_value: Expression | undefined = undefined;
+ let contenteditable_attr_value: Expression | true | undefined = undefined;
if (contenteditable_attributes.length > 0) {
- const value = (contenteditable_attributes[0] as AttributeWrapper).get_value(block);
- contenteditable_attr_value = x`${value}`;
+ const attribute = contenteditable_attributes[0] as AttributeWrapper;
+ if ([true, 'true', ''].includes(attribute.node.get_static_value())) {
+ contenteditable_attr_value = true;
+ } else {
+ contenteditable_attr_value = x`${attribute.get_value(block)}`;
+ }
} else if (spread_attributes.length > 0 && data.element_data_name) {
contenteditable_attr_value = x`${data.element_data_name}['contenteditable']`;
}
@@ -37,7 +41,11 @@ export default class MustacheTagWrapper extends Tag {
block,
value => {
if (contenteditable_attr_value) {
- return x`@set_data_maybe_contenteditable(${this.var}, ${value}, ${contenteditable_attr_value})`;
+ if (contenteditable_attr_value === true) {
+ return x`@set_data_contenteditable(${this.var}, ${value})`;
+ } else {
+ return x`@set_data_maybe_contenteditable(${this.var}, ${value}, ${contenteditable_attr_value})`;
+ }
} else {
return x`@set_data(${this.var}, ${value})`;
}
diff --git a/src/runtime/internal/dev.ts b/src/runtime/internal/dev.ts
index ae50e365d2e9..cd47138fefcc 100644
--- a/src/runtime/internal/dev.ts
+++ b/src/runtime/internal/dev.ts
@@ -91,12 +91,16 @@ export function set_data_dev(text: Text, data: unknown) {
text.data = (data as string);
}
+export function set_data_contenteditable_dev(text: Text, data: unknown) {
+ data = '' + data;
+ if (text.wholeText === data) return;
+ dispatch_dev('SvelteDOMSetData', { node: text, data });
+ text.data = (data as string);
+}
+
export function set_data_maybe_contenteditable_dev(text: Text, data: unknown, attr_value: string) {
if (~contenteditable_truthy_values.indexOf(attr_value)) {
- data = '' + data;
- if (text.wholeText === data) return;
- dispatch_dev('SvelteDOMSetData', { node: text, data });
- text.data = (data as string);
+ set_data_contenteditable_dev(text, data);
} else {
set_data_dev(text, data);
}
diff --git a/src/runtime/internal/dom.ts b/src/runtime/internal/dom.ts
index 2e54305c46f3..bbe9ed2e0859 100644
--- a/src/runtime/internal/dom.ts
+++ b/src/runtime/internal/dom.ts
@@ -587,11 +587,15 @@ export function set_data(text: Text, data: unknown) {
text.data = (data as string);
}
+export function set_data_contenteditable(text: Text, data: unknown) {
+ data = '' + data;
+ if (text.wholeText === data) return;
+ text.data = (data as string);
+}
+
export function set_data_maybe_contenteditable(text: Text, data: unknown, attr_value: string) {
if (~contenteditable_truthy_values.indexOf(attr_value)) {
- data = '' + data;
- if (text.wholeText === data) return;
- text.data = (data as string);
+ set_data_contenteditable(text, data)
} else {
set_data(text, data);
}
From 05f0927f556092bc7f32136713e2d99ac29fac02 Mon Sep 17 00:00:00 2001
From: Simon Holthausen
Date: Tue, 21 Mar 2023 13:59:58 +0100
Subject: [PATCH 14/14] ffs
---
src/runtime/internal/dom.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/runtime/internal/dom.ts b/src/runtime/internal/dom.ts
index bbe9ed2e0859..a7466131708e 100644
--- a/src/runtime/internal/dom.ts
+++ b/src/runtime/internal/dom.ts
@@ -595,7 +595,7 @@ export function set_data_contenteditable(text: Text, data: unknown) {
export function set_data_maybe_contenteditable(text: Text, data: unknown, attr_value: string) {
if (~contenteditable_truthy_values.indexOf(attr_value)) {
- set_data_contenteditable(text, data)
+ set_data_contenteditable(text, data);
} else {
set_data(text, data);
}