diff --git a/src/compiler/compile/render_dom/wrappers/Element/Attribute.ts b/src/compiler/compile/render_dom/wrappers/Element/Attribute.ts
index 9ee7694b71..db3cf7a662 100644
--- a/src/compiler/compile/render_dom/wrappers/Element/Attribute.ts
+++ b/src/compiler/compile/render_dom/wrappers/Element/Attribute.ts
@@ -73,10 +73,11 @@ export default class AttributeWrapper {
const dependencies = this.node.get_dependencies();
const value = this.get_value(block);
+ const is_src = this.node.name === 'src'; // TODO retire this exception in favour of https://github.com/sveltejs/svelte/issues/3750
const is_select_value_attribute =
name === 'value' && element.node.name === 'select';
- const should_cache = is_select_value_attribute; // TODO is this necessary?
+ const should_cache = is_src || this.node.should_cache() || is_select_value_attribute; // TODO is this necessary?
const last = should_cache && block.get_unique_name(
`${element.var.name}_${name.replace(/[^a-zA-Z_$]/g, '_')}_value`
@@ -119,6 +120,11 @@ export default class AttributeWrapper {
${last} = ${value};
${updater}
`);
+ } else if (is_src) {
+ block.chunks.hydrate.push(
+ b`if (${element.var}.src !== ${init}) ${method}(${element.var}, "${name}", ${last});`
+ );
+ updater = b`${method}(${element.var}, "${name}", ${should_cache ? last : value});`;
} else if (property_name) {
block.chunks.hydrate.push(
b`${element.var}.${property_name} = ${init};`
@@ -137,7 +143,9 @@ export default class AttributeWrapper {
let condition = changed(dependencies);
if (should_cache) {
- condition = x`${condition} && (${last} !== (${last} = ${value}))`;
+ condition = is_src
+ ? x`${condition} && (${element.var}.src !== (${last} = ${value}))`
+ : x`${condition} && (${last} !== (${last} = ${value}))`;
}
if (block.has_outros) {
diff --git a/test/js/samples/inline-style-unoptimized/expected.js b/test/js/samples/inline-style-unoptimized/expected.js
index 93692daa32..11eaddbdf7 100644
--- a/test/js/samples/inline-style-unoptimized/expected.js
+++ b/test/js/samples/inline-style-unoptimized/expected.js
@@ -15,6 +15,7 @@ function create_fragment(ctx) {
let div0;
let t;
let div1;
+ let div1_style_value;
return {
c() {
@@ -22,7 +23,7 @@ function create_fragment(ctx) {
t = space();
div1 = element("div");
attr(div0, "style", ctx.style);
- attr(div1, "style", "" + (ctx.key + ": " + ctx.value));
+ attr(div1, "style", div1_style_value = "" + (ctx.key + ": " + ctx.value));
},
m(target, anchor) {
insert(target, div0, anchor);
@@ -34,8 +35,8 @@ function create_fragment(ctx) {
attr(div0, "style", ctx.style);
}
- if (changed.key || changed.value) {
- attr(div1, "style", "" + (ctx.key + ": " + ctx.value));
+ if ((changed.key || changed.value) && div1_style_value !== (div1_style_value = "" + (ctx.key + ": " + ctx.value))) {
+ attr(div1, "style", div1_style_value);
}
},
i: noop,
diff --git a/test/js/samples/src-attribute-check/_config.js b/test/js/samples/src-attribute-check/_config.js
new file mode 100644
index 0000000000..84c0d733ef
--- /dev/null
+++ b/test/js/samples/src-attribute-check/_config.js
@@ -0,0 +1,5 @@
+export default {
+ options: {
+ hydratable: true
+ }
+};
\ No newline at end of file
diff --git a/test/js/samples/src-attribute-check/expected.js b/test/js/samples/src-attribute-check/expected.js
new file mode 100644
index 0000000000..3e6364fa4a
--- /dev/null
+++ b/test/js/samples/src-attribute-check/expected.js
@@ -0,0 +1,90 @@
+/* generated by Svelte vX.Y.Z */
+import {
+ SvelteComponent,
+ attr,
+ children,
+ claim_element,
+ claim_space,
+ detach,
+ element,
+ init,
+ insert,
+ noop,
+ safe_not_equal,
+ space
+} from "svelte/internal";
+
+function create_fragment(ctx) {
+ let img0;
+ let img0_src_value;
+ let t;
+ let img1;
+ let img1_src_value;
+
+ return {
+ c() {
+ img0 = element("img");
+ t = space();
+ img1 = element("img");
+ this.h();
+ },
+ l(nodes) {
+ img0 = claim_element(nodes, "IMG", { alt: true, src: true });
+ var img0_nodes = children(img0);
+ img0_nodes.forEach(detach);
+ t = claim_space(nodes);
+ img1 = claim_element(nodes, "IMG", { alt: true, src: true });
+ var img1_nodes = children(img1);
+ img1_nodes.forEach(detach);
+ this.h();
+ },
+ h() {
+ attr(img0, "alt", "potato");
+ if (img0.src !== (img0_src_value = ctx.url)) attr(img0, "src", img0_src_value);
+ attr(img1, "alt", "potato");
+ if (img1.src !== (img1_src_value = "" + (ctx.slug + ".jpg"))) attr(img1, "src", img1_src_value);
+ },
+ m(target, anchor) {
+ insert(target, img0, anchor);
+ insert(target, t, anchor);
+ insert(target, img1, anchor);
+ },
+ p(changed, ctx) {
+ if (changed.url && img0.src !== (img0_src_value = ctx.url)) {
+ attr(img0, "src", img0_src_value);
+ }
+
+ if (changed.slug && img1.src !== (img1_src_value = "" + (ctx.slug + ".jpg"))) {
+ attr(img1, "src", img1_src_value);
+ }
+ },
+ i: noop,
+ o: noop,
+ d(detaching) {
+ if (detaching) detach(img0);
+ if (detaching) detach(t);
+ if (detaching) detach(img1);
+ }
+ };
+}
+
+function instance($$self, $$props, $$invalidate) {
+ let { url } = $$props;
+ let { slug } = $$props;
+
+ $$self.$set = $$props => {
+ if ("url" in $$props) $$invalidate("url", url = $$props.url);
+ if ("slug" in $$props) $$invalidate("slug", slug = $$props.slug);
+ };
+
+ return { url, slug };
+}
+
+class Component extends SvelteComponent {
+ constructor(options) {
+ super();
+ init(this, options, instance, create_fragment, safe_not_equal, { url: 0, slug: 0 });
+ }
+}
+
+export default Component;
\ No newline at end of file
diff --git a/test/js/samples/src-attribute-check/input.svelte b/test/js/samples/src-attribute-check/input.svelte
new file mode 100644
index 0000000000..9febd7e4ea
--- /dev/null
+++ b/test/js/samples/src-attribute-check/input.svelte
@@ -0,0 +1,7 @@
+
+
+
+
\ No newline at end of file