UNPKG

10.3 kBSource Map (JSON)View Raw
1{"version":3,"file":"v-pip.cjs.js","sources":["../src/VPip.vue","../src/VPip.vue?vue&type=template&id=63b7ba3a&lang.js","../src/install.ts"],"sourcesContent":["<template>\n <div :class=\"wrapper\">\n <div :class=\"videoOptions.wrapper\">\n <video\n ref=\"video\"\n :src=\"videoOptions.src\"\n :poster=\"videoOptions.poster\"\n :class=\"videoOptions.class\"\n :height=\"videoOptions.height\"\n :width=\"videoOptions.width\"\n controls\n />\n </div>\n <div :class=\"buttonOptions.wrapper\">\n <button\n v-if=\"state.isPipSupported\"\n :type=\"buttonOptions.type\"\n :class=\"buttonOptions.class\"\n @click=\"togglePip\"\n >\n {{ buttonOptions.label }}\n </button>\n </div>\n </div>\n</template>\n\n<script lang=\"ts\">\n import {\n reactive,\n onMounted,\n onBeforeUnmount,\n defineComponent,\n PropType,\n } from 'vue';\n import { VideoOptionsProps, ButtonOptionsProps, State } from '../types';\n\n export default defineComponent({\n name: 'VPip',\n props: {\n // Video related options\n videoOptions: {\n type: Object as PropType<VideoOptionsProps>,\n required: false,\n default: () => ({\n wrapper: '',\n src: '',\n poster: '',\n class: '',\n height: '100%',\n width: '100%',\n }),\n },\n // button related options\n buttonOptions: {\n type: Object as PropType<ButtonOptionsProps>,\n required: false,\n default: () => ({\n wrapper: '',\n type: 'button',\n class: '',\n label: 'Toggle picture-in-picture',\n }),\n },\n wrapper: {\n type: String as PropType<string>,\n default: '',\n required: false,\n },\n },\n emits: ['video-in-pip', 'requesting-pip-failure', 'exiting-pip-failure'],\n setup(_, { emit }) {\n // State\n const state: State = reactive({\n video: null,\n isPipSupported: false,\n });\n\n // Lifecycle Hooks\n onMounted(() => {\n state.isPipSupported = 'pictureInPictureEnabled' in document;\n state.video?.addEventListener('enterpictureinpicture', enteredPip);\n state.video?.addEventListener('leavepictureinpicture', leftPip);\n });\n onBeforeUnmount(() => {\n state.video?.removeEventListener('enterpictureinpicture', leftPip);\n state.video?.removeEventListener('leavepictureinpicture', leftPip);\n });\n /**\n * Emit an event when entered PiP mode\n *\n * @returns {void}\n */\n function enteredPip(): void {\n emit('video-in-pip', true);\n }\n /**\n * Emit an event when left PiP mode\n *\n * @returns {void}\n */\n function leftPip(): void {\n emit('video-in-pip', false);\n }\n // Methods\n const togglePip = () => {\n // If there is no element in Picture-in-Picture yet, let’s request\n // Picture-in-Picture for the video, otherwise leave it.\n const { pictureInPictureElement, exitPictureInPicture } =\n document as Document;\n if (!pictureInPictureElement && state.video) {\n state.video.requestPictureInPicture().catch((error: any) => {\n // Video failed to enter Picture-in-Picture mode.\n emit('requesting-pip-failure', error);\n });\n } else {\n exitPictureInPicture().catch((error: any) => {\n // Video failed to leave Picture-in-Picture mode.\n emit('exiting-pip-failure', error);\n });\n }\n };\n\n return {\n state,\n togglePip,\n };\n },\n });\n</script>\n","<template>\n <div :class=\"wrapper\">\n <div :class=\"videoOptions.wrapper\">\n <video\n ref=\"video\"\n :src=\"videoOptions.src\"\n :poster=\"videoOptions.poster\"\n :class=\"videoOptions.class\"\n :height=\"videoOptions.height\"\n :width=\"videoOptions.width\"\n controls\n />\n </div>\n <div :class=\"buttonOptions.wrapper\">\n <button\n v-if=\"state.isPipSupported\"\n :type=\"buttonOptions.type\"\n :class=\"buttonOptions.class\"\n @click=\"togglePip\"\n >\n {{ buttonOptions.label }}\n </button>\n </div>\n </div>\n</template>\n\n<script lang=\"ts\">\n import {\n reactive,\n onMounted,\n onBeforeUnmount,\n defineComponent,\n PropType,\n } from 'vue';\n import { VideoOptionsProps, ButtonOptionsProps, State } from '../types';\n\n export default defineComponent({\n name: 'VPip',\n props: {\n // Video related options\n videoOptions: {\n type: Object as PropType<VideoOptionsProps>,\n required: false,\n default: () => ({\n wrapper: '',\n src: '',\n poster: '',\n class: '',\n height: '100%',\n width: '100%',\n }),\n },\n // button related options\n buttonOptions: {\n type: Object as PropType<ButtonOptionsProps>,\n required: false,\n default: () => ({\n wrapper: '',\n type: 'button',\n class: '',\n label: 'Toggle picture-in-picture',\n }),\n },\n wrapper: {\n type: String as PropType<string>,\n default: '',\n required: false,\n },\n },\n emits: ['video-in-pip', 'requesting-pip-failure', 'exiting-pip-failure'],\n setup(_, { emit }) {\n // State\n const state: State = reactive({\n video: null,\n isPipSupported: false,\n });\n\n // Lifecycle Hooks\n onMounted(() => {\n state.isPipSupported = 'pictureInPictureEnabled' in document;\n state.video?.addEventListener('enterpictureinpicture', enteredPip);\n state.video?.addEventListener('leavepictureinpicture', leftPip);\n });\n onBeforeUnmount(() => {\n state.video?.removeEventListener('enterpictureinpicture', leftPip);\n state.video?.removeEventListener('leavepictureinpicture', leftPip);\n });\n /**\n * Emit an event when entered PiP mode\n *\n * @returns {void}\n */\n function enteredPip(): void {\n emit('video-in-pip', true);\n }\n /**\n * Emit an event when left PiP mode\n *\n * @returns {void}\n */\n function leftPip(): void {\n emit('video-in-pip', false);\n }\n // Methods\n const togglePip = () => {\n // If there is no element in Picture-in-Picture yet, let’s request\n // Picture-in-Picture for the video, otherwise leave it.\n const { pictureInPictureElement, exitPictureInPicture } =\n document as Document;\n if (!pictureInPictureElement && state.video) {\n state.video.requestPictureInPicture().catch((error: any) => {\n // Video failed to enter Picture-in-Picture mode.\n emit('requesting-pip-failure', error);\n });\n } else {\n exitPictureInPicture().catch((error: any) => {\n // Video failed to leave Picture-in-Picture mode.\n emit('exiting-pip-failure', error);\n });\n }\n };\n\n return {\n state,\n togglePip,\n };\n },\n });\n</script>\n","import { App } from 'vue';\nimport VPip from './VPip.vue';\n\nlet installed = false;\n\nconst install = {\n install(app: App): void {\n if (installed) return;\n app.component('VPip', VPip);\n installed = true;\n },\n};\n\nexport default install;\n"],"names":["onMounted","onBeforeUnmount","_normalizeClass","_toDisplayString","VPip"],"mappings":"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"}
\No newline at end of file