diff --git a/src/compiler/compile/nodes/Binding.ts b/src/compiler/compile/nodes/Binding.ts
index 1efc1a3038..88c67c9de3 100644
--- a/src/compiler/compile/nodes/Binding.ts
+++ b/src/compiler/compile/nodes/Binding.ts
@@ -85,7 +85,8 @@ export default class Binding extends Node {
this.is_readonly =
dimensions.test(this.name) ||
(isElement(parent) &&
- ((parent.is_media_node() && read_only_media_attributes.has(this.name)) ||
+ ((parent.is_media_node() && read_only_media_attributes.has(this.name)) ||
+ (parent.name === 'img' && this.name == 'complete') ||
(parent.name === 'input' && type === 'file')) /* TODO others? */);
}
diff --git a/src/compiler/compile/nodes/Element.ts b/src/compiler/compile/nodes/Element.ts
index dbde8f1b2d..4da159d31d 100644
--- a/src/compiler/compile/nodes/Element.ts
+++ b/src/compiler/compile/nodes/Element.ts
@@ -651,6 +651,13 @@ export default class Element extends Node {
} else if (contenteditable && !contenteditable.is_static) {
return component.error(contenteditable, compiler_errors.dynamic_contenteditable_attribute);
}
+ } else if (name === 'complete') {
+ if (this.name !== 'img') {
+ component.error(binding, {
+ code: `invalid-binding`,
+ message: `'${binding.name}' binding can only be used with `
+ });
+ }
} else if (name !== 'this') {
return component.error(binding, compiler_errors.invalid_binding(binding.name));
}
diff --git a/src/compiler/compile/render_dom/wrappers/Element/index.ts b/src/compiler/compile/render_dom/wrappers/Element/index.ts
index db26b6673c..6b4c286bba 100644
--- a/src/compiler/compile/render_dom/wrappers/Element/index.ts
+++ b/src/compiler/compile/render_dom/wrappers/Element/index.ts
@@ -56,6 +56,13 @@ const events = [
filter: (node: Element, _name: string) =>
node.name === 'input' && node.get_static_attribute_value('type') === 'range'
},
+ // img events
+ {
+ event_names: ['load'],
+ filter: (node: Element, name: string) =>
+ node.name === 'img' &&
+ name === 'complete'
+ },
{
event_names: ['elementresize'],
@@ -557,6 +564,7 @@ export default class ElementWrapper extends Wrapper {
binding.node.name === 'indeterminate' ||
binding.node.name === 'textContent' ||
binding.node.name === 'innerHTML' ||
+ binding.node.name === 'complete' ||
binding.is_readonly_media_attribute()
);
})
diff --git a/test/js/samples/img-bindings/expected.js b/test/js/samples/img-bindings/expected.js
new file mode 100644
index 0000000000..545694d7fb
--- /dev/null
+++ b/test/js/samples/img-bindings/expected.js
@@ -0,0 +1,65 @@
+/* generated by Svelte vX.Y.Z */
+import {
+ SvelteComponent,
+ add_render_callback,
+ detach,
+ element,
+ init,
+ insert,
+ listen,
+ noop,
+ safe_not_equal
+} from "svelte/internal";
+
+function create_fragment(ctx) {
+ let img;
+ let mounted;
+ let dispose;
+
+ return {
+ c() {
+ img = element("img");
+ if (/*complete*/ ctx[0] === void 0) add_render_callback(() => /*img_load_handler*/ ctx[1].call(img));
+ },
+ m(target, anchor) {
+ insert(target, img, anchor);
+
+ if (!mounted) {
+ dispose = listen(img, "load", /*img_load_handler*/ ctx[1]);
+ mounted = true;
+ }
+ },
+ p: noop,
+ i: noop,
+ o: noop,
+ d(detaching) {
+ if (detaching) detach(img);
+ mounted = false;
+ dispose();
+ }
+ };
+}
+
+function instance($$self, $$props, $$invalidate) {
+ let { complete } = $$props;
+
+ function img_load_handler() {
+ complete = this.complete;
+ $$invalidate(0, complete);
+ }
+
+ $$self.$set = $$props => {
+ if ("complete" in $$props) $$invalidate(0, complete = $$props.complete);
+ };
+
+ return [complete, img_load_handler];
+}
+
+class Component extends SvelteComponent {
+ constructor(options) {
+ super();
+ init(this, options, instance, create_fragment, safe_not_equal, { complete: 0 });
+ }
+}
+
+export default Component;
\ No newline at end of file
diff --git a/test/js/samples/img-bindings/input.svelte b/test/js/samples/img-bindings/input.svelte
new file mode 100644
index 0000000000..64509aa541
--- /dev/null
+++ b/test/js/samples/img-bindings/input.svelte
@@ -0,0 +1,5 @@
+
+
+
diff --git a/test/validator/samples/binding-invalid-complete/errors.json b/test/validator/samples/binding-invalid-complete/errors.json
new file mode 100644
index 0000000000..4139aac0be
--- /dev/null
+++ b/test/validator/samples/binding-invalid-complete/errors.json
@@ -0,0 +1,15 @@
+[{
+ "code": "invalid-binding",
+ "message": "'complete' binding can only be used with
",
+ "pos": 40,
+ "start": {
+ "line": 5,
+ "column": 5,
+ "character": 40
+ },
+ "end": {
+ "line": 5,
+ "column": 18,
+ "character": 53
+ }
+}]
\ No newline at end of file
diff --git a/test/validator/samples/binding-invalid-complete/input.svelte b/test/validator/samples/binding-invalid-complete/input.svelte
new file mode 100644
index 0000000000..9380dc485c
--- /dev/null
+++ b/test/validator/samples/binding-invalid-complete/input.svelte
@@ -0,0 +1,5 @@
+
+
+