UNPKG

7.73 kBJavaScriptView Raw
1(function (global, factory) {
2 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('@vue/composition-api')) :
3 typeof define === 'function' && define.amd ? define(['@vue/composition-api'], factory) :
4 (global = global || self, global.VPip = factory(global.vueCompositionApi));
5}(this, (function (compositionApi) { 'use strict';
6
7 //
8 var script = compositionApi.defineComponent({
9 name: 'VPip',
10 props: {
11 // Video related options
12 videoOptions: {
13 type: Object,
14 required: false,
15 default: function _default() {
16 return {
17 wrapper: '',
18 src: '',
19 poster: '',
20 class: '',
21 height: '100%',
22 width: '100%'
23 };
24 }
25 },
26 // button related options
27 buttonOptions: {
28 type: Object,
29 required: false,
30 default: function _default() {
31 return {
32 wrapper: '',
33 type: 'button',
34 class: '',
35 label: 'Toggle picture-in-picture'
36 };
37 }
38 },
39 wrapper: {
40 type: String,
41 default: '',
42 required: false
43 }
44 },
45
46 setup(props, _ref) {
47 var emit = _ref.emit;
48 // State
49 var video = compositionApi.ref(null);
50 var isPipSupported = compositionApi.ref(false); // Lifecycle Hooks
51
52 compositionApi.onMounted(function () {
53 isPipSupported.value = 'pictureInPictureEnabled' in document;
54 video.value.addEventListener('enterpictureinpicture', function () {
55 emit('video-in-pip', true);
56 });
57 video.value.addEventListener('leavepictureinpicture', function () {
58 emit('video-in-pip', false);
59 });
60 });
61 compositionApi.onBeforeUnmount(function () {
62 video.value.removeEventListener('enterpictureinpicture');
63 video.value.removeEventListener('leavepictureinpicture');
64 }); // Methods
65
66 var togglePip = function togglePip() {
67 // If there is no element in Picture-in-Picture yet, let’s request
68 // Picture-in-Picture for the video, otherwise leave it.
69 if (!document.pictureInPictureElement) {
70 video.value.requestPictureInPicture().catch(function (error) {
71 // Video failed to enter Picture-in-Picture mode.
72 emit('requesting-pip-failure', error);
73 });
74 } else {
75 document.exitPictureInPicture().catch(function (error) {
76 // Video failed to leave Picture-in-Picture mode.
77 emit('exiting-pip-failure', error);
78 });
79 }
80 };
81
82 return {
83 video,
84 isPipSupported,
85 togglePip
86 };
87 }
88
89 });
90
91 function normalizeComponent(template, style, script, scopeId, isFunctionalTemplate, moduleIdentifier /* server only */, shadowMode, createInjector, createInjectorSSR, createInjectorShadow) {
92 if (typeof shadowMode !== 'boolean') {
93 createInjectorSSR = createInjector;
94 createInjector = shadowMode;
95 shadowMode = false;
96 }
97 // Vue.extend constructor export interop.
98 const options = typeof script === 'function' ? script.options : script;
99 // render functions
100 if (template && template.render) {
101 options.render = template.render;
102 options.staticRenderFns = template.staticRenderFns;
103 options._compiled = true;
104 // functional template
105 if (isFunctionalTemplate) {
106 options.functional = true;
107 }
108 }
109 // scopedId
110 if (scopeId) {
111 options._scopeId = scopeId;
112 }
113 let hook;
114 if (moduleIdentifier) {
115 // server build
116 hook = function (context) {
117 // 2.3 injection
118 context =
119 context || // cached call
120 (this.$vnode && this.$vnode.ssrContext) || // stateful
121 (this.parent && this.parent.$vnode && this.parent.$vnode.ssrContext); // functional
122 // 2.2 with runInNewContext: true
123 if (!context && typeof __VUE_SSR_CONTEXT__ !== 'undefined') {
124 context = __VUE_SSR_CONTEXT__;
125 }
126 // inject component styles
127 if (style) {
128 style.call(this, createInjectorSSR(context));
129 }
130 // register component module identifier for async chunk inference
131 if (context && context._registeredComponents) {
132 context._registeredComponents.add(moduleIdentifier);
133 }
134 };
135 // used by ssr in case component is cached and beforeCreate
136 // never gets called
137 options._ssrRegister = hook;
138 }
139 else if (style) {
140 hook = shadowMode
141 ? function (context) {
142 style.call(this, createInjectorShadow(context, this.$root.$options.shadowRoot));
143 }
144 : function (context) {
145 style.call(this, createInjector(context));
146 };
147 }
148 if (hook) {
149 if (options.functional) {
150 // register for functional component in vue file
151 const originalRender = options.render;
152 options.render = function renderWithStyleInjection(h, context) {
153 hook.call(context);
154 return originalRender(h, context);
155 };
156 }
157 else {
158 // inject component registration as beforeCreate hook
159 const existing = options.beforeCreate;
160 options.beforeCreate = existing ? [].concat(existing, hook) : [hook];
161 }
162 }
163 return script;
164 }
165
166 /* script */
167 const __vue_script__ = script;
168
169 /* template */
170 var __vue_render__ = function() {
171 var _vm = this;
172 var _h = _vm.$createElement;
173 var _c = _vm._self._c || _h;
174 return _c("div", { class: _vm.wrapper }, [
175 _c("div", { class: _vm.videoOptions.wrapper }, [
176 _c("video", {
177 ref: "video",
178 class: _vm.videoOptions.class,
179 attrs: {
180 src: _vm.videoOptions.src,
181 poster: _vm.videoOptions.poster,
182 height: _vm.videoOptions.height,
183 width: _vm.videoOptions.width,
184 controls: ""
185 }
186 })
187 ]),
188 _vm._v(" "),
189 _c("div", { class: _vm.buttonOptions.wrapper }, [
190 _vm.isPipSupported
191 ? _c(
192 "button",
193 {
194 class: _vm.buttonOptions.class,
195 attrs: { type: _vm.buttonOptions.type },
196 on: { click: _vm.togglePip }
197 },
198 [_vm._v("\n " + _vm._s(_vm.buttonOptions.label) + "\n ")]
199 )
200 : _vm._e()
201 ])
202 ])
203 };
204 var __vue_staticRenderFns__ = [];
205 __vue_render__._withStripped = true;
206
207 /* style */
208 const __vue_inject_styles__ = undefined;
209 /* scoped */
210 const __vue_scope_id__ = undefined;
211 /* module identifier */
212 const __vue_module_identifier__ = undefined;
213 /* functional template */
214 const __vue_is_functional_template__ = false;
215 /* style inject */
216
217 /* style inject SSR */
218
219 /* style inject shadow dom */
220
221
222
223 const __vue_component__ = normalizeComponent(
224 { render: __vue_render__, staticRenderFns: __vue_staticRenderFns__ },
225 __vue_inject_styles__,
226 __vue_script__,
227 __vue_scope_id__,
228 __vue_is_functional_template__,
229 __vue_module_identifier__,
230 false,
231 undefined,
232 undefined,
233 undefined
234 );
235
236 return __vue_component__;
237
238})));