UNPKG

5.29 kBJavaScriptView Raw
1/*!
2* v-pip v2.3.1
3* (c) 2022 Vinayak Kulkarni
4* @license MIT
5*/
6import { defineComponent, reactive, onMounted, onBeforeUnmount, openBlock, createElementBlock, normalizeClass, createElementVNode, toDisplayString, createCommentVNode } from 'vue';
7
8function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
9
10
11 var script = defineComponent({
12 name: 'VPip',
13 props: {
14 // Video related options
15 videoOptions: {
16 type: Object ,
17 required: false,
18 default: () => ({
19 wrapper: '',
20 src: '',
21 poster: '',
22 class: '',
23 height: '100%',
24 width: '100%',
25 }),
26 },
27 // button related options
28 buttonOptions: {
29 type: Object ,
30 required: false,
31 default: () => ({
32 wrapper: '',
33 type: 'button',
34 class: '',
35 label: 'Toggle picture-in-picture',
36 }),
37 },
38 wrapper: {
39 type: String ,
40 default: '',
41 required: false,
42 },
43 },
44 emits: ['video-in-pip', 'requesting-pip-failure', 'exiting-pip-failure'],
45 setup(_, { emit }) {
46 // State
47 const state = reactive({
48 video: null,
49 isPipSupported: false,
50 });
51
52 // Lifecycle Hooks
53 onMounted(() => {
54 state.isPipSupported = 'pictureInPictureEnabled' in document;
55 _optionalChain([state, 'access', _2 => _2.video, 'optionalAccess', _3 => _3.addEventListener, 'call', _4 => _4('enterpictureinpicture', enteredPip)]);
56 _optionalChain([state, 'access', _5 => _5.video, 'optionalAccess', _6 => _6.addEventListener, 'call', _7 => _7('leavepictureinpicture', leftPip)]);
57 });
58 onBeforeUnmount(() => {
59 _optionalChain([state, 'access', _8 => _8.video, 'optionalAccess', _9 => _9.removeEventListener, 'call', _10 => _10('enterpictureinpicture', leftPip)]);
60 _optionalChain([state, 'access', _11 => _11.video, 'optionalAccess', _12 => _12.removeEventListener, 'call', _13 => _13('leavepictureinpicture', leftPip)]);
61 });
62 /**
63 * Emit an event when entered PiP mode
64 *
65 * @returns {void}
66 */
67 function enteredPip() {
68 emit('video-in-pip', true);
69 }
70 /**
71 * Emit an event when left PiP mode
72 *
73 * @returns {void}
74 */
75 function leftPip() {
76 emit('video-in-pip', false);
77 }
78 // Methods
79 const togglePip = () => {
80 // If there is no element in Picture-in-Picture yet, let’s request
81 // Picture-in-Picture for the video, otherwise leave it.
82 const { pictureInPictureElement, exitPictureInPicture } =
83 document ;
84 if (!pictureInPictureElement && state.video) {
85 state.video.requestPictureInPicture().catch((error) => {
86 // Video failed to enter Picture-in-Picture mode.
87 emit('requesting-pip-failure', error);
88 });
89 } else {
90 exitPictureInPicture().catch((error) => {
91 // Video failed to leave Picture-in-Picture mode.
92 emit('exiting-pip-failure', error);
93 });
94 }
95 };
96
97 return {
98 state,
99 togglePip,
100 };
101 },
102 });
103
104const _hoisted_1 = ["src", "poster", "height", "width"];
105const _hoisted_2 = ["type"];
106
107function render(_ctx, _cache, $props, $setup, $data, $options) {
108 return (openBlock(), createElementBlock("div", {
109 class: normalizeClass(_ctx.wrapper)
110 }, [
111 createElementVNode("div", {
112 class: normalizeClass(_ctx.videoOptions.wrapper)
113 }, [
114 createElementVNode("video", {
115 ref: "video",
116 src: _ctx.videoOptions.src,
117 poster: _ctx.videoOptions.poster,
118 class: normalizeClass(_ctx.videoOptions.class),
119 height: _ctx.videoOptions.height,
120 width: _ctx.videoOptions.width,
121 controls: ""
122 }, null, 10 /* CLASS, PROPS */, _hoisted_1)
123 ], 2 /* CLASS */),
124 createElementVNode("div", {
125 class: normalizeClass(_ctx.buttonOptions.wrapper)
126 }, [
127 (_ctx.state.isPipSupported)
128 ? (openBlock(), createElementBlock("button", {
129 key: 0,
130 type: _ctx.buttonOptions.type,
131 class: normalizeClass(_ctx.buttonOptions.class),
132 onClick: _cache[0] || (_cache[0] = (...args) => (_ctx.togglePip && _ctx.togglePip(...args)))
133 }, toDisplayString(_ctx.buttonOptions.label), 11 /* TEXT, CLASS, PROPS */, _hoisted_2))
134 : createCommentVNode("v-if", true)
135 ], 2 /* CLASS */)
136 ], 2 /* CLASS */))
137}
138
139script.render = render;
140script.__file = "src/VPip.vue";
141
142let installed = false;
143
144const install = {
145 install(app) {
146 if (installed) return;
147 app.component('VPip', script);
148 installed = true;
149 },
150};
151
152var install$1 = install;
153
154export { script as VPip, install$1 as default };
155//# sourceMappingURL=v-pip.esm.js.map