Skip to content

Commit 927fcbf

Browse files
authored
Merge pull request #3927 from MattiasBuelens/video-bindings
Add bindings for HTMLVideoElement.videoWidth and videoHeight
2 parents 05cf649 + 51c1ade commit 927fcbf

File tree

6 files changed

+155
-8
lines changed

6 files changed

+155
-8
lines changed

src/compiler/compile/nodes/Binding.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@ const read_only_media_attributes = new Set([
1313
'seekable',
1414
'played',
1515
'seeking',
16-
'ended'
16+
'ended',
17+
'videoHeight',
18+
'videoWidth'
1719
]);
1820

1921
export default class Binding extends Node {

src/compiler/compile/nodes/Element.ts

+10
Original file line numberDiff line numberDiff line change
@@ -606,6 +606,16 @@ export default class Element extends Node {
606606
message: `'${name}' binding can only be used with <audio> or <video>`
607607
});
608608
}
609+
} else if (
610+
name === 'videoHeight' ||
611+
name === 'videoWidth'
612+
) {
613+
if (this.name !== 'video') {
614+
component.error(binding, {
615+
code: `invalid-binding`,
616+
message: `'${name}' binding can only be used with <video>`
617+
});
618+
}
609619
} else if (dimensions.test(name)) {
610620
if (this.name === 'svg' && (name === 'offsetWidth' || name === 'offsetHeight')) {
611621
component.error(binding, {

src/compiler/compile/render_dom/wrappers/Element/index.ts

+9-3
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ const events = [
5252
},
5353

5454
{
55-
event_names: ['resize'],
55+
event_names: ['elementresize'],
5656
filter: (_node: Element, name: string) =>
5757
dimensions.test(name)
5858
},
@@ -112,6 +112,12 @@ const events = [
112112
node.is_media_node() &&
113113
name === 'ended'
114114
},
115+
{
116+
event_names: ['resize'],
117+
filter: (node: Element, name: string) =>
118+
node.is_media_node() &&
119+
(name === 'videoHeight' || name === 'videoWidth')
120+
},
115121

116122
// details event
117123
{
@@ -536,7 +542,7 @@ export default class ElementWrapper extends Wrapper {
536542
`);
537543

538544
group.events.forEach(name => {
539-
if (name === 'resize') {
545+
if (name === 'elementresize') {
540546
// special case
541547
const resize_listener = block.get_unique_name(`${this.var.name}_resize_listener`);
542548
block.add_variable(resize_listener);
@@ -578,7 +584,7 @@ export default class ElementWrapper extends Wrapper {
578584
);
579585
}
580586

581-
if (group.events[0] === 'resize') {
587+
if (group.events[0] === 'elementresize') {
582588
block.chunks.hydrate.push(
583589
b`@add_render_callback(() => ${callee}.call(${this.var}));`
584590
);

test/js/samples/bind-width-height/expected.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,11 @@ function create_fragment(ctx) {
1919
c() {
2020
div = element("div");
2121
div.textContent = "some content";
22-
add_render_callback(() => ctx.div_resize_handler.call(div));
22+
add_render_callback(() => ctx.div_elementresize_handler.call(div));
2323
},
2424
m(target, anchor) {
2525
insert(target, div, anchor);
26-
div_resize_listener = add_resize_listener(div, ctx.div_resize_handler.bind(div));
26+
div_resize_listener = add_resize_listener(div, ctx.div_elementresize_handler.bind(div));
2727
},
2828
p: noop,
2929
i: noop,
@@ -39,7 +39,7 @@ function instance($$self, $$props, $$invalidate) {
3939
let { w } = $$props;
4040
let { h } = $$props;
4141

42-
function div_resize_handler() {
42+
function div_elementresize_handler() {
4343
w = this.offsetWidth;
4444
h = this.offsetHeight;
4545
$$invalidate("w", w);
@@ -51,7 +51,7 @@ function instance($$self, $$props, $$invalidate) {
5151
if ("h" in $$props) $$invalidate("h", h = $$props.h);
5252
};
5353

54-
return { w, h, div_resize_handler };
54+
return { w, h, div_elementresize_handler };
5555
}
5656

5757
class Component extends SvelteComponent {
+121
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
/* generated by Svelte vX.Y.Z */
2+
import {
3+
SvelteComponent,
4+
add_render_callback,
5+
add_resize_listener,
6+
detach,
7+
element,
8+
init,
9+
insert,
10+
listen,
11+
noop,
12+
raf,
13+
run_all,
14+
safe_not_equal
15+
} from "svelte/internal";
16+
17+
function create_fragment(ctx) {
18+
let video;
19+
let video_updating = false;
20+
let video_resize_listener;
21+
let video_animationframe;
22+
let dispose;
23+
24+
function video_timeupdate_handler() {
25+
cancelAnimationFrame(video_animationframe);
26+
27+
if (!video.paused) {
28+
video_animationframe = raf(video_timeupdate_handler);
29+
video_updating = true;
30+
}
31+
32+
ctx.video_timeupdate_handler.call(video);
33+
}
34+
35+
return {
36+
c() {
37+
video = element("video");
38+
add_render_callback(() => ctx.video_elementresize_handler.call(video));
39+
if (ctx.videoHeight === void 0 || ctx.videoWidth === void 0) add_render_callback(() => ctx.video_resize_handler.call(video));
40+
41+
dispose = [
42+
listen(video, "timeupdate", video_timeupdate_handler),
43+
listen(video, "resize", ctx.video_resize_handler)
44+
];
45+
},
46+
m(target, anchor) {
47+
insert(target, video, anchor);
48+
video_resize_listener = add_resize_listener(video, ctx.video_elementresize_handler.bind(video));
49+
},
50+
p(changed, ctx) {
51+
if (!video_updating && changed.currentTime && !isNaN(ctx.currentTime)) {
52+
video.currentTime = ctx.currentTime;
53+
}
54+
55+
video_updating = false;
56+
},
57+
i: noop,
58+
o: noop,
59+
d(detaching) {
60+
if (detaching) detach(video);
61+
video_resize_listener.cancel();
62+
run_all(dispose);
63+
}
64+
};
65+
}
66+
67+
function instance($$self, $$props, $$invalidate) {
68+
let { currentTime } = $$props;
69+
let { videoHeight } = $$props;
70+
let { videoWidth } = $$props;
71+
let { offsetWidth } = $$props;
72+
73+
function video_elementresize_handler() {
74+
offsetWidth = this.offsetWidth;
75+
$$invalidate("offsetWidth", offsetWidth);
76+
}
77+
78+
function video_timeupdate_handler() {
79+
currentTime = this.currentTime;
80+
$$invalidate("currentTime", currentTime);
81+
}
82+
83+
function video_resize_handler() {
84+
videoHeight = this.videoHeight;
85+
videoWidth = this.videoWidth;
86+
$$invalidate("videoHeight", videoHeight);
87+
$$invalidate("videoWidth", videoWidth);
88+
}
89+
90+
$$self.$set = $$props => {
91+
if ("currentTime" in $$props) $$invalidate("currentTime", currentTime = $$props.currentTime);
92+
if ("videoHeight" in $$props) $$invalidate("videoHeight", videoHeight = $$props.videoHeight);
93+
if ("videoWidth" in $$props) $$invalidate("videoWidth", videoWidth = $$props.videoWidth);
94+
if ("offsetWidth" in $$props) $$invalidate("offsetWidth", offsetWidth = $$props.offsetWidth);
95+
};
96+
97+
return {
98+
currentTime,
99+
videoHeight,
100+
videoWidth,
101+
offsetWidth,
102+
video_elementresize_handler,
103+
video_timeupdate_handler,
104+
video_resize_handler
105+
};
106+
}
107+
108+
class Component extends SvelteComponent {
109+
constructor(options) {
110+
super();
111+
112+
init(this, options, instance, create_fragment, safe_not_equal, {
113+
currentTime: 0,
114+
videoHeight: 0,
115+
videoWidth: 0,
116+
offsetWidth: 0
117+
});
118+
}
119+
}
120+
121+
export default Component;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<script>
2+
export let currentTime;
3+
export let videoHeight;
4+
export let videoWidth;
5+
export let offsetWidth;
6+
</script>
7+
8+
<video bind:currentTime bind:videoHeight bind:videoWidth bind:offsetWidth/>

0 commit comments

Comments
 (0)