├── .babelrc
├── .npmignore
├── .editorconfig
├── .eslintrc.json
├── .gitignore
├── index.html
├── .github
└── workflows
│ └── npmpublish.yml
├── rollup.config.js
├── LICENSE
├── README.md
├── package.json
├── src
└── Vimeo.js
└── dist
├── videojs-vimeo.esm.js
├── videojs-vimeo.cjs.js
└── videojs-vimeo.umd.js
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [["es2015", {"loose": true}]],
3 | "plugins": ["transform-object-assign"]
4 | }
5 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | # Intentionally left blank, so that npm does not ignore anything by default,
2 | # but relies on the package.json "files" array to explicitly define what ends
3 | # up in the package.
4 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # http://editorconfig.org
2 | root = true
3 |
4 | [*]
5 | charset = utf-8
6 | end_of_line = lf
7 | indent_style = space
8 | indent_size = 2
9 | insert_final_newline = true
10 | trim_trailing_whitespace = true
11 |
12 | [*.md]
13 | trim_trailing_whitespace = false
14 |
--------------------------------------------------------------------------------
/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "env": {
3 | "browser": true,
4 | "es6": true
5 | },
6 | "extends": "videojs",
7 | "globals": {
8 | "Atomics": "readonly",
9 | "SharedArrayBuffer": "readonly"
10 | },
11 | "parserOptions": {
12 | "ecmaVersion": 2018,
13 | "sourceType": "module"
14 | },
15 | "rules": {
16 | "require-jsdoc": 0,
17 | "no-console": 0
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # OS
2 | Thumbs.db
3 | ehthumbs.db
4 | Desktop.ini
5 | .DS_Store
6 | ._*
7 |
8 | # Editors
9 | *~
10 | *.swp
11 | *.tmproj
12 | *.tmproject
13 | *.sublime-*
14 | .idea/
15 | .project/
16 | .settings/
17 | .vscode/
18 |
19 | # Logs
20 | logs
21 | *.log
22 | npm-debug.log*
23 |
24 | # Dependency directories
25 | bower_components/
26 | node_modules/
27 |
28 | # Yeoman meta-data
29 | .yo-rc.json
30 |
31 | # Build-related directories
32 | docs/api/
33 | es5/
34 | test/dist/
35 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | videojs-vimeo Demo
7 |
8 |
9 |
10 |
11 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/.github/workflows/npmpublish.yml:
--------------------------------------------------------------------------------
1 | name: Library - Build and Deploy to NPM
2 |
3 | on:
4 | release:
5 | types: [created]
6 |
7 | jobs:
8 | build-and-deploy:
9 | runs-on: ubuntu-latest
10 | steps:
11 | - uses: actions/checkout@v2
12 | - uses: actions/setup-node@v1
13 | with:
14 | node-version: "12.x"
15 | registry-url: "https://registry.npmjs.org"
16 | scope: "@devmobiliza"
17 | - run: yarn install
18 | - run: yarn build:lib
19 | - run: npm publish --access public
20 | env:
21 | NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
22 |
--------------------------------------------------------------------------------
/rollup.config.js:
--------------------------------------------------------------------------------
1 | import resolve from '@rollup/plugin-node-resolve';
2 | import commonjs from '@rollup/plugin-commonjs';
3 | import pkg from './package.json';
4 |
5 | export default [
6 | // browser-friendly UMD build
7 | {
8 | input: 'src/Vimeo.js',
9 | output: {
10 | name: 'videojs-vimeo',
11 | file: pkg.browser,
12 | format: 'umd'
13 | },
14 | plugins: [
15 | resolve(),
16 | commonjs()
17 | ]
18 | },
19 |
20 | // CommonJS (for Node) and ES module (for bundlers) build.
21 | // (We could have three entries in the configuration array
22 | // instead of two, but it's quicker to generate multiple
23 | // builds from a single configuration where possible, using
24 | // an array for the `output` option, where we can specify
25 | // `file` and `format` for each target)
26 | {
27 | input: 'src/Vimeo.js',
28 | external: ['ms'],
29 | output: [
30 | { file: pkg.main, format: 'cjs' },
31 | { file: pkg.module, format: 'es' }
32 | ]
33 | }
34 | ];
35 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2020 Kevin Aguiar and videojs-vimeo contributors
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Videojs Vimeo plugin hard fork
2 |
3 | #### videojs-vimeo official plugin fork for supporting videojs v7.6.6 onwards.
4 |
5 | This project is a hard fork of the currently unmaintained official videojs-vimeo plugin: https://github.com/videojs/videojs-vimeo
6 |
7 | This fork has some significant changes in project structure:
8 |
9 | - Build now uses rollup;
10 |
11 | - Project linting now uses eslint + videojs styleguide;
12 |
13 | - Project folder structure reworked;
14 |
15 | - Lib version reseted relative to the official plugin.
16 |
17 | ## Installation
18 |
19 | ```bash
20 | npm i @devmobiliza/videojs-vimeo
21 | // OR
22 | yarn add @devmobiliza/videojs-vimeo
23 | ```
24 |
25 | ## Usage
26 |
27 | - CommonJS:
28 |
29 | ```js
30 | import videojs from 'video.js';
31 | import '@devmobiliza/videojs-vimeo/dist/videojs-vimeo.cjs';
32 | ```
33 |
34 | - Module:
35 |
36 | ```js
37 | import videojs from 'video.js';
38 | import '@devmobiliza/videojs-vimeo/dist/videojs-vimeo.esm';
39 | ```
40 |
41 | - Browser:
42 |
43 | See [index.html](https://github.com/Mobiliza/videojs-vimeo/blob/master/index.html)
44 |
45 | ## Events / Vimeo Options
46 |
47 | Events, like `on('play')`, `one('play')` work as per the video.js API: https://docs.videojs.com/
48 |
49 | For setting the time of the player the `videojs.currentTime(TIME_SECONDS)` function can be used.
50 |
51 | Vimeo options are available here (must be used with the `vimeo` key in the options object of the video.js): https://vimeo.zendesk.com/hc/pt/articles/360001494447-Usando-os-par%C3%A2metros-do-player
52 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@devmobiliza/videojs-vimeo",
3 | "version": "0.6.0",
4 | "description": "Videojs Vimeo official plugin fork for working with video.js v7.6.6 onwards.",
5 | "main": "dist/videojs-vimeo.cjs.js",
6 | "module": "dist/videojs-vimeo.esm.js",
7 | "browser": "dist/videojs-vimeo.umd.js",
8 | "scripts": {
9 | "build:lib": "rollup -c",
10 | "dev": "rollup -c -w"
11 | },
12 | "keywords": [
13 | "videojs",
14 | "videojs-plugin",
15 | "vimeo",
16 | "mobiliza"
17 | ],
18 | "author": "Kevin Aguiar ",
19 | "license": "MIT",
20 | "files": [
21 | "dist/",
22 | "index.html",
23 | "src/"
24 | ],
25 | "dependencies": {
26 | "@vimeo/player": "^2.10.0",
27 | "video.js": "^7.6.6"
28 | },
29 | "devDependencies": {
30 | "@rollup/plugin-commonjs": "^11.0.2",
31 | "@rollup/plugin-node-resolve": "^7.1.1",
32 | "babel-cli": "^6.26.0",
33 | "babel-plugin-transform-object-assign": "^6.22.0",
34 | "babel-preset-es2015": "^6.24.1",
35 | "eslint": "^6.8.0",
36 | "eslint-config-standard": "^14.1.0",
37 | "eslint-config-videojs": "^5.0.2",
38 | "eslint-plugin-import": "^2.20.1",
39 | "eslint-plugin-jsdoc": "^21.0.0",
40 | "eslint-plugin-json-light": "^1.0.3",
41 | "eslint-plugin-markdown": "^1.0.2",
42 | "eslint-plugin-node": "^11.0.0",
43 | "eslint-plugin-promise": "^4.2.1",
44 | "eslint-plugin-standard": "^4.0.1",
45 | "ghooks": "^2.0.4",
46 | "rollup": "^1.32.0"
47 | },
48 | "repository": {
49 | "type": "git",
50 | "url": "git+https://github.com/Mobiliza/videojs-vimeo.git"
51 | },
52 | "bugs": {
53 | "url": "https://github.com/Mobiliza/videojs-vimeo/issues"
54 | },
55 | "homepage": "https://github.com/Mobiliza/videojs-vimeo/#readme"
56 | }
57 |
--------------------------------------------------------------------------------
/src/Vimeo.js:
--------------------------------------------------------------------------------
1 | import videojs from 'video.js';
2 | import VimeoPlayer from '@vimeo/player';
3 |
4 | let cssInjected = false;
5 |
6 | // Since the iframe can't be touched using Vimeo's way of embedding,
7 | // let's add a new styling rule to have the same style as `vjs-tech`
8 | function injectCss() {
9 | if (cssInjected) {
10 | return;
11 | }
12 | cssInjected = true;
13 | const css = `
14 | .vjs-vimeo iframe {
15 | position: absolute;
16 | top: 0;
17 | left: 0;
18 | width: 100%;
19 | height: 100%;
20 | }
21 | `;
22 | const head = document.head || document.getElementsByTagName('head')[0];
23 |
24 | const style = document.createElement('style');
25 |
26 | style.type = 'text/css';
27 |
28 | if (style.styleSheet) {
29 | style.styleSheet.cssText = css;
30 | } else {
31 | style.appendChild(document.createTextNode(css));
32 | }
33 |
34 | head.appendChild(style);
35 | }
36 |
37 | const Tech = videojs.getTech('Tech');
38 |
39 | /**
40 | * Vimeo - Wrapper for Video Player API
41 | *
42 | * @param {Object=} options Object of option names and values
43 | * @param {Function=} ready Ready callback function
44 | * @extends Tech
45 | * @class Vimeo
46 | */
47 | class Vimeo extends Tech {
48 | constructor(options, ready) {
49 | super(options, ready);
50 |
51 | injectCss();
52 | this.setPoster(options.poster);
53 | this.initVimeoPlayer();
54 | }
55 |
56 | initVimeoPlayer() {
57 | const vimeoOptions = {
58 | url: this.options_.source.src,
59 | byline: false,
60 | portrait: false,
61 | title: false
62 | };
63 |
64 | if (this.options_.autoplay) {
65 | vimeoOptions.autoplay = true;
66 | }
67 | if (this.options_.height) {
68 | vimeoOptions.height = this.options_.height;
69 | }
70 | if (this.options_.width) {
71 | vimeoOptions.width = this.options_.width;
72 | }
73 | if (this.options_.maxheight) {
74 | vimeoOptions.maxheight = this.options_.maxheight;
75 | }
76 | if (this.options_.maxwidth) {
77 | vimeoOptions.maxwidth = this.options_.maxwidth;
78 | }
79 | if (this.options_.loop) {
80 | vimeoOptions.loop = this.options_.loop;
81 | }
82 | if (this.options_.color) {
83 | vimeoOptions.color = this.options_.color.replace(/^#/, '');
84 | }
85 |
86 | this._player = new VimeoPlayer(this.el(), vimeoOptions);
87 | this.initVimeoState();
88 |
89 | ['play', 'pause', 'ended', 'timeupdate', 'progress', 'seeked'].forEach(e => {
90 | this._player.on(e, (progress) => {
91 | if (this._vimeoState.progress.duration !== progress.duration) {
92 | this.trigger('durationchange');
93 | }
94 | this._vimeoState.progress = progress;
95 | this.trigger(e);
96 | });
97 | });
98 |
99 | this._player.on('pause', () => (this._vimeoState.playing = false));
100 | this._player.on('play', () => {
101 | this._vimeoState.playing = true;
102 | this._vimeoState.ended = false;
103 | });
104 | this._player.on('ended', () => {
105 | this._vimeoState.playing = false;
106 | this._vimeoState.ended = true;
107 | });
108 | this._player.on('volumechange', (v) => (this._vimeoState.volume = v));
109 | this._player.on('error', e => this.trigger('error', e));
110 |
111 | this.triggerReady();
112 | }
113 |
114 | initVimeoState() {
115 | const state = this._vimeoState = {
116 | ended: false,
117 | playing: false,
118 | volume: 0,
119 | progress: {
120 | seconds: 0,
121 | percent: 0,
122 | duration: 0
123 | }
124 | };
125 |
126 | this._player.getCurrentTime().then(time => (state.progress.seconds = time));
127 | this._player.getDuration().then(time => (state.progress.duration = time));
128 | this._player.getPaused().then(paused => (state.playing = !paused));
129 | this._player.getVolume().then(volume => (state.volume = volume));
130 | }
131 |
132 | createEl() {
133 | const div = videojs.dom.createEl('div', {
134 | id: this.options_.techId
135 | });
136 |
137 | div.style.cssText = 'width:100%;height:100%;top:0;left:0;position:absolute';
138 | div.className = 'vjs-vimeo';
139 |
140 | return div;
141 | }
142 |
143 | controls() {
144 | return true;
145 | }
146 |
147 | supportsFullScreen() {
148 | return true;
149 | }
150 |
151 | src() {
152 | return this.options_.source;
153 | }
154 |
155 | currentSrc() {
156 | return this.options_.source.src;
157 | }
158 |
159 | currentTime() {
160 | return this._vimeoState.progress.seconds;
161 | }
162 |
163 | setCurrentTime(time) {
164 | this._player.setCurrentTime(time);
165 | }
166 |
167 | volume() {
168 | return this._vimeoState.volume;
169 | }
170 |
171 | setVolume(volume) {
172 | return this._player.setVolume(volume);
173 | }
174 |
175 | duration() {
176 | return this._vimeoState.progress.duration;
177 | }
178 |
179 | buffered() {
180 | const progress = this._vimeoState.progress;
181 |
182 | return videojs.createTimeRange(0, progress.percent * progress.duration);
183 | }
184 |
185 | paused() {
186 | return !this._vimeoState.playing;
187 | }
188 |
189 | pause() {
190 | this._player.pause();
191 | }
192 |
193 | play() {
194 | this._player.play();
195 | }
196 |
197 | muted() {
198 | return this._vimeoState.volume === 0;
199 | }
200 |
201 | ended() {
202 | return this._vimeoState.ended;
203 | }
204 |
205 | playbackRate() {
206 | return 1;
207 | }
208 |
209 | }
210 |
211 | Vimeo.prototype.featuresTimeupdateEvents = true;
212 |
213 | Vimeo.isSupported = function () {
214 | return true;
215 | };
216 |
217 | // Add Source Handler pattern functions to this tech
218 | Tech.withSourceHandlers(Vimeo);
219 |
220 | Vimeo.nativeSourceHandler = {
221 | };
222 |
223 | /**
224 | * Check if Vimeo can play the given videotype
225 | *
226 | * @param {string} source The mimetype to check
227 | * @return {string} 'maybe', or '' (empty string)
228 | */
229 | Vimeo.nativeSourceHandler.canPlayType = function (source) {
230 | if (source === 'video/vimeo') {
231 | return 'maybe';
232 | }
233 |
234 | return '';
235 | };
236 |
237 | /*
238 | * Check Vimeo can handle the source natively
239 | *
240 | * @param {Object} source The source object
241 | * @return {String} 'maybe', or '' (empty string)
242 | * @note: Copied over from YouTube — not sure this is relevant
243 | */
244 | Vimeo.nativeSourceHandler.canHandleSource = function (source) {
245 | if (source.type) {
246 | return Vimeo.nativeSourceHandler.canPlayType(source.type);
247 | } else if (source.src) {
248 | return Vimeo.nativeSourceHandler.canPlayType(source.src);
249 | }
250 |
251 | return '';
252 | };
253 |
254 | // @note: Copied over from YouTube — not sure this is relevant
255 | Vimeo.nativeSourceHandler.handleSource = function (source, tech) {
256 | tech.src(source.src);
257 | };
258 |
259 | // @note: Copied over from YouTube — not sure this is relevant
260 | Vimeo.nativeSourceHandler.dispose = function () { };
261 |
262 | Vimeo.registerSourceHandler(Vimeo.nativeSourceHandler);
263 |
264 | // Older versions of VJS5 doesn't have the registerTech function
265 | if (typeof videojs.registerTech !== 'undefined') {
266 | videojs.registerTech('Vimeo', Vimeo);
267 | } else {
268 | videojs.registerComponent('Vimeo', Vimeo);
269 | }
270 |
271 | // Include the version number.
272 | Vimeo.VERSION = '0.0.1';
273 |
274 | export default Vimeo;
275 |
--------------------------------------------------------------------------------
/dist/videojs-vimeo.esm.js:
--------------------------------------------------------------------------------
1 | import videojs from 'video.js';
2 | import VimeoPlayer from '@vimeo/player';
3 |
4 | let cssInjected = false;
5 |
6 | // Since the iframe can't be touched using Vimeo's way of embedding,
7 | // let's add a new styling rule to have the same style as `vjs-tech`
8 | function injectCss() {
9 | if (cssInjected) {
10 | return;
11 | }
12 | cssInjected = true;
13 | const css = `
14 | .vjs-vimeo iframe {
15 | position: absolute;
16 | top: 0;
17 | left: 0;
18 | width: 100%;
19 | height: 100%;
20 | }
21 | `;
22 | const head = document.head || document.getElementsByTagName('head')[0];
23 |
24 | const style = document.createElement('style');
25 |
26 | style.type = 'text/css';
27 |
28 | if (style.styleSheet) {
29 | style.styleSheet.cssText = css;
30 | } else {
31 | style.appendChild(document.createTextNode(css));
32 | }
33 |
34 | head.appendChild(style);
35 | }
36 |
37 | const Tech = videojs.getTech('Tech');
38 |
39 | /**
40 | * Vimeo - Wrapper for Video Player API
41 | *
42 | * @param {Object=} options Object of option names and values
43 | * @param {Function=} ready Ready callback function
44 | * @extends Tech
45 | * @class Vimeo
46 | */
47 | class Vimeo extends Tech {
48 | constructor(options, ready) {
49 | super(options, ready);
50 |
51 | injectCss();
52 | this.setPoster(options.poster);
53 | this.initVimeoPlayer();
54 | }
55 |
56 | initVimeoPlayer() {
57 | const vimeoOptions = {
58 | url: this.options_.source.src,
59 | byline: false,
60 | portrait: false,
61 | title: false
62 | };
63 |
64 | if (this.options_.autoplay) {
65 | vimeoOptions.autoplay = true;
66 | }
67 | if (this.options_.height) {
68 | vimeoOptions.height = this.options_.height;
69 | }
70 | if (this.options_.width) {
71 | vimeoOptions.width = this.options_.width;
72 | }
73 | if (this.options_.maxheight) {
74 | vimeoOptions.maxheight = this.options_.maxheight;
75 | }
76 | if (this.options_.maxwidth) {
77 | vimeoOptions.maxwidth = this.options_.maxwidth;
78 | }
79 | if (this.options_.loop) {
80 | vimeoOptions.loop = this.options_.loop;
81 | }
82 | if (this.options_.color) {
83 | vimeoOptions.color = this.options_.color.replace(/^#/, '');
84 | }
85 |
86 | this._player = new VimeoPlayer(this.el(), vimeoOptions);
87 | this.initVimeoState();
88 |
89 | ['play', 'pause', 'ended', 'timeupdate', 'progress', 'seeked'].forEach(e => {
90 | this._player.on(e, (progress) => {
91 | if (this._vimeoState.progress.duration !== progress.duration) {
92 | this.trigger('durationchange');
93 | }
94 | this._vimeoState.progress = progress;
95 | this.trigger(e);
96 | });
97 | });
98 |
99 | this._player.on('pause', () => (this._vimeoState.playing = false));
100 | this._player.on('play', () => {
101 | this._vimeoState.playing = true;
102 | this._vimeoState.ended = false;
103 | });
104 | this._player.on('ended', () => {
105 | this._vimeoState.playing = false;
106 | this._vimeoState.ended = true;
107 | });
108 | this._player.on('volumechange', (v) => (this._vimeoState.volume = v));
109 | this._player.on('error', e => this.trigger('error', e));
110 |
111 | this.triggerReady();
112 | }
113 |
114 | initVimeoState() {
115 | const state = this._vimeoState = {
116 | ended: false,
117 | playing: false,
118 | volume: 0,
119 | progress: {
120 | seconds: 0,
121 | percent: 0,
122 | duration: 0
123 | }
124 | };
125 |
126 | this._player.getCurrentTime().then(time => (state.progress.seconds = time));
127 | this._player.getDuration().then(time => (state.progress.duration = time));
128 | this._player.getPaused().then(paused => (state.playing = !paused));
129 | this._player.getVolume().then(volume => (state.volume = volume));
130 | }
131 |
132 | createEl() {
133 | const div = videojs.dom.createEl('div', {
134 | id: this.options_.techId
135 | });
136 |
137 | div.style.cssText = 'width:100%;height:100%;top:0;left:0;position:absolute';
138 | div.className = 'vjs-vimeo';
139 |
140 | return div;
141 | }
142 |
143 | controls() {
144 | return true;
145 | }
146 |
147 | supportsFullScreen() {
148 | return true;
149 | }
150 |
151 | src() {
152 | return this.options_.source;
153 | }
154 |
155 | currentSrc() {
156 | return this.options_.source.src;
157 | }
158 |
159 | currentTime() {
160 | return this._vimeoState.progress.seconds;
161 | }
162 |
163 | setCurrentTime(time) {
164 | this._player.setCurrentTime(time);
165 | }
166 |
167 | volume() {
168 | return this._vimeoState.volume;
169 | }
170 |
171 | setVolume(volume) {
172 | return this._player.setVolume(volume);
173 | }
174 |
175 | duration() {
176 | return this._vimeoState.progress.duration;
177 | }
178 |
179 | buffered() {
180 | const progress = this._vimeoState.progress;
181 |
182 | return videojs.createTimeRange(0, progress.percent * progress.duration);
183 | }
184 |
185 | paused() {
186 | return !this._vimeoState.playing;
187 | }
188 |
189 | pause() {
190 | this._player.pause();
191 | }
192 |
193 | play() {
194 | this._player.play();
195 | }
196 |
197 | muted() {
198 | return this._vimeoState.volume === 0;
199 | }
200 |
201 | ended() {
202 | return this._vimeoState.ended;
203 | }
204 |
205 | playbackRate() {
206 | return 1;
207 | }
208 |
209 | }
210 |
211 | Vimeo.prototype.featuresTimeupdateEvents = true;
212 |
213 | Vimeo.isSupported = function () {
214 | return true;
215 | };
216 |
217 | // Add Source Handler pattern functions to this tech
218 | Tech.withSourceHandlers(Vimeo);
219 |
220 | Vimeo.nativeSourceHandler = {
221 | };
222 |
223 | /**
224 | * Check if Vimeo can play the given videotype
225 | *
226 | * @param {string} source The mimetype to check
227 | * @return {string} 'maybe', or '' (empty string)
228 | */
229 | Vimeo.nativeSourceHandler.canPlayType = function (source) {
230 | if (source === 'video/vimeo') {
231 | return 'maybe';
232 | }
233 |
234 | return '';
235 | };
236 |
237 | /*
238 | * Check Vimeo can handle the source natively
239 | *
240 | * @param {Object} source The source object
241 | * @return {String} 'maybe', or '' (empty string)
242 | * @note: Copied over from YouTube — not sure this is relevant
243 | */
244 | Vimeo.nativeSourceHandler.canHandleSource = function (source) {
245 | if (source.type) {
246 | return Vimeo.nativeSourceHandler.canPlayType(source.type);
247 | } else if (source.src) {
248 | return Vimeo.nativeSourceHandler.canPlayType(source.src);
249 | }
250 |
251 | return '';
252 | };
253 |
254 | // @note: Copied over from YouTube — not sure this is relevant
255 | Vimeo.nativeSourceHandler.handleSource = function (source, tech) {
256 | tech.src(source.src);
257 | };
258 |
259 | // @note: Copied over from YouTube — not sure this is relevant
260 | Vimeo.nativeSourceHandler.dispose = function () { };
261 |
262 | Vimeo.registerSourceHandler(Vimeo.nativeSourceHandler);
263 |
264 | // Older versions of VJS5 doesn't have the registerTech function
265 | if (typeof videojs.registerTech !== 'undefined') {
266 | videojs.registerTech('Vimeo', Vimeo);
267 | } else {
268 | videojs.registerComponent('Vimeo', Vimeo);
269 | }
270 |
271 | // Include the version number.
272 | Vimeo.VERSION = '0.0.1';
273 |
274 | export default Vimeo;
275 |
--------------------------------------------------------------------------------
/dist/videojs-vimeo.cjs.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
4 |
5 | var videojs = _interopDefault(require('video.js'));
6 | var VimeoPlayer = _interopDefault(require('@vimeo/player'));
7 |
8 | let cssInjected = false;
9 |
10 | // Since the iframe can't be touched using Vimeo's way of embedding,
11 | // let's add a new styling rule to have the same style as `vjs-tech`
12 | function injectCss() {
13 | if (cssInjected) {
14 | return;
15 | }
16 | cssInjected = true;
17 | const css = `
18 | .vjs-vimeo iframe {
19 | position: absolute;
20 | top: 0;
21 | left: 0;
22 | width: 100%;
23 | height: 100%;
24 | }
25 | `;
26 | const head = document.head || document.getElementsByTagName('head')[0];
27 |
28 | const style = document.createElement('style');
29 |
30 | style.type = 'text/css';
31 |
32 | if (style.styleSheet) {
33 | style.styleSheet.cssText = css;
34 | } else {
35 | style.appendChild(document.createTextNode(css));
36 | }
37 |
38 | head.appendChild(style);
39 | }
40 |
41 | const Tech = videojs.getTech('Tech');
42 |
43 | /**
44 | * Vimeo - Wrapper for Video Player API
45 | *
46 | * @param {Object=} options Object of option names and values
47 | * @param {Function=} ready Ready callback function
48 | * @extends Tech
49 | * @class Vimeo
50 | */
51 | class Vimeo extends Tech {
52 | constructor(options, ready) {
53 | super(options, ready);
54 |
55 | injectCss();
56 | this.setPoster(options.poster);
57 | this.initVimeoPlayer();
58 | }
59 |
60 | initVimeoPlayer() {
61 | const vimeoOptions = {
62 | url: this.options_.source.src,
63 | byline: false,
64 | portrait: false,
65 | title: false
66 | };
67 |
68 | if (this.options_.autoplay) {
69 | vimeoOptions.autoplay = true;
70 | }
71 | if (this.options_.height) {
72 | vimeoOptions.height = this.options_.height;
73 | }
74 | if (this.options_.width) {
75 | vimeoOptions.width = this.options_.width;
76 | }
77 | if (this.options_.maxheight) {
78 | vimeoOptions.maxheight = this.options_.maxheight;
79 | }
80 | if (this.options_.maxwidth) {
81 | vimeoOptions.maxwidth = this.options_.maxwidth;
82 | }
83 | if (this.options_.loop) {
84 | vimeoOptions.loop = this.options_.loop;
85 | }
86 | if (this.options_.color) {
87 | vimeoOptions.color = this.options_.color.replace(/^#/, '');
88 | }
89 |
90 | this._player = new VimeoPlayer(this.el(), vimeoOptions);
91 | this.initVimeoState();
92 |
93 | ['play', 'pause', 'ended', 'timeupdate', 'progress', 'seeked'].forEach(e => {
94 | this._player.on(e, (progress) => {
95 | if (this._vimeoState.progress.duration !== progress.duration) {
96 | this.trigger('durationchange');
97 | }
98 | this._vimeoState.progress = progress;
99 | this.trigger(e);
100 | });
101 | });
102 |
103 | this._player.on('pause', () => (this._vimeoState.playing = false));
104 | this._player.on('play', () => {
105 | this._vimeoState.playing = true;
106 | this._vimeoState.ended = false;
107 | });
108 | this._player.on('ended', () => {
109 | this._vimeoState.playing = false;
110 | this._vimeoState.ended = true;
111 | });
112 | this._player.on('volumechange', (v) => (this._vimeoState.volume = v));
113 | this._player.on('error', e => this.trigger('error', e));
114 |
115 | this.triggerReady();
116 | }
117 |
118 | initVimeoState() {
119 | const state = this._vimeoState = {
120 | ended: false,
121 | playing: false,
122 | volume: 0,
123 | progress: {
124 | seconds: 0,
125 | percent: 0,
126 | duration: 0
127 | }
128 | };
129 |
130 | this._player.getCurrentTime().then(time => (state.progress.seconds = time));
131 | this._player.getDuration().then(time => (state.progress.duration = time));
132 | this._player.getPaused().then(paused => (state.playing = !paused));
133 | this._player.getVolume().then(volume => (state.volume = volume));
134 | }
135 |
136 | createEl() {
137 | const div = videojs.dom.createEl('div', {
138 | id: this.options_.techId
139 | });
140 |
141 | div.style.cssText = 'width:100%;height:100%;top:0;left:0;position:absolute';
142 | div.className = 'vjs-vimeo';
143 |
144 | return div;
145 | }
146 |
147 | controls() {
148 | return true;
149 | }
150 |
151 | supportsFullScreen() {
152 | return true;
153 | }
154 |
155 | src() {
156 | return this.options_.source;
157 | }
158 |
159 | currentSrc() {
160 | return this.options_.source.src;
161 | }
162 |
163 | currentTime() {
164 | return this._vimeoState.progress.seconds;
165 | }
166 |
167 | setCurrentTime(time) {
168 | this._player.setCurrentTime(time);
169 | }
170 |
171 | volume() {
172 | return this._vimeoState.volume;
173 | }
174 |
175 | setVolume(volume) {
176 | return this._player.setVolume(volume);
177 | }
178 |
179 | duration() {
180 | return this._vimeoState.progress.duration;
181 | }
182 |
183 | buffered() {
184 | const progress = this._vimeoState.progress;
185 |
186 | return videojs.createTimeRange(0, progress.percent * progress.duration);
187 | }
188 |
189 | paused() {
190 | return !this._vimeoState.playing;
191 | }
192 |
193 | pause() {
194 | this._player.pause();
195 | }
196 |
197 | play() {
198 | this._player.play();
199 | }
200 |
201 | muted() {
202 | return this._vimeoState.volume === 0;
203 | }
204 |
205 | ended() {
206 | return this._vimeoState.ended;
207 | }
208 |
209 | playbackRate() {
210 | return 1;
211 | }
212 |
213 | }
214 |
215 | Vimeo.prototype.featuresTimeupdateEvents = true;
216 |
217 | Vimeo.isSupported = function () {
218 | return true;
219 | };
220 |
221 | // Add Source Handler pattern functions to this tech
222 | Tech.withSourceHandlers(Vimeo);
223 |
224 | Vimeo.nativeSourceHandler = {
225 | };
226 |
227 | /**
228 | * Check if Vimeo can play the given videotype
229 | *
230 | * @param {string} source The mimetype to check
231 | * @return {string} 'maybe', or '' (empty string)
232 | */
233 | Vimeo.nativeSourceHandler.canPlayType = function (source) {
234 | if (source === 'video/vimeo') {
235 | return 'maybe';
236 | }
237 |
238 | return '';
239 | };
240 |
241 | /*
242 | * Check Vimeo can handle the source natively
243 | *
244 | * @param {Object} source The source object
245 | * @return {String} 'maybe', or '' (empty string)
246 | * @note: Copied over from YouTube — not sure this is relevant
247 | */
248 | Vimeo.nativeSourceHandler.canHandleSource = function (source) {
249 | if (source.type) {
250 | return Vimeo.nativeSourceHandler.canPlayType(source.type);
251 | } else if (source.src) {
252 | return Vimeo.nativeSourceHandler.canPlayType(source.src);
253 | }
254 |
255 | return '';
256 | };
257 |
258 | // @note: Copied over from YouTube — not sure this is relevant
259 | Vimeo.nativeSourceHandler.handleSource = function (source, tech) {
260 | tech.src(source.src);
261 | };
262 |
263 | // @note: Copied over from YouTube — not sure this is relevant
264 | Vimeo.nativeSourceHandler.dispose = function () { };
265 |
266 | Vimeo.registerSourceHandler(Vimeo.nativeSourceHandler);
267 |
268 | // Older versions of VJS5 doesn't have the registerTech function
269 | if (typeof videojs.registerTech !== 'undefined') {
270 | videojs.registerTech('Vimeo', Vimeo);
271 | } else {
272 | videojs.registerComponent('Vimeo', Vimeo);
273 | }
274 |
275 | // Include the version number.
276 | Vimeo.VERSION = '0.0.1';
277 |
278 | module.exports = Vimeo;
279 |
--------------------------------------------------------------------------------
/dist/videojs-vimeo.umd.js:
--------------------------------------------------------------------------------
1 | (function (global, factory) {
2 | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('video.js')) :
3 | typeof define === 'function' && define.amd ? define(['video.js'], factory) :
4 | (global = global || self, global['videojs-vimeo'] = factory(global.videojs));
5 | }(this, (function (videojs) { 'use strict';
6 |
7 | videojs = videojs && videojs.hasOwnProperty('default') ? videojs['default'] : videojs;
8 |
9 | /*! @vimeo/player v2.10.0 | (c) 2019 Vimeo | MIT License | https://github.com/vimeo/player.js */
10 | function _classCallCheck(instance, Constructor) {
11 | if (!(instance instanceof Constructor)) {
12 | throw new TypeError("Cannot call a class as a function");
13 | }
14 | }
15 |
16 | function _defineProperties(target, props) {
17 | for (var i = 0; i < props.length; i++) {
18 | var descriptor = props[i];
19 | descriptor.enumerable = descriptor.enumerable || false;
20 | descriptor.configurable = true;
21 | if ("value" in descriptor) descriptor.writable = true;
22 | Object.defineProperty(target, descriptor.key, descriptor);
23 | }
24 | }
25 |
26 | function _createClass(Constructor, protoProps, staticProps) {
27 | if (protoProps) _defineProperties(Constructor.prototype, protoProps);
28 | if (staticProps) _defineProperties(Constructor, staticProps);
29 | return Constructor;
30 | }
31 |
32 | /**
33 | * @module lib/functions
34 | */
35 |
36 | /**
37 | * Check to see this is a node environment.
38 | * @type {Boolean}
39 | */
40 |
41 | /* global global */
42 | var isNode = typeof global !== 'undefined' && {}.toString.call(global) === '[object global]';
43 | /**
44 | * Get the name of the method for a given getter or setter.
45 | *
46 | * @param {string} prop The name of the property.
47 | * @param {string} type Either “get” or “set”.
48 | * @return {string}
49 | */
50 |
51 | function getMethodName(prop, type) {
52 | if (prop.indexOf(type.toLowerCase()) === 0) {
53 | return prop;
54 | }
55 |
56 | return "".concat(type.toLowerCase()).concat(prop.substr(0, 1).toUpperCase()).concat(prop.substr(1));
57 | }
58 | /**
59 | * Check to see if the object is a DOM Element.
60 | *
61 | * @param {*} element The object to check.
62 | * @return {boolean}
63 | */
64 |
65 | function isDomElement(element) {
66 | return Boolean(element && element.nodeType === 1 && 'nodeName' in element && element.ownerDocument && element.ownerDocument.defaultView);
67 | }
68 | /**
69 | * Check to see whether the value is a number.
70 | *
71 | * @see http://dl.dropboxusercontent.com/u/35146/js/tests/isNumber.html
72 | * @param {*} value The value to check.
73 | * @param {boolean} integer Check if the value is an integer.
74 | * @return {boolean}
75 | */
76 |
77 | function isInteger(value) {
78 | // eslint-disable-next-line eqeqeq
79 | return !isNaN(parseFloat(value)) && isFinite(value) && Math.floor(value) == value;
80 | }
81 | /**
82 | * Check to see if the URL is a Vimeo url.
83 | *
84 | * @param {string} url The url string.
85 | * @return {boolean}
86 | */
87 |
88 | function isVimeoUrl(url) {
89 | return /^(https?:)?\/\/((player|www)\.)?vimeo\.com(?=$|\/)/.test(url);
90 | }
91 | /**
92 | * Get the Vimeo URL from an element.
93 | * The element must have either a data-vimeo-id or data-vimeo-url attribute.
94 | *
95 | * @param {object} oEmbedParameters The oEmbed parameters.
96 | * @return {string}
97 | */
98 |
99 | function getVimeoUrl() {
100 | var oEmbedParameters = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
101 | var id = oEmbedParameters.id;
102 | var url = oEmbedParameters.url;
103 | var idOrUrl = id || url;
104 |
105 | if (!idOrUrl) {
106 | throw new Error('An id or url must be passed, either in an options object or as a data-vimeo-id or data-vimeo-url attribute.');
107 | }
108 |
109 | if (isInteger(idOrUrl)) {
110 | return "https://vimeo.com/".concat(idOrUrl);
111 | }
112 |
113 | if (isVimeoUrl(idOrUrl)) {
114 | return idOrUrl.replace('http:', 'https:');
115 | }
116 |
117 | if (id) {
118 | throw new TypeError("\u201C".concat(id, "\u201D is not a valid video id."));
119 | }
120 |
121 | throw new TypeError("\u201C".concat(idOrUrl, "\u201D is not a vimeo.com url."));
122 | }
123 |
124 | var arrayIndexOfSupport = typeof Array.prototype.indexOf !== 'undefined';
125 | var postMessageSupport = typeof window !== 'undefined' && typeof window.postMessage !== 'undefined';
126 |
127 | if (!isNode && (!arrayIndexOfSupport || !postMessageSupport)) {
128 | throw new Error('Sorry, the Vimeo Player API is not available in this browser.');
129 | }
130 |
131 | var commonjsGlobal = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
132 |
133 | function createCommonjsModule(fn, module) {
134 | return module = { exports: {} }, fn(module, module.exports), module.exports;
135 | }
136 |
137 | /*!
138 | * weakmap-polyfill v2.0.0 - ECMAScript6 WeakMap polyfill
139 | * https://github.com/polygonplanet/weakmap-polyfill
140 | * Copyright (c) 2015-2016 polygon planet
141 | * @license MIT
142 | */
143 | (function (self) {
144 |
145 | if (self.WeakMap) {
146 | return;
147 | }
148 |
149 | var hasOwnProperty = Object.prototype.hasOwnProperty;
150 |
151 | var defineProperty = function (object, name, value) {
152 | if (Object.defineProperty) {
153 | Object.defineProperty(object, name, {
154 | configurable: true,
155 | writable: true,
156 | value: value
157 | });
158 | } else {
159 | object[name] = value;
160 | }
161 | };
162 |
163 | self.WeakMap = function () {
164 | // ECMA-262 23.3 WeakMap Objects
165 | function WeakMap() {
166 | if (this === void 0) {
167 | throw new TypeError("Constructor WeakMap requires 'new'");
168 | }
169 |
170 | defineProperty(this, '_id', genId('_WeakMap')); // ECMA-262 23.3.1.1 WeakMap([iterable])
171 |
172 | if (arguments.length > 0) {
173 | // Currently, WeakMap `iterable` argument is not supported
174 | throw new TypeError('WeakMap iterable is not supported');
175 | }
176 | } // ECMA-262 23.3.3.2 WeakMap.prototype.delete(key)
177 |
178 |
179 | defineProperty(WeakMap.prototype, 'delete', function (key) {
180 | checkInstance(this, 'delete');
181 |
182 | if (!isObject(key)) {
183 | return false;
184 | }
185 |
186 | var entry = key[this._id];
187 |
188 | if (entry && entry[0] === key) {
189 | delete key[this._id];
190 | return true;
191 | }
192 |
193 | return false;
194 | }); // ECMA-262 23.3.3.3 WeakMap.prototype.get(key)
195 |
196 | defineProperty(WeakMap.prototype, 'get', function (key) {
197 | checkInstance(this, 'get');
198 |
199 | if (!isObject(key)) {
200 | return void 0;
201 | }
202 |
203 | var entry = key[this._id];
204 |
205 | if (entry && entry[0] === key) {
206 | return entry[1];
207 | }
208 |
209 | return void 0;
210 | }); // ECMA-262 23.3.3.4 WeakMap.prototype.has(key)
211 |
212 | defineProperty(WeakMap.prototype, 'has', function (key) {
213 | checkInstance(this, 'has');
214 |
215 | if (!isObject(key)) {
216 | return false;
217 | }
218 |
219 | var entry = key[this._id];
220 |
221 | if (entry && entry[0] === key) {
222 | return true;
223 | }
224 |
225 | return false;
226 | }); // ECMA-262 23.3.3.5 WeakMap.prototype.set(key, value)
227 |
228 | defineProperty(WeakMap.prototype, 'set', function (key, value) {
229 | checkInstance(this, 'set');
230 |
231 | if (!isObject(key)) {
232 | throw new TypeError('Invalid value used as weak map key');
233 | }
234 |
235 | var entry = key[this._id];
236 |
237 | if (entry && entry[0] === key) {
238 | entry[1] = value;
239 | return this;
240 | }
241 |
242 | defineProperty(key, this._id, [key, value]);
243 | return this;
244 | });
245 |
246 | function checkInstance(x, methodName) {
247 | if (!isObject(x) || !hasOwnProperty.call(x, '_id')) {
248 | throw new TypeError(methodName + ' method called on incompatible receiver ' + typeof x);
249 | }
250 | }
251 |
252 | function genId(prefix) {
253 | return prefix + '_' + rand() + '.' + rand();
254 | }
255 |
256 | function rand() {
257 | return Math.random().toString().substring(2);
258 | }
259 |
260 | defineProperty(WeakMap, '_polyfill', true);
261 | return WeakMap;
262 | }();
263 |
264 | function isObject(x) {
265 | return Object(x) === x;
266 | }
267 | })(typeof self !== 'undefined' ? self : typeof window !== 'undefined' ? window : typeof commonjsGlobal !== 'undefined' ? commonjsGlobal : commonjsGlobal);
268 |
269 | var npo_src = createCommonjsModule(function (module) {
270 | /*! Native Promise Only
271 | v0.8.1 (c) Kyle Simpson
272 | MIT License: http://getify.mit-license.org
273 | */
274 | (function UMD(name, context, definition) {
275 | // special form of UMD for polyfilling across evironments
276 | context[name] = context[name] || definition();
277 |
278 | if (module.exports) {
279 | module.exports = context[name];
280 | }
281 | })("Promise", typeof commonjsGlobal != "undefined" ? commonjsGlobal : commonjsGlobal, function DEF() {
282 |
283 | var builtInProp,
284 | cycle,
285 | scheduling_queue,
286 | ToString = Object.prototype.toString,
287 | timer = typeof setImmediate != "undefined" ? function timer(fn) {
288 | return setImmediate(fn);
289 | } : setTimeout; // dammit, IE8.
290 |
291 | try {
292 | Object.defineProperty({}, "x", {});
293 |
294 | builtInProp = function builtInProp(obj, name, val, config) {
295 | return Object.defineProperty(obj, name, {
296 | value: val,
297 | writable: true,
298 | configurable: config !== false
299 | });
300 | };
301 | } catch (err) {
302 | builtInProp = function builtInProp(obj, name, val) {
303 | obj[name] = val;
304 | return obj;
305 | };
306 | } // Note: using a queue instead of array for efficiency
307 |
308 |
309 | scheduling_queue = function Queue() {
310 | var first, last, item;
311 |
312 | function Item(fn, self) {
313 | this.fn = fn;
314 | this.self = self;
315 | this.next = void 0;
316 | }
317 |
318 | return {
319 | add: function add(fn, self) {
320 | item = new Item(fn, self);
321 |
322 | if (last) {
323 | last.next = item;
324 | } else {
325 | first = item;
326 | }
327 |
328 | last = item;
329 | item = void 0;
330 | },
331 | drain: function drain() {
332 | var f = first;
333 | first = last = cycle = void 0;
334 |
335 | while (f) {
336 | f.fn.call(f.self);
337 | f = f.next;
338 | }
339 | }
340 | };
341 | }();
342 |
343 | function schedule(fn, self) {
344 | scheduling_queue.add(fn, self);
345 |
346 | if (!cycle) {
347 | cycle = timer(scheduling_queue.drain);
348 | }
349 | } // promise duck typing
350 |
351 |
352 | function isThenable(o) {
353 | var _then,
354 | o_type = typeof o;
355 |
356 | if (o != null && (o_type == "object" || o_type == "function")) {
357 | _then = o.then;
358 | }
359 |
360 | return typeof _then == "function" ? _then : false;
361 | }
362 |
363 | function notify() {
364 | for (var i = 0; i < this.chain.length; i++) {
365 | notifyIsolated(this, this.state === 1 ? this.chain[i].success : this.chain[i].failure, this.chain[i]);
366 | }
367 |
368 | this.chain.length = 0;
369 | } // NOTE: This is a separate function to isolate
370 | // the `try..catch` so that other code can be
371 | // optimized better
372 |
373 |
374 | function notifyIsolated(self, cb, chain) {
375 | var ret, _then;
376 |
377 | try {
378 | if (cb === false) {
379 | chain.reject(self.msg);
380 | } else {
381 | if (cb === true) {
382 | ret = self.msg;
383 | } else {
384 | ret = cb.call(void 0, self.msg);
385 | }
386 |
387 | if (ret === chain.promise) {
388 | chain.reject(TypeError("Promise-chain cycle"));
389 | } else if (_then = isThenable(ret)) {
390 | _then.call(ret, chain.resolve, chain.reject);
391 | } else {
392 | chain.resolve(ret);
393 | }
394 | }
395 | } catch (err) {
396 | chain.reject(err);
397 | }
398 | }
399 |
400 | function resolve(msg) {
401 | var _then,
402 | self = this; // already triggered?
403 |
404 |
405 | if (self.triggered) {
406 | return;
407 | }
408 |
409 | self.triggered = true; // unwrap
410 |
411 | if (self.def) {
412 | self = self.def;
413 | }
414 |
415 | try {
416 | if (_then = isThenable(msg)) {
417 | schedule(function () {
418 | var def_wrapper = new MakeDefWrapper(self);
419 |
420 | try {
421 | _then.call(msg, function $resolve$() {
422 | resolve.apply(def_wrapper, arguments);
423 | }, function $reject$() {
424 | reject.apply(def_wrapper, arguments);
425 | });
426 | } catch (err) {
427 | reject.call(def_wrapper, err);
428 | }
429 | });
430 | } else {
431 | self.msg = msg;
432 | self.state = 1;
433 |
434 | if (self.chain.length > 0) {
435 | schedule(notify, self);
436 | }
437 | }
438 | } catch (err) {
439 | reject.call(new MakeDefWrapper(self), err);
440 | }
441 | }
442 |
443 | function reject(msg) {
444 | var self = this; // already triggered?
445 |
446 | if (self.triggered) {
447 | return;
448 | }
449 |
450 | self.triggered = true; // unwrap
451 |
452 | if (self.def) {
453 | self = self.def;
454 | }
455 |
456 | self.msg = msg;
457 | self.state = 2;
458 |
459 | if (self.chain.length > 0) {
460 | schedule(notify, self);
461 | }
462 | }
463 |
464 | function iteratePromises(Constructor, arr, resolver, rejecter) {
465 | for (var idx = 0; idx < arr.length; idx++) {
466 | (function IIFE(idx) {
467 | Constructor.resolve(arr[idx]).then(function $resolver$(msg) {
468 | resolver(idx, msg);
469 | }, rejecter);
470 | })(idx);
471 | }
472 | }
473 |
474 | function MakeDefWrapper(self) {
475 | this.def = self;
476 | this.triggered = false;
477 | }
478 |
479 | function MakeDef(self) {
480 | this.promise = self;
481 | this.state = 0;
482 | this.triggered = false;
483 | this.chain = [];
484 | this.msg = void 0;
485 | }
486 |
487 | function Promise(executor) {
488 | if (typeof executor != "function") {
489 | throw TypeError("Not a function");
490 | }
491 |
492 | if (this.__NPO__ !== 0) {
493 | throw TypeError("Not a promise");
494 | } // instance shadowing the inherited "brand"
495 | // to signal an already "initialized" promise
496 |
497 |
498 | this.__NPO__ = 1;
499 | var def = new MakeDef(this);
500 |
501 | this["then"] = function then(success, failure) {
502 | var o = {
503 | success: typeof success == "function" ? success : true,
504 | failure: typeof failure == "function" ? failure : false
505 | }; // Note: `then(..)` itself can be borrowed to be used against
506 | // a different promise constructor for making the chained promise,
507 | // by substituting a different `this` binding.
508 |
509 | o.promise = new this.constructor(function extractChain(resolve, reject) {
510 | if (typeof resolve != "function" || typeof reject != "function") {
511 | throw TypeError("Not a function");
512 | }
513 |
514 | o.resolve = resolve;
515 | o.reject = reject;
516 | });
517 | def.chain.push(o);
518 |
519 | if (def.state !== 0) {
520 | schedule(notify, def);
521 | }
522 |
523 | return o.promise;
524 | };
525 |
526 | this["catch"] = function $catch$(failure) {
527 | return this.then(void 0, failure);
528 | };
529 |
530 | try {
531 | executor.call(void 0, function publicResolve(msg) {
532 | resolve.call(def, msg);
533 | }, function publicReject(msg) {
534 | reject.call(def, msg);
535 | });
536 | } catch (err) {
537 | reject.call(def, err);
538 | }
539 | }
540 |
541 | var PromisePrototype = builtInProp({}, "constructor", Promise,
542 | /*configurable=*/
543 | false); // Note: Android 4 cannot use `Object.defineProperty(..)` here
544 |
545 | Promise.prototype = PromisePrototype; // built-in "brand" to signal an "uninitialized" promise
546 |
547 | builtInProp(PromisePrototype, "__NPO__", 0,
548 | /*configurable=*/
549 | false);
550 | builtInProp(Promise, "resolve", function Promise$resolve(msg) {
551 | var Constructor = this; // spec mandated checks
552 | // note: best "isPromise" check that's practical for now
553 |
554 | if (msg && typeof msg == "object" && msg.__NPO__ === 1) {
555 | return msg;
556 | }
557 |
558 | return new Constructor(function executor(resolve, reject) {
559 | if (typeof resolve != "function" || typeof reject != "function") {
560 | throw TypeError("Not a function");
561 | }
562 |
563 | resolve(msg);
564 | });
565 | });
566 | builtInProp(Promise, "reject", function Promise$reject(msg) {
567 | return new this(function executor(resolve, reject) {
568 | if (typeof resolve != "function" || typeof reject != "function") {
569 | throw TypeError("Not a function");
570 | }
571 |
572 | reject(msg);
573 | });
574 | });
575 | builtInProp(Promise, "all", function Promise$all(arr) {
576 | var Constructor = this; // spec mandated checks
577 |
578 | if (ToString.call(arr) != "[object Array]") {
579 | return Constructor.reject(TypeError("Not an array"));
580 | }
581 |
582 | if (arr.length === 0) {
583 | return Constructor.resolve([]);
584 | }
585 |
586 | return new Constructor(function executor(resolve, reject) {
587 | if (typeof resolve != "function" || typeof reject != "function") {
588 | throw TypeError("Not a function");
589 | }
590 |
591 | var len = arr.length,
592 | msgs = Array(len),
593 | count = 0;
594 | iteratePromises(Constructor, arr, function resolver(idx, msg) {
595 | msgs[idx] = msg;
596 |
597 | if (++count === len) {
598 | resolve(msgs);
599 | }
600 | }, reject);
601 | });
602 | });
603 | builtInProp(Promise, "race", function Promise$race(arr) {
604 | var Constructor = this; // spec mandated checks
605 |
606 | if (ToString.call(arr) != "[object Array]") {
607 | return Constructor.reject(TypeError("Not an array"));
608 | }
609 |
610 | return new Constructor(function executor(resolve, reject) {
611 | if (typeof resolve != "function" || typeof reject != "function") {
612 | throw TypeError("Not a function");
613 | }
614 |
615 | iteratePromises(Constructor, arr, function resolver(idx, msg) {
616 | resolve(msg);
617 | }, reject);
618 | });
619 | });
620 | return Promise;
621 | });
622 | });
623 |
624 | /**
625 | * @module lib/callbacks
626 | */
627 | var callbackMap = new WeakMap();
628 | /**
629 | * Store a callback for a method or event for a player.
630 | *
631 | * @param {Player} player The player object.
632 | * @param {string} name The method or event name.
633 | * @param {(function(this:Player, *): void|{resolve: function, reject: function})} callback
634 | * The callback to call or an object with resolve and reject functions for a promise.
635 | * @return {void}
636 | */
637 |
638 | function storeCallback(player, name, callback) {
639 | var playerCallbacks = callbackMap.get(player.element) || {};
640 |
641 | if (!(name in playerCallbacks)) {
642 | playerCallbacks[name] = [];
643 | }
644 |
645 | playerCallbacks[name].push(callback);
646 | callbackMap.set(player.element, playerCallbacks);
647 | }
648 | /**
649 | * Get the callbacks for a player and event or method.
650 | *
651 | * @param {Player} player The player object.
652 | * @param {string} name The method or event name
653 | * @return {function[]}
654 | */
655 |
656 | function getCallbacks(player, name) {
657 | var playerCallbacks = callbackMap.get(player.element) || {};
658 | return playerCallbacks[name] || [];
659 | }
660 | /**
661 | * Remove a stored callback for a method or event for a player.
662 | *
663 | * @param {Player} player The player object.
664 | * @param {string} name The method or event name
665 | * @param {function} [callback] The specific callback to remove.
666 | * @return {boolean} Was this the last callback?
667 | */
668 |
669 | function removeCallback(player, name, callback) {
670 | var playerCallbacks = callbackMap.get(player.element) || {};
671 |
672 | if (!playerCallbacks[name]) {
673 | return true;
674 | } // If no callback is passed, remove all callbacks for the event
675 |
676 |
677 | if (!callback) {
678 | playerCallbacks[name] = [];
679 | callbackMap.set(player.element, playerCallbacks);
680 | return true;
681 | }
682 |
683 | var index = playerCallbacks[name].indexOf(callback);
684 |
685 | if (index !== -1) {
686 | playerCallbacks[name].splice(index, 1);
687 | }
688 |
689 | callbackMap.set(player.element, playerCallbacks);
690 | return playerCallbacks[name] && playerCallbacks[name].length === 0;
691 | }
692 | /**
693 | * Return the first stored callback for a player and event or method.
694 | *
695 | * @param {Player} player The player object.
696 | * @param {string} name The method or event name.
697 | * @return {function} The callback, or false if there were none
698 | */
699 |
700 | function shiftCallbacks(player, name) {
701 | var playerCallbacks = getCallbacks(player, name);
702 |
703 | if (playerCallbacks.length < 1) {
704 | return false;
705 | }
706 |
707 | var callback = playerCallbacks.shift();
708 | removeCallback(player, name, callback);
709 | return callback;
710 | }
711 | /**
712 | * Move callbacks associated with an element to another element.
713 | *
714 | * @param {HTMLElement} oldElement The old element.
715 | * @param {HTMLElement} newElement The new element.
716 | * @return {void}
717 | */
718 |
719 | function swapCallbacks(oldElement, newElement) {
720 | var playerCallbacks = callbackMap.get(oldElement);
721 | callbackMap.set(newElement, playerCallbacks);
722 | callbackMap.delete(oldElement);
723 | }
724 |
725 | /**
726 | * @module lib/embed
727 | */
728 | var oEmbedParameters = ['autopause', 'autoplay', 'background', 'byline', 'color', 'controls', 'dnt', 'height', 'id', 'loop', 'maxheight', 'maxwidth', 'muted', 'playsinline', 'portrait', 'responsive', 'speed', 'texttrack', 'title', 'transparent', 'url', 'width'];
729 | /**
730 | * Get the 'data-vimeo'-prefixed attributes from an element as an object.
731 | *
732 | * @param {HTMLElement} element The element.
733 | * @param {Object} [defaults={}] The default values to use.
734 | * @return {Object}
735 | */
736 |
737 | function getOEmbedParameters(element) {
738 | var defaults = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
739 | return oEmbedParameters.reduce(function (params, param) {
740 | var value = element.getAttribute("data-vimeo-".concat(param));
741 |
742 | if (value || value === '') {
743 | params[param] = value === '' ? 1 : value;
744 | }
745 |
746 | return params;
747 | }, defaults);
748 | }
749 | /**
750 | * Create an embed from oEmbed data inside an element.
751 | *
752 | * @param {object} data The oEmbed data.
753 | * @param {HTMLElement} element The element to put the iframe in.
754 | * @return {HTMLIFrameElement} The iframe embed.
755 | */
756 |
757 | function createEmbed(_ref, element) {
758 | var html = _ref.html;
759 |
760 | if (!element) {
761 | throw new TypeError('An element must be provided');
762 | }
763 |
764 | if (element.getAttribute('data-vimeo-initialized') !== null) {
765 | return element.querySelector('iframe');
766 | }
767 |
768 | var div = document.createElement('div');
769 | div.innerHTML = html;
770 | element.appendChild(div.firstChild);
771 | element.setAttribute('data-vimeo-initialized', 'true');
772 | return element.querySelector('iframe');
773 | }
774 | /**
775 | * Make an oEmbed call for the specified URL.
776 | *
777 | * @param {string} videoUrl The vimeo.com url for the video.
778 | * @param {Object} [params] Parameters to pass to oEmbed.
779 | * @param {HTMLElement} element The element.
780 | * @return {Promise}
781 | */
782 |
783 | function getOEmbedData(videoUrl) {
784 | var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
785 | var element = arguments.length > 2 ? arguments[2] : undefined;
786 | return new Promise(function (resolve, reject) {
787 | if (!isVimeoUrl(videoUrl)) {
788 | throw new TypeError("\u201C".concat(videoUrl, "\u201D is not a vimeo.com url."));
789 | }
790 |
791 | var url = "https://vimeo.com/api/oembed.json?url=".concat(encodeURIComponent(videoUrl));
792 |
793 | for (var param in params) {
794 | if (params.hasOwnProperty(param)) {
795 | url += "&".concat(param, "=").concat(encodeURIComponent(params[param]));
796 | }
797 | }
798 |
799 | var xhr = 'XDomainRequest' in window ? new XDomainRequest() : new XMLHttpRequest();
800 | xhr.open('GET', url, true);
801 |
802 | xhr.onload = function () {
803 | if (xhr.status === 404) {
804 | reject(new Error("\u201C".concat(videoUrl, "\u201D was not found.")));
805 | return;
806 | }
807 |
808 | if (xhr.status === 403) {
809 | reject(new Error("\u201C".concat(videoUrl, "\u201D is not embeddable.")));
810 | return;
811 | }
812 |
813 | try {
814 | var json = JSON.parse(xhr.responseText); // Check api response for 403 on oembed
815 |
816 | if (json.domain_status_code === 403) {
817 | // We still want to create the embed to give users visual feedback
818 | createEmbed(json, element);
819 | reject(new Error("\u201C".concat(videoUrl, "\u201D is not embeddable.")));
820 | return;
821 | }
822 |
823 | resolve(json);
824 | } catch (error) {
825 | reject(error);
826 | }
827 | };
828 |
829 | xhr.onerror = function () {
830 | var status = xhr.status ? " (".concat(xhr.status, ")") : '';
831 | reject(new Error("There was an error fetching the embed code from Vimeo".concat(status, ".")));
832 | };
833 |
834 | xhr.send();
835 | });
836 | }
837 | /**
838 | * Initialize all embeds within a specific element
839 | *
840 | * @param {HTMLElement} [parent=document] The parent element.
841 | * @return {void}
842 | */
843 |
844 | function initializeEmbeds() {
845 | var parent = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : document;
846 | var elements = [].slice.call(parent.querySelectorAll('[data-vimeo-id], [data-vimeo-url]'));
847 |
848 | var handleError = function handleError(error) {
849 | if ('console' in window && console.error) {
850 | console.error("There was an error creating an embed: ".concat(error));
851 | }
852 | };
853 |
854 | elements.forEach(function (element) {
855 | try {
856 | // Skip any that have data-vimeo-defer
857 | if (element.getAttribute('data-vimeo-defer') !== null) {
858 | return;
859 | }
860 |
861 | var params = getOEmbedParameters(element);
862 | var url = getVimeoUrl(params);
863 | getOEmbedData(url, params, element).then(function (data) {
864 | return createEmbed(data, element);
865 | }).catch(handleError);
866 | } catch (error) {
867 | handleError(error);
868 | }
869 | });
870 | }
871 | /**
872 | * Resize embeds when messaged by the player.
873 | *
874 | * @param {HTMLElement} [parent=document] The parent element.
875 | * @return {void}
876 | */
877 |
878 | function resizeEmbeds() {
879 | var parent = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : document;
880 |
881 | // Prevent execution if users include the player.js script multiple times.
882 | if (window.VimeoPlayerResizeEmbeds_) {
883 | return;
884 | }
885 |
886 | window.VimeoPlayerResizeEmbeds_ = true;
887 |
888 | var onMessage = function onMessage(event) {
889 | if (!isVimeoUrl(event.origin)) {
890 | return;
891 | } // 'spacechange' is fired only on embeds with cards
892 |
893 |
894 | if (!event.data || event.data.event !== 'spacechange') {
895 | return;
896 | }
897 |
898 | var iframes = parent.querySelectorAll('iframe');
899 |
900 | for (var i = 0; i < iframes.length; i++) {
901 | if (iframes[i].contentWindow !== event.source) {
902 | continue;
903 | } // Change padding-bottom of the enclosing div to accommodate
904 | // card carousel without distorting aspect ratio
905 |
906 |
907 | var space = iframes[i].parentElement;
908 | space.style.paddingBottom = "".concat(event.data.data[0].bottom, "px");
909 | break;
910 | }
911 | };
912 |
913 | if (window.addEventListener) {
914 | window.addEventListener('message', onMessage, false);
915 | } else if (window.attachEvent) {
916 | window.attachEvent('onmessage', onMessage);
917 | }
918 | }
919 |
920 | /**
921 | * @module lib/postmessage
922 | */
923 | /**
924 | * Parse a message received from postMessage.
925 | *
926 | * @param {*} data The data received from postMessage.
927 | * @return {object}
928 | */
929 |
930 | function parseMessageData(data) {
931 | if (typeof data === 'string') {
932 | try {
933 | data = JSON.parse(data);
934 | } catch (error) {
935 | // If the message cannot be parsed, throw the error as a warning
936 | console.warn(error);
937 | return {};
938 | }
939 | }
940 |
941 | return data;
942 | }
943 | /**
944 | * Post a message to the specified target.
945 | *
946 | * @param {Player} player The player object to use.
947 | * @param {string} method The API method to call.
948 | * @param {object} params The parameters to send to the player.
949 | * @return {void}
950 | */
951 |
952 | function postMessage(player, method, params) {
953 | if (!player.element.contentWindow || !player.element.contentWindow.postMessage) {
954 | return;
955 | }
956 |
957 | var message = {
958 | method: method
959 | };
960 |
961 | if (params !== undefined) {
962 | message.value = params;
963 | } // IE 8 and 9 do not support passing messages, so stringify them
964 |
965 |
966 | var ieVersion = parseFloat(navigator.userAgent.toLowerCase().replace(/^.*msie (\d+).*$/, '$1'));
967 |
968 | if (ieVersion >= 8 && ieVersion < 10) {
969 | message = JSON.stringify(message);
970 | }
971 |
972 | player.element.contentWindow.postMessage(message, player.origin);
973 | }
974 | /**
975 | * Parse the data received from a message event.
976 | *
977 | * @param {Player} player The player that received the message.
978 | * @param {(Object|string)} data The message data. Strings will be parsed into JSON.
979 | * @return {void}
980 | */
981 |
982 | function processData(player, data) {
983 | data = parseMessageData(data);
984 | var callbacks = [];
985 | var param;
986 |
987 | if (data.event) {
988 | if (data.event === 'error') {
989 | var promises = getCallbacks(player, data.data.method);
990 | promises.forEach(function (promise) {
991 | var error = new Error(data.data.message);
992 | error.name = data.data.name;
993 | promise.reject(error);
994 | removeCallback(player, data.data.method, promise);
995 | });
996 | }
997 |
998 | callbacks = getCallbacks(player, "event:".concat(data.event));
999 | param = data.data;
1000 | } else if (data.method) {
1001 | var callback = shiftCallbacks(player, data.method);
1002 |
1003 | if (callback) {
1004 | callbacks.push(callback);
1005 | param = data.value;
1006 | }
1007 | }
1008 |
1009 | callbacks.forEach(function (callback) {
1010 | try {
1011 | if (typeof callback === 'function') {
1012 | callback.call(player, param);
1013 | return;
1014 | }
1015 |
1016 | callback.resolve(param);
1017 | } catch (e) {// empty
1018 | }
1019 | });
1020 | }
1021 |
1022 | var playerMap = new WeakMap();
1023 | var readyMap = new WeakMap();
1024 |
1025 | var Player =
1026 | /*#__PURE__*/
1027 | function () {
1028 | /**
1029 | * Create a Player.
1030 | *
1031 | * @param {(HTMLIFrameElement|HTMLElement|string|jQuery)} element A reference to the Vimeo
1032 | * player iframe, and id, or a jQuery object.
1033 | * @param {object} [options] oEmbed parameters to use when creating an embed in the element.
1034 | * @return {Player}
1035 | */
1036 | function Player(element) {
1037 | var _this = this;
1038 |
1039 | var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
1040 |
1041 | _classCallCheck(this, Player);
1042 |
1043 | /* global jQuery */
1044 | if (window.jQuery && element instanceof jQuery) {
1045 | if (element.length > 1 && window.console && console.warn) {
1046 | console.warn('A jQuery object with multiple elements was passed, using the first element.');
1047 | }
1048 |
1049 | element = element[0];
1050 | } // Find an element by ID
1051 |
1052 |
1053 | if (typeof document !== 'undefined' && typeof element === 'string') {
1054 | element = document.getElementById(element);
1055 | } // Not an element!
1056 |
1057 |
1058 | if (!isDomElement(element)) {
1059 | throw new TypeError('You must pass either a valid element or a valid id.');
1060 | }
1061 |
1062 | var win = element.ownerDocument.defaultView; // Already initialized an embed in this div, so grab the iframe
1063 |
1064 | if (element.nodeName !== 'IFRAME') {
1065 | var iframe = element.querySelector('iframe');
1066 |
1067 | if (iframe) {
1068 | element = iframe;
1069 | }
1070 | } // iframe url is not a Vimeo url
1071 |
1072 |
1073 | if (element.nodeName === 'IFRAME' && !isVimeoUrl(element.getAttribute('src') || '')) {
1074 | throw new Error('The player element passed isn’t a Vimeo embed.');
1075 | } // If there is already a player object in the map, return that
1076 |
1077 |
1078 | if (playerMap.has(element)) {
1079 | return playerMap.get(element);
1080 | }
1081 |
1082 | this.element = element;
1083 | this.origin = '*';
1084 | var readyPromise = new npo_src(function (resolve, reject) {
1085 | var onMessage = function onMessage(event) {
1086 | if (!isVimeoUrl(event.origin) || _this.element.contentWindow !== event.source) {
1087 | return;
1088 | }
1089 |
1090 | if (_this.origin === '*') {
1091 | _this.origin = event.origin;
1092 | }
1093 |
1094 | var data = parseMessageData(event.data);
1095 | var isError = data && data.event === 'error';
1096 | var isReadyError = isError && data.data && data.data.method === 'ready';
1097 |
1098 | if (isReadyError) {
1099 | var error = new Error(data.data.message);
1100 | error.name = data.data.name;
1101 | reject(error);
1102 | return;
1103 | }
1104 |
1105 | var isReadyEvent = data && data.event === 'ready';
1106 | var isPingResponse = data && data.method === 'ping';
1107 |
1108 | if (isReadyEvent || isPingResponse) {
1109 | _this.element.setAttribute('data-ready', 'true');
1110 |
1111 | resolve();
1112 | return;
1113 | }
1114 |
1115 | processData(_this, data);
1116 | };
1117 |
1118 | if (win.addEventListener) {
1119 | win.addEventListener('message', onMessage, false);
1120 | } else if (win.attachEvent) {
1121 | win.attachEvent('onmessage', onMessage);
1122 | }
1123 |
1124 | if (_this.element.nodeName !== 'IFRAME') {
1125 | var params = getOEmbedParameters(element, options);
1126 | var url = getVimeoUrl(params);
1127 | getOEmbedData(url, params, element).then(function (data) {
1128 | var iframe = createEmbed(data, element); // Overwrite element with the new iframe,
1129 | // but store reference to the original element
1130 |
1131 | _this.element = iframe;
1132 | _this._originalElement = element;
1133 | swapCallbacks(element, iframe);
1134 | playerMap.set(_this.element, _this);
1135 | return data;
1136 | }).catch(reject);
1137 | }
1138 | }); // Store a copy of this Player in the map
1139 |
1140 | readyMap.set(this, readyPromise);
1141 | playerMap.set(this.element, this); // Send a ping to the iframe so the ready promise will be resolved if
1142 | // the player is already ready.
1143 |
1144 | if (this.element.nodeName === 'IFRAME') {
1145 | postMessage(this, 'ping');
1146 | }
1147 |
1148 | return this;
1149 | }
1150 | /**
1151 | * Get a promise for a method.
1152 | *
1153 | * @param {string} name The API method to call.
1154 | * @param {Object} [args={}] Arguments to send via postMessage.
1155 | * @return {Promise}
1156 | */
1157 |
1158 |
1159 | _createClass(Player, [{
1160 | key: "callMethod",
1161 | value: function callMethod(name) {
1162 | var _this2 = this;
1163 |
1164 | var args = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
1165 | return new npo_src(function (resolve, reject) {
1166 | // We are storing the resolve/reject handlers to call later, so we
1167 | // can’t return here.
1168 | // eslint-disable-next-line promise/always-return
1169 | return _this2.ready().then(function () {
1170 | storeCallback(_this2, name, {
1171 | resolve: resolve,
1172 | reject: reject
1173 | });
1174 | postMessage(_this2, name, args);
1175 | }).catch(reject);
1176 | });
1177 | }
1178 | /**
1179 | * Get a promise for the value of a player property.
1180 | *
1181 | * @param {string} name The property name
1182 | * @return {Promise}
1183 | */
1184 |
1185 | }, {
1186 | key: "get",
1187 | value: function get(name) {
1188 | var _this3 = this;
1189 |
1190 | return new npo_src(function (resolve, reject) {
1191 | name = getMethodName(name, 'get'); // We are storing the resolve/reject handlers to call later, so we
1192 | // can’t return here.
1193 | // eslint-disable-next-line promise/always-return
1194 |
1195 | return _this3.ready().then(function () {
1196 | storeCallback(_this3, name, {
1197 | resolve: resolve,
1198 | reject: reject
1199 | });
1200 | postMessage(_this3, name);
1201 | }).catch(reject);
1202 | });
1203 | }
1204 | /**
1205 | * Get a promise for setting the value of a player property.
1206 | *
1207 | * @param {string} name The API method to call.
1208 | * @param {mixed} value The value to set.
1209 | * @return {Promise}
1210 | */
1211 |
1212 | }, {
1213 | key: "set",
1214 | value: function set(name, value) {
1215 | var _this4 = this;
1216 |
1217 | return new npo_src(function (resolve, reject) {
1218 | name = getMethodName(name, 'set');
1219 |
1220 | if (value === undefined || value === null) {
1221 | throw new TypeError('There must be a value to set.');
1222 | } // We are storing the resolve/reject handlers to call later, so we
1223 | // can’t return here.
1224 | // eslint-disable-next-line promise/always-return
1225 |
1226 |
1227 | return _this4.ready().then(function () {
1228 | storeCallback(_this4, name, {
1229 | resolve: resolve,
1230 | reject: reject
1231 | });
1232 | postMessage(_this4, name, value);
1233 | }).catch(reject);
1234 | });
1235 | }
1236 | /**
1237 | * Add an event listener for the specified event. Will call the
1238 | * callback with a single parameter, `data`, that contains the data for
1239 | * that event.
1240 | *
1241 | * @param {string} eventName The name of the event.
1242 | * @param {function(*)} callback The function to call when the event fires.
1243 | * @return {void}
1244 | */
1245 |
1246 | }, {
1247 | key: "on",
1248 | value: function on(eventName, callback) {
1249 | if (!eventName) {
1250 | throw new TypeError('You must pass an event name.');
1251 | }
1252 |
1253 | if (!callback) {
1254 | throw new TypeError('You must pass a callback function.');
1255 | }
1256 |
1257 | if (typeof callback !== 'function') {
1258 | throw new TypeError('The callback must be a function.');
1259 | }
1260 |
1261 | var callbacks = getCallbacks(this, "event:".concat(eventName));
1262 |
1263 | if (callbacks.length === 0) {
1264 | this.callMethod('addEventListener', eventName).catch(function () {// Ignore the error. There will be an error event fired that
1265 | // will trigger the error callback if they are listening.
1266 | });
1267 | }
1268 |
1269 | storeCallback(this, "event:".concat(eventName), callback);
1270 | }
1271 | /**
1272 | * Remove an event listener for the specified event. Will remove all
1273 | * listeners for that event if a `callback` isn’t passed, or only that
1274 | * specific callback if it is passed.
1275 | *
1276 | * @param {string} eventName The name of the event.
1277 | * @param {function} [callback] The specific callback to remove.
1278 | * @return {void}
1279 | */
1280 |
1281 | }, {
1282 | key: "off",
1283 | value: function off(eventName, callback) {
1284 | if (!eventName) {
1285 | throw new TypeError('You must pass an event name.');
1286 | }
1287 |
1288 | if (callback && typeof callback !== 'function') {
1289 | throw new TypeError('The callback must be a function.');
1290 | }
1291 |
1292 | var lastCallback = removeCallback(this, "event:".concat(eventName), callback); // If there are no callbacks left, remove the listener
1293 |
1294 | if (lastCallback) {
1295 | this.callMethod('removeEventListener', eventName).catch(function (e) {// Ignore the error. There will be an error event fired that
1296 | // will trigger the error callback if they are listening.
1297 | });
1298 | }
1299 | }
1300 | /**
1301 | * A promise to load a new video.
1302 | *
1303 | * @promise LoadVideoPromise
1304 | * @fulfill {number} The video with this id successfully loaded.
1305 | * @reject {TypeError} The id was not a number.
1306 | */
1307 |
1308 | /**
1309 | * Load a new video into this embed. The promise will be resolved if
1310 | * the video is successfully loaded, or it will be rejected if it could
1311 | * not be loaded.
1312 | *
1313 | * @param {number|object} options The id of the video or an object with embed options.
1314 | * @return {LoadVideoPromise}
1315 | */
1316 |
1317 | }, {
1318 | key: "loadVideo",
1319 | value: function loadVideo(options) {
1320 | return this.callMethod('loadVideo', options);
1321 | }
1322 | /**
1323 | * A promise to perform an action when the Player is ready.
1324 | *
1325 | * @todo document errors
1326 | * @promise LoadVideoPromise
1327 | * @fulfill {void}
1328 | */
1329 |
1330 | /**
1331 | * Trigger a function when the player iframe has initialized. You do not
1332 | * need to wait for `ready` to trigger to begin adding event listeners
1333 | * or calling other methods.
1334 | *
1335 | * @return {ReadyPromise}
1336 | */
1337 |
1338 | }, {
1339 | key: "ready",
1340 | value: function ready() {
1341 | var readyPromise = readyMap.get(this) || new npo_src(function (resolve, reject) {
1342 | reject(new Error('Unknown player. Probably unloaded.'));
1343 | });
1344 | return npo_src.resolve(readyPromise);
1345 | }
1346 | /**
1347 | * A promise to add a cue point to the player.
1348 | *
1349 | * @promise AddCuePointPromise
1350 | * @fulfill {string} The id of the cue point to use for removeCuePoint.
1351 | * @reject {RangeError} the time was less than 0 or greater than the
1352 | * video’s duration.
1353 | * @reject {UnsupportedError} Cue points are not supported with the current
1354 | * player or browser.
1355 | */
1356 |
1357 | /**
1358 | * Add a cue point to the player.
1359 | *
1360 | * @param {number} time The time for the cue point.
1361 | * @param {object} [data] Arbitrary data to be returned with the cue point.
1362 | * @return {AddCuePointPromise}
1363 | */
1364 |
1365 | }, {
1366 | key: "addCuePoint",
1367 | value: function addCuePoint(time) {
1368 | var data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
1369 | return this.callMethod('addCuePoint', {
1370 | time: time,
1371 | data: data
1372 | });
1373 | }
1374 | /**
1375 | * A promise to remove a cue point from the player.
1376 | *
1377 | * @promise AddCuePointPromise
1378 | * @fulfill {string} The id of the cue point that was removed.
1379 | * @reject {InvalidCuePoint} The cue point with the specified id was not
1380 | * found.
1381 | * @reject {UnsupportedError} Cue points are not supported with the current
1382 | * player or browser.
1383 | */
1384 |
1385 | /**
1386 | * Remove a cue point from the video.
1387 | *
1388 | * @param {string} id The id of the cue point to remove.
1389 | * @return {RemoveCuePointPromise}
1390 | */
1391 |
1392 | }, {
1393 | key: "removeCuePoint",
1394 | value: function removeCuePoint(id) {
1395 | return this.callMethod('removeCuePoint', id);
1396 | }
1397 | /**
1398 | * A representation of a text track on a video.
1399 | *
1400 | * @typedef {Object} VimeoTextTrack
1401 | * @property {string} language The ISO language code.
1402 | * @property {string} kind The kind of track it is (captions or subtitles).
1403 | * @property {string} label The human‐readable label for the track.
1404 | */
1405 |
1406 | /**
1407 | * A promise to enable a text track.
1408 | *
1409 | * @promise EnableTextTrackPromise
1410 | * @fulfill {VimeoTextTrack} The text track that was enabled.
1411 | * @reject {InvalidTrackLanguageError} No track was available with the
1412 | * specified language.
1413 | * @reject {InvalidTrackError} No track was available with the specified
1414 | * language and kind.
1415 | */
1416 |
1417 | /**
1418 | * Enable the text track with the specified language, and optionally the
1419 | * specified kind (captions or subtitles).
1420 | *
1421 | * When set via the API, the track language will not change the viewer’s
1422 | * stored preference.
1423 | *
1424 | * @param {string} language The two‐letter language code.
1425 | * @param {string} [kind] The kind of track to enable (captions or subtitles).
1426 | * @return {EnableTextTrackPromise}
1427 | */
1428 |
1429 | }, {
1430 | key: "enableTextTrack",
1431 | value: function enableTextTrack(language, kind) {
1432 | if (!language) {
1433 | throw new TypeError('You must pass a language.');
1434 | }
1435 |
1436 | return this.callMethod('enableTextTrack', {
1437 | language: language,
1438 | kind: kind
1439 | });
1440 | }
1441 | /**
1442 | * A promise to disable the active text track.
1443 | *
1444 | * @promise DisableTextTrackPromise
1445 | * @fulfill {void} The track was disabled.
1446 | */
1447 |
1448 | /**
1449 | * Disable the currently-active text track.
1450 | *
1451 | * @return {DisableTextTrackPromise}
1452 | */
1453 |
1454 | }, {
1455 | key: "disableTextTrack",
1456 | value: function disableTextTrack() {
1457 | return this.callMethod('disableTextTrack');
1458 | }
1459 | /**
1460 | * A promise to pause the video.
1461 | *
1462 | * @promise PausePromise
1463 | * @fulfill {void} The video was paused.
1464 | */
1465 |
1466 | /**
1467 | * Pause the video if it’s playing.
1468 | *
1469 | * @return {PausePromise}
1470 | */
1471 |
1472 | }, {
1473 | key: "pause",
1474 | value: function pause() {
1475 | return this.callMethod('pause');
1476 | }
1477 | /**
1478 | * A promise to play the video.
1479 | *
1480 | * @promise PlayPromise
1481 | * @fulfill {void} The video was played.
1482 | */
1483 |
1484 | /**
1485 | * Play the video if it’s paused. **Note:** on iOS and some other
1486 | * mobile devices, you cannot programmatically trigger play. Once the
1487 | * viewer has tapped on the play button in the player, however, you
1488 | * will be able to use this function.
1489 | *
1490 | * @return {PlayPromise}
1491 | */
1492 |
1493 | }, {
1494 | key: "play",
1495 | value: function play() {
1496 | return this.callMethod('play');
1497 | }
1498 | /**
1499 | * A promise to unload the video.
1500 | *
1501 | * @promise UnloadPromise
1502 | * @fulfill {void} The video was unloaded.
1503 | */
1504 |
1505 | /**
1506 | * Return the player to its initial state.
1507 | *
1508 | * @return {UnloadPromise}
1509 | */
1510 |
1511 | }, {
1512 | key: "unload",
1513 | value: function unload() {
1514 | return this.callMethod('unload');
1515 | }
1516 | /**
1517 | * Cleanup the player and remove it from the DOM
1518 | *
1519 | * It won't be usable and a new one should be constructed
1520 | * in order to do any operations.
1521 | *
1522 | * @return {Promise}
1523 | */
1524 |
1525 | }, {
1526 | key: "destroy",
1527 | value: function destroy() {
1528 | var _this5 = this;
1529 |
1530 | return new npo_src(function (resolve) {
1531 | readyMap.delete(_this5);
1532 | playerMap.delete(_this5.element);
1533 |
1534 | if (_this5._originalElement) {
1535 | playerMap.delete(_this5._originalElement);
1536 |
1537 | _this5._originalElement.removeAttribute('data-vimeo-initialized');
1538 | }
1539 |
1540 | if (_this5.element && _this5.element.nodeName === 'IFRAME' && _this5.element.parentNode) {
1541 | _this5.element.parentNode.removeChild(_this5.element);
1542 | }
1543 |
1544 | resolve();
1545 | });
1546 | }
1547 | /**
1548 | * A promise to get the autopause behavior of the video.
1549 | *
1550 | * @promise GetAutopausePromise
1551 | * @fulfill {boolean} Whether autopause is turned on or off.
1552 | * @reject {UnsupportedError} Autopause is not supported with the current
1553 | * player or browser.
1554 | */
1555 |
1556 | /**
1557 | * Get the autopause behavior for this player.
1558 | *
1559 | * @return {GetAutopausePromise}
1560 | */
1561 |
1562 | }, {
1563 | key: "getAutopause",
1564 | value: function getAutopause() {
1565 | return this.get('autopause');
1566 | }
1567 | /**
1568 | * A promise to set the autopause behavior of the video.
1569 | *
1570 | * @promise SetAutopausePromise
1571 | * @fulfill {boolean} Whether autopause is turned on or off.
1572 | * @reject {UnsupportedError} Autopause is not supported with the current
1573 | * player or browser.
1574 | */
1575 |
1576 | /**
1577 | * Enable or disable the autopause behavior of this player.
1578 | *
1579 | * By default, when another video is played in the same browser, this
1580 | * player will automatically pause. Unless you have a specific reason
1581 | * for doing so, we recommend that you leave autopause set to the
1582 | * default (`true`).
1583 | *
1584 | * @param {boolean} autopause
1585 | * @return {SetAutopausePromise}
1586 | */
1587 |
1588 | }, {
1589 | key: "setAutopause",
1590 | value: function setAutopause(autopause) {
1591 | return this.set('autopause', autopause);
1592 | }
1593 | /**
1594 | * A promise to get the buffered property of the video.
1595 | *
1596 | * @promise GetBufferedPromise
1597 | * @fulfill {Array} Buffered Timeranges converted to an Array.
1598 | */
1599 |
1600 | /**
1601 | * Get the buffered property of the video.
1602 | *
1603 | * @return {GetBufferedPromise}
1604 | */
1605 |
1606 | }, {
1607 | key: "getBuffered",
1608 | value: function getBuffered() {
1609 | return this.get('buffered');
1610 | }
1611 | /**
1612 | * A promise to get the color of the player.
1613 | *
1614 | * @promise GetColorPromise
1615 | * @fulfill {string} The hex color of the player.
1616 | */
1617 |
1618 | /**
1619 | * Get the color for this player.
1620 | *
1621 | * @return {GetColorPromise}
1622 | */
1623 |
1624 | }, {
1625 | key: "getColor",
1626 | value: function getColor() {
1627 | return this.get('color');
1628 | }
1629 | /**
1630 | * A promise to set the color of the player.
1631 | *
1632 | * @promise SetColorPromise
1633 | * @fulfill {string} The color was successfully set.
1634 | * @reject {TypeError} The string was not a valid hex or rgb color.
1635 | * @reject {ContrastError} The color was set, but the contrast is
1636 | * outside of the acceptable range.
1637 | * @reject {EmbedSettingsError} The owner of the player has chosen to
1638 | * use a specific color.
1639 | */
1640 |
1641 | /**
1642 | * Set the color of this player to a hex or rgb string. Setting the
1643 | * color may fail if the owner of the video has set their embed
1644 | * preferences to force a specific color.
1645 | *
1646 | * @param {string} color The hex or rgb color string to set.
1647 | * @return {SetColorPromise}
1648 | */
1649 |
1650 | }, {
1651 | key: "setColor",
1652 | value: function setColor(color) {
1653 | return this.set('color', color);
1654 | }
1655 | /**
1656 | * A representation of a cue point.
1657 | *
1658 | * @typedef {Object} VimeoCuePoint
1659 | * @property {number} time The time of the cue point.
1660 | * @property {object} data The data passed when adding the cue point.
1661 | * @property {string} id The unique id for use with removeCuePoint.
1662 | */
1663 |
1664 | /**
1665 | * A promise to get the cue points of a video.
1666 | *
1667 | * @promise GetCuePointsPromise
1668 | * @fulfill {VimeoCuePoint[]} The cue points added to the video.
1669 | * @reject {UnsupportedError} Cue points are not supported with the current
1670 | * player or browser.
1671 | */
1672 |
1673 | /**
1674 | * Get an array of the cue points added to the video.
1675 | *
1676 | * @return {GetCuePointsPromise}
1677 | */
1678 |
1679 | }, {
1680 | key: "getCuePoints",
1681 | value: function getCuePoints() {
1682 | return this.get('cuePoints');
1683 | }
1684 | /**
1685 | * A promise to get the current time of the video.
1686 | *
1687 | * @promise GetCurrentTimePromise
1688 | * @fulfill {number} The current time in seconds.
1689 | */
1690 |
1691 | /**
1692 | * Get the current playback position in seconds.
1693 | *
1694 | * @return {GetCurrentTimePromise}
1695 | */
1696 |
1697 | }, {
1698 | key: "getCurrentTime",
1699 | value: function getCurrentTime() {
1700 | return this.get('currentTime');
1701 | }
1702 | /**
1703 | * A promise to set the current time of the video.
1704 | *
1705 | * @promise SetCurrentTimePromise
1706 | * @fulfill {number} The actual current time that was set.
1707 | * @reject {RangeError} the time was less than 0 or greater than the
1708 | * video’s duration.
1709 | */
1710 |
1711 | /**
1712 | * Set the current playback position in seconds. If the player was
1713 | * paused, it will remain paused. Likewise, if the player was playing,
1714 | * it will resume playing once the video has buffered.
1715 | *
1716 | * You can provide an accurate time and the player will attempt to seek
1717 | * to as close to that time as possible. The exact time will be the
1718 | * fulfilled value of the promise.
1719 | *
1720 | * @param {number} currentTime
1721 | * @return {SetCurrentTimePromise}
1722 | */
1723 |
1724 | }, {
1725 | key: "setCurrentTime",
1726 | value: function setCurrentTime(currentTime) {
1727 | return this.set('currentTime', currentTime);
1728 | }
1729 | /**
1730 | * A promise to get the duration of the video.
1731 | *
1732 | * @promise GetDurationPromise
1733 | * @fulfill {number} The duration in seconds.
1734 | */
1735 |
1736 | /**
1737 | * Get the duration of the video in seconds. It will be rounded to the
1738 | * nearest second before playback begins, and to the nearest thousandth
1739 | * of a second after playback begins.
1740 | *
1741 | * @return {GetDurationPromise}
1742 | */
1743 |
1744 | }, {
1745 | key: "getDuration",
1746 | value: function getDuration() {
1747 | return this.get('duration');
1748 | }
1749 | /**
1750 | * A promise to get the ended state of the video.
1751 | *
1752 | * @promise GetEndedPromise
1753 | * @fulfill {boolean} Whether or not the video has ended.
1754 | */
1755 |
1756 | /**
1757 | * Get the ended state of the video. The video has ended if
1758 | * `currentTime === duration`.
1759 | *
1760 | * @return {GetEndedPromise}
1761 | */
1762 |
1763 | }, {
1764 | key: "getEnded",
1765 | value: function getEnded() {
1766 | return this.get('ended');
1767 | }
1768 | /**
1769 | * A promise to get the loop state of the player.
1770 | *
1771 | * @promise GetLoopPromise
1772 | * @fulfill {boolean} Whether or not the player is set to loop.
1773 | */
1774 |
1775 | /**
1776 | * Get the loop state of the player.
1777 | *
1778 | * @return {GetLoopPromise}
1779 | */
1780 |
1781 | }, {
1782 | key: "getLoop",
1783 | value: function getLoop() {
1784 | return this.get('loop');
1785 | }
1786 | /**
1787 | * A promise to set the loop state of the player.
1788 | *
1789 | * @promise SetLoopPromise
1790 | * @fulfill {boolean} The loop state that was set.
1791 | */
1792 |
1793 | /**
1794 | * Set the loop state of the player. When set to `true`, the player
1795 | * will start over immediately once playback ends.
1796 | *
1797 | * @param {boolean} loop
1798 | * @return {SetLoopPromise}
1799 | */
1800 |
1801 | }, {
1802 | key: "setLoop",
1803 | value: function setLoop(loop) {
1804 | return this.set('loop', loop);
1805 | }
1806 | /**
1807 | * A promise to set the muted state of the player.
1808 | *
1809 | * @promise SetMutedPromise
1810 | * @fulfill {boolean} The muted state that was set.
1811 | */
1812 |
1813 | /**
1814 | * Set the muted state of the player. When set to `true`, the player
1815 | * volume will be muted.
1816 | *
1817 | * @param {boolean} muted
1818 | * @return {SetMutedPromise}
1819 | */
1820 |
1821 | }, {
1822 | key: "setMuted",
1823 | value: function setMuted(muted) {
1824 | return this.set('muted', muted);
1825 | }
1826 | /**
1827 | * A promise to get the muted state of the player.
1828 | *
1829 | * @promise GetMutedPromise
1830 | * @fulfill {boolean} Whether or not the player is muted.
1831 | */
1832 |
1833 | /**
1834 | * Get the muted state of the player.
1835 | *
1836 | * @return {GetMutedPromise}
1837 | */
1838 |
1839 | }, {
1840 | key: "getMuted",
1841 | value: function getMuted() {
1842 | return this.get('muted');
1843 | }
1844 | /**
1845 | * A promise to get the paused state of the player.
1846 | *
1847 | * @promise GetLoopPromise
1848 | * @fulfill {boolean} Whether or not the video is paused.
1849 | */
1850 |
1851 | /**
1852 | * Get the paused state of the player.
1853 | *
1854 | * @return {GetLoopPromise}
1855 | */
1856 |
1857 | }, {
1858 | key: "getPaused",
1859 | value: function getPaused() {
1860 | return this.get('paused');
1861 | }
1862 | /**
1863 | * A promise to get the playback rate of the player.
1864 | *
1865 | * @promise GetPlaybackRatePromise
1866 | * @fulfill {number} The playback rate of the player on a scale from 0.5 to 2.
1867 | */
1868 |
1869 | /**
1870 | * Get the playback rate of the player on a scale from `0.5` to `2`.
1871 | *
1872 | * @return {GetPlaybackRatePromise}
1873 | */
1874 |
1875 | }, {
1876 | key: "getPlaybackRate",
1877 | value: function getPlaybackRate() {
1878 | return this.get('playbackRate');
1879 | }
1880 | /**
1881 | * A promise to set the playbackrate of the player.
1882 | *
1883 | * @promise SetPlaybackRatePromise
1884 | * @fulfill {number} The playback rate was set.
1885 | * @reject {RangeError} The playback rate was less than 0.5 or greater than 2.
1886 | */
1887 |
1888 | /**
1889 | * Set the playback rate of the player on a scale from `0.5` to `2`. When set
1890 | * via the API, the playback rate will not be synchronized to other
1891 | * players or stored as the viewer's preference.
1892 | *
1893 | * @param {number} playbackRate
1894 | * @return {SetPlaybackRatePromise}
1895 | */
1896 |
1897 | }, {
1898 | key: "setPlaybackRate",
1899 | value: function setPlaybackRate(playbackRate) {
1900 | return this.set('playbackRate', playbackRate);
1901 | }
1902 | /**
1903 | * A promise to get the played property of the video.
1904 | *
1905 | * @promise GetPlayedPromise
1906 | * @fulfill {Array} Played Timeranges converted to an Array.
1907 | */
1908 |
1909 | /**
1910 | * Get the played property of the video.
1911 | *
1912 | * @return {GetPlayedPromise}
1913 | */
1914 |
1915 | }, {
1916 | key: "getPlayed",
1917 | value: function getPlayed() {
1918 | return this.get('played');
1919 | }
1920 | /**
1921 | * A promise to get the seekable property of the video.
1922 | *
1923 | * @promise GetSeekablePromise
1924 | * @fulfill {Array} Seekable Timeranges converted to an Array.
1925 | */
1926 |
1927 | /**
1928 | * Get the seekable property of the video.
1929 | *
1930 | * @return {GetSeekablePromise}
1931 | */
1932 |
1933 | }, {
1934 | key: "getSeekable",
1935 | value: function getSeekable() {
1936 | return this.get('seekable');
1937 | }
1938 | /**
1939 | * A promise to get the seeking property of the player.
1940 | *
1941 | * @promise GetSeekingPromise
1942 | * @fulfill {boolean} Whether or not the player is currently seeking.
1943 | */
1944 |
1945 | /**
1946 | * Get if the player is currently seeking.
1947 | *
1948 | * @return {GetSeekingPromise}
1949 | */
1950 |
1951 | }, {
1952 | key: "getSeeking",
1953 | value: function getSeeking() {
1954 | return this.get('seeking');
1955 | }
1956 | /**
1957 | * A promise to get the text tracks of a video.
1958 | *
1959 | * @promise GetTextTracksPromise
1960 | * @fulfill {VimeoTextTrack[]} The text tracks associated with the video.
1961 | */
1962 |
1963 | /**
1964 | * Get an array of the text tracks that exist for the video.
1965 | *
1966 | * @return {GetTextTracksPromise}
1967 | */
1968 |
1969 | }, {
1970 | key: "getTextTracks",
1971 | value: function getTextTracks() {
1972 | return this.get('textTracks');
1973 | }
1974 | /**
1975 | * A promise to get the embed code for the video.
1976 | *
1977 | * @promise GetVideoEmbedCodePromise
1978 | * @fulfill {string} The `