├── .editorconfig
├── .github
├── dependabot.yml
└── workflows
│ └── ci.yml
├── .gitignore
├── .npmignore
├── .nvmrc
├── .travis.yml
├── CHANGELOG.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── index.html
├── lang
├── de.json
├── en.json
├── fa.json
├── it.json
├── ja.json
├── lv.json
├── nl.json
├── ru.json
├── zh-CN.json
└── zh-TW.json
├── package-lock.json
├── package.json
├── scripts
├── karma.conf.js
├── postcss.config.js
└── rollup.config.js
├── src
├── plugin.css
└── plugin.js
└── test
└── plugin.test.js
/.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 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | - package-ecosystem: npm
4 | directory: "/"
5 | schedule:
6 | interval: daily
7 | commit-message:
8 | prefix: fix
9 | prefix-development: chore
10 | include: scope
11 |
--------------------------------------------------------------------------------
/.github/workflows/ci.yml:
--------------------------------------------------------------------------------
1 | name: ci
2 |
3 | on: [push, pull_request]
4 |
5 | jobs:
6 | should-skip:
7 | continue-on-error: true
8 | runs-on: ubuntu-latest
9 | # Map a step output to a job output
10 | outputs:
11 | should-skip-job: ${{steps.skip-check.outputs.should_skip}}
12 | steps:
13 | - id: skip-check
14 | uses: fkirc/skip-duplicate-actions@v2.1.0
15 | with:
16 | github_token: ${{github.token}}
17 |
18 | ci:
19 | needs: should-skip
20 | if: ${{needs.should-skip.outputs.should-skip-job != 'true' || github.ref == 'refs/heads/main'}}
21 | strategy:
22 | fail-fast: false
23 | matrix:
24 | os: [ubuntu-latest]
25 | env:
26 | BROWSER_STACK_USERNAME: ${{secrets.BROWSER_STACK_USERNAME}}
27 | BROWSER_STACK_ACCESS_KEY: ${{secrets.BROWSER_STACK_ACCESS_KEY}}
28 | runs-on: ${{matrix.os}}
29 | steps:
30 | - name: checkout code
31 | uses: actions/checkout@v2
32 |
33 | - name: Cache dependencies
34 | uses: actions/cache@v2
35 | with:
36 | path: |
37 | ~/.npm
38 | **/node_modules
39 | key: ${{runner.os}}-npm-${{hashFiles('**/package-lock.json')}}
40 | restore-keys: |
41 | ${{runner.os}}-npm-
42 | ${{runner.os}}-
43 |
44 | - name: read node version from .nvmrc
45 | run: echo ::set-output name=NVMRC::$(cat .nvmrc)
46 | shell: bash
47 | id: nvm
48 |
49 | - name: update apt cache on linux w/o browserstack
50 | run: sudo apt-get update
51 | if: ${{startsWith(matrix.os, 'ubuntu') && !env.BROWSER_STACK_USERNAME}}
52 |
53 | - name: install ffmpeg/pulseaudio for firefox on linux w/o browserstack
54 | run: sudo apt-get install ffmpeg pulseaudio
55 | if: ${{startsWith(matrix.os, 'ubuntu') && !env.BROWSER_STACK_USERNAME}}
56 |
57 | - name: start pulseaudio for firefox on linux w/o browserstack
58 | run: pulseaudio -D
59 | if: ${{startsWith(matrix.os, 'ubuntu') && !env.BROWSER_STACK_USERNAME}}
60 |
61 | - name: setup node
62 | uses: actions/setup-node@v1
63 | with:
64 | node-version: '${{steps.nvm.outputs.NVMRC}}'
65 |
66 | # turn off the default setup-node problem watchers...
67 | - run: echo "::remove-matcher owner=eslint-compact::"
68 | - run: echo "::remove-matcher owner=eslint-stylish::"
69 | - run: echo "::remove-matcher owner=tsc::"
70 |
71 | - name: npm install
72 | run: npm i --prefer-offline --no-audit
73 |
74 | - name: run npm test
75 | uses: GabrielBB/xvfb-action@v1
76 | with:
77 | run: npm run test
78 |
--------------------------------------------------------------------------------
/.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 | # Build-related directories
29 | dist/
30 | es/
31 | cjs/
32 | docs/api/
33 | test/dist/
34 | .eslintcache
35 | .yo-rc.json
36 |
--------------------------------------------------------------------------------
/.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 |
--------------------------------------------------------------------------------
/.nvmrc:
--------------------------------------------------------------------------------
1 | 14
2 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | dist: xenial
2 | language: node_js
3 | # node version is specified using the .nvmrc file
4 | cache: npm
5 | before_install:
6 | - npm install -g greenkeeper-lockfile@1
7 | before_script:
8 | - greenkeeper-lockfile-update
9 | after_script:
10 | - greenkeeper-lockfile-upload
11 | addons:
12 | firefox: latest
13 | chrome: stable
14 | services:
15 | - xvfb
16 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 |
2 | ## [4.0.2](https://github.com/mister-ben/videojs-seek-buttons/compare/v4.0.1...v4.0.2) (2023-01-17)
3 |
4 | ### Bug Fixes
5 |
6 | * **deps:** bump decode-uri-component from 0.2.0 to 0.2.2 (#106) ([7c78da1](https://github.com/mister-ben/videojs-seek-buttons/commit/7c78da1)), closes [#106](https://github.com/mister-ben/videojs-seek-buttons/issues/106)
7 | * **deps:** bump json5 from 2.1.3 to 2.2.3 (#111) ([d9d5e95](https://github.com/mister-ben/videojs-seek-buttons/commit/d9d5e95)), closes [#111](https://github.com/mister-ben/videojs-seek-buttons/issues/111)
8 |
9 | ### Chores
10 |
11 | * **deps-dev:** bump [@babel](https://github.com/babel)/cli from 7.19.3 to 7.20.7 (#110) ([0ad741d](https://github.com/mister-ben/videojs-seek-buttons/commit/0ad741d)), closes [#110](https://github.com/mister-ben/videojs-seek-buttons/issues/110)
12 | * **deps-dev:** bump [@babel](https://github.com/babel)/runtime from 7.20.1 to 7.20.6 (#104) ([753f849](https://github.com/mister-ben/videojs-seek-buttons/commit/753f849)), closes [#104](https://github.com/mister-ben/videojs-seek-buttons/issues/104)
13 | * **deps-dev:** bump [@babel](https://github.com/babel)/runtime from 7.20.6 to 7.20.7 (#109) ([7f81b6d](https://github.com/mister-ben/videojs-seek-buttons/commit/7f81b6d)), closes [#109](https://github.com/mister-ben/videojs-seek-buttons/issues/109)
14 | * **deps-dev:** bump postcss from 8.4.19 to 8.4.20 (#107) ([5d91486](https://github.com/mister-ben/videojs-seek-buttons/commit/5d91486)), closes [#107](https://github.com/mister-ben/videojs-seek-buttons/issues/107)
15 | * **deps-dev:** bump postcss from 8.4.20 to 8.4.21 (#114) ([aa9370b](https://github.com/mister-ben/videojs-seek-buttons/commit/aa9370b)), closes [#114](https://github.com/mister-ben/videojs-seek-buttons/issues/114)
16 | * **deps-dev:** bump sinon from 14.0.2 to 15.0.0 (#105) ([6d57ed0](https://github.com/mister-ben/videojs-seek-buttons/commit/6d57ed0)), closes [#105](https://github.com/mister-ben/videojs-seek-buttons/issues/105)
17 | * **deps-dev:** bump sinon from 15.0.0 to 15.0.1 (#108) ([83ebc32](https://github.com/mister-ben/videojs-seek-buttons/commit/83ebc32)), closes [#108](https://github.com/mister-ben/videojs-seek-buttons/issues/108)
18 | * **deps-dev:** bump video.js from 8.0.0 to 8.0.1 (#102) ([f89a7fc](https://github.com/mister-ben/videojs-seek-buttons/commit/f89a7fc)), closes [#102](https://github.com/mister-ben/videojs-seek-buttons/issues/102)
19 | * **deps-dev:** bump video.js from 8.0.1 to 8.0.2 (#103) ([379dc99](https://github.com/mister-ben/videojs-seek-buttons/commit/379dc99)), closes [#103](https://github.com/mister-ben/videojs-seek-buttons/issues/103)
20 | * **deps-dev:** bump video.js from 8.0.2 to 8.0.3 (#112) ([6401398](https://github.com/mister-ben/videojs-seek-buttons/commit/6401398)), closes [#112](https://github.com/mister-ben/videojs-seek-buttons/issues/112)
21 |
22 |
23 | ## [4.0.1](https://github.com/mister-ben/videojs-seek-buttons/compare/v4.0.0...v4.0.1) (2022-11-23)
24 |
25 | ### Documentation
26 |
27 | * Note version support in readme ([9778b38](https://github.com/mister-ben/videojs-seek-buttons/commit/9778b38))
28 |
29 |
30 | # [4.0.0](https://github.com/mister-ben/videojs-seek-buttons/compare/v4.0.0-1...v4.0.0) (2022-11-23)
31 |
32 | ### Bug Fixes
33 |
34 | * **deps:** bump engine.io from 6.2.0 to 6.2.1 (#98) ([934f2a1](https://github.com/mister-ben/videojs-seek-buttons/commit/934f2a1)), closes [#98](https://github.com/mister-ben/videojs-seek-buttons/issues/98)
35 |
36 | ### Chores
37 |
38 | * **deps-dev:** bump [@babel](https://github.com/babel)/runtime from 7.19.4 to 7.20.1 (#99) ([232e2d1](https://github.com/mister-ben/videojs-seek-buttons/commit/232e2d1)), closes [#99](https://github.com/mister-ben/videojs-seek-buttons/issues/99)
39 | * **deps-dev:** bump postcss from 8.4.18 to 8.4.19 (#100) ([9d68302](https://github.com/mister-ben/videojs-seek-buttons/commit/9d68302)), closes [#100](https://github.com/mister-ben/videojs-seek-buttons/issues/100)
40 | * **deps-dev:** bump sinon from 14.0.1 to 14.0.2 (#101) ([1af4bd8](https://github.com/mister-ben/videojs-seek-buttons/commit/1af4bd8)), closes [#101](https://github.com/mister-ben/videojs-seek-buttons/issues/101)
41 | * update dep to release version of vjs 8 ([4398518](https://github.com/mister-ben/videojs-seek-buttons/commit/4398518))
42 |
43 |
44 | # [4.0.0-1](https://github.com/mister-ben/videojs-seek-buttons/compare/v3.0.1...v4.0.0-1) (2022-11-21)
45 |
46 | ### Features
47 |
48 | * Video.js 8 support (#97) ([597fe02](https://github.com/mister-ben/videojs-seek-buttons/commit/597fe02)), closes [#97](https://github.com/mister-ben/videojs-seek-buttons/issues/97) [#90](https://github.com/mister-ben/videojs-seek-buttons/issues/90) [#96](https://github.com/mister-ben/videojs-seek-buttons/issues/96)
49 |
50 | ### Chores
51 |
52 | * **deps-dev:** bump [@babel](https://github.com/babel)/cli from 7.13.16 to 7.19.3 (#84) ([834d35f](https://github.com/mister-ben/videojs-seek-buttons/commit/834d35f)), closes [#84](https://github.com/mister-ben/videojs-seek-buttons/issues/84)
53 | * **deps-dev:** bump [@babel](https://github.com/babel)/runtime from 7.14.0 to 7.19.4 (#87) ([48c856d](https://github.com/mister-ben/videojs-seek-buttons/commit/48c856d)), closes [#87](https://github.com/mister-ben/videojs-seek-buttons/issues/87)
54 | * **deps-dev:** bump [@babel](https://github.com/babel)/runtime from 7.19.4 to 7.20.1 (#92) ([191899b](https://github.com/mister-ben/videojs-seek-buttons/commit/191899b)), closes [#92](https://github.com/mister-ben/videojs-seek-buttons/issues/92)
55 | * **deps-dev:** bump jsdoc from 3.6.11 to 4.0.0 (#93) ([1c48f93](https://github.com/mister-ben/videojs-seek-buttons/commit/1c48f93)), closes [#93](https://github.com/mister-ben/videojs-seek-buttons/issues/93)
56 | * **deps-dev:** bump karma from 6.3.16 to 6.4.1 (#88) ([930fbd4](https://github.com/mister-ben/videojs-seek-buttons/commit/930fbd4)), closes [#88](https://github.com/mister-ben/videojs-seek-buttons/issues/88)
57 | * **deps-dev:** bump postcss from 8.2.13 to 8.4.18 (#89) ([614ca7e](https://github.com/mister-ben/videojs-seek-buttons/commit/614ca7e)), closes [#89](https://github.com/mister-ben/videojs-seek-buttons/issues/89)
58 | * **deps-dev:** bump postcss from 8.4.18 to 8.4.19 (#95) ([12c496f](https://github.com/mister-ben/videojs-seek-buttons/commit/12c496f)), closes [#95](https://github.com/mister-ben/videojs-seek-buttons/issues/95)
59 | * **deps-dev:** bump rollup from 2.46.0 to 2.79.1 (#83) ([23ef14d](https://github.com/mister-ben/videojs-seek-buttons/commit/23ef14d)), closes [#83](https://github.com/mister-ben/videojs-seek-buttons/issues/83)
60 | * **deps-dev:** bump sinon from 14.0.1 to 14.0.2 (#94) ([2562054](https://github.com/mister-ben/videojs-seek-buttons/commit/2562054)), closes [#94](https://github.com/mister-ben/videojs-seek-buttons/issues/94)
61 | * **deps-dev:** bump sinon from 9.2.4 to 14.0.1 (#86) ([f2fa7b8](https://github.com/mister-ben/videojs-seek-buttons/commit/f2fa7b8)), closes [#86](https://github.com/mister-ben/videojs-seek-buttons/issues/86)
62 | * **deps-dev:** bump videojs-generate-karma-config from 8.0.0 to 8.0.1 (#85) ([2458e4e](https://github.com/mister-ben/videojs-seek-buttons/commit/2458e4e)), closes [#85](https://github.com/mister-ben/videojs-seek-buttons/issues/85)
63 |
64 |
65 | ## [3.0.1](https://github.com/mister-ben/videojs-seek-buttons/compare/v3.0.0...v3.0.1) (2022-10-18)
66 |
67 | ### Chores
68 |
69 | * Use conventional commit prefixes with dependabot (#82) ([d8da86f](https://github.com/mister-ben/videojs-seek-buttons/commit/d8da86f)), closes [#82](https://github.com/mister-ben/videojs-seek-buttons/issues/82)
70 |
71 |
72 | # [3.0.0](https://github.com/mister-ben/videojs-seek-buttons/compare/v2.2.1...v3.0.0) (2022-09-19)
73 |
74 | ### Chores
75 |
76 | * cleanup comments ([3111020](https://github.com/mister-ben/videojs-seek-buttons/commit/3111020))
77 | * Move video.js to peerDependencies (#74) ([870408c](https://github.com/mister-ben/videojs-seek-buttons/commit/870408c)), closes [#74](https://github.com/mister-ben/videojs-seek-buttons/issues/74)
78 | * vjs verify update ([7bc9765](https://github.com/mister-ben/videojs-seek-buttons/commit/7bc9765))
79 |
80 | ### Documentation
81 |
82 | * Clarify peerDependency in Readme ([a4a118f](https://github.com/mister-ben/videojs-seek-buttons/commit/a4a118f))
83 |
84 |
85 | ### BREAKING CHANGES
86 |
87 | * video.js is no longer a dependency but a peer dependency.
88 | This should alleviate issues with requiring/importing the right version,
89 | but if video.js wasn't explicitly installed before it now needs to be.
90 | * es and cjs script paths change to match current video.js
91 | plugin standards.
92 |
93 |
94 | ## [2.2.1](https://github.com/mister-ben/videojs-seek-buttons/compare/v2.2.0...v2.2.1) (2022-04-23)
95 |
96 | ### Bug Fixes
97 |
98 | * don't try to seek past start or end (#68) ([e349018](https://github.com/mister-ben/videojs-seek-buttons/commit/e349018)), closes [#68](https://github.com/mister-ben/videojs-seek-buttons/issues/68) [#69](https://github.com/mister-ben/videojs-seek-buttons/issues/69)
99 |
100 | ### Chores
101 |
102 | * Remove erroneous sass comment ([5efc6fd](https://github.com/mister-ben/videojs-seek-buttons/commit/5efc6fd))
103 |
104 |
105 | # [2.2.0](https://github.com/mister-ben/videojs-seek-buttons/compare/v2.0.0...v2.2.0) (2021-10-06)
106 |
107 | ### Features
108 |
109 | * Add Latvian (#52)
110 | * Add Russian (#53)
111 |
112 | ### Bug Fixes
113 |
114 | * Workaround for Safari bug with rotateY (#47) ([eadd89a](https://github.com/mister-ben/videojs-seek-buttons/commit/eadd89a)), closes [#47](https://github.com/mister-ben/videojs-seek-buttons/issues/47)
115 |
116 |
117 | # [2.1.0](https://github.com/mister-ben/videojs-seek-buttons/compare/v2.0.1...v2.1.0) (2021-07-20)
118 |
119 |
120 | ### Features
121 |
122 | * Add Farsi (#49) ([eda3607b2c564b1578133a76ece4c90de64439f3](https://github.com/mister-ben/videojs-seek-buttons/commit/eda3607b2c564b1578133a76ece4c90de64439f3))
123 |
124 |
125 | ## [2.0.1](https://github.com/mister-ben/videojs-seek-buttons/compare/v1.3.0...v2.0.1) (2021-06-06)
126 |
127 | ### Features
128 |
129 | * Remove google font (#38) ([1d85d5a](https://github.com/mister-ben/videojs-seek-buttons/commit/1d85d5a)), closes [#38](https://github.com/mister-ben/videojs-seek-buttons/issues/38)
130 |
131 | ### Bug Fixes
132 |
133 | * Restore skip-n classes (#45) ([0c9c453](https://github.com/mister-ben/videojs-seek-buttons/commit/0c9c453)), closes [#45](https://github.com/mister-ben/videojs-seek-buttons/issues/45)
134 | * Workaround for Safari bug with rotateY (#47) ([eadd89a](https://github.com/mister-ben/videojs-seek-buttons/commit/eadd89a)), closes [#47](https://github.com/mister-ben/videojs-seek-buttons/issues/47)
135 |
136 | ### Chores
137 |
138 | * Complete JSDoc comments ([fa24f5b](https://github.com/mister-ben/videojs-seek-buttons/commit/fa24f5b))
139 | * Improve tests ([12c3dcf](https://github.com/mister-ben/videojs-seek-buttons/commit/12c3dcf))
140 | * Update plugin generator to v7 ([141c2e4](https://github.com/mister-ben/videojs-seek-buttons/commit/141c2e4))
141 | * Update to Node 14 and Generator 8 packages ([06e56d5](https://github.com/mister-ben/videojs-seek-buttons/commit/06e56d5))
142 |
143 | ### Documentation
144 |
145 | * add css and option to readme ([d08a9df](https://github.com/mister-ben/videojs-seek-buttons/commit/d08a9df))
146 |
147 |
148 | # [2.0.0](https://github.com/mister-ben/videojs-seek-buttons/compare/v1.3.0...v2.0.0) (2021-05-31)
149 |
150 | ### Features
151 |
152 | * Remove google font (#38) ([1d85d5a](https://github.com/mister-ben/videojs-seek-buttons/commit/1d85d5a)), closes [#38](https://github.com/mister-ben/videojs-seek-buttons/issues/38)
153 |
154 | ### Bug Fixes
155 |
156 | * Restore skip-n classes (#45) ([0c9c453](https://github.com/mister-ben/videojs-seek-buttons/commit/0c9c453)), closes [#45](https://github.com/mister-ben/videojs-seek-buttons/issues/45)
157 |
158 | ### Chores
159 |
160 | * Complete JSDoc comments ([fa24f5b](https://github.com/mister-ben/videojs-seek-buttons/commit/fa24f5b))
161 | * Improve tests ([12c3dcf](https://github.com/mister-ben/videojs-seek-buttons/commit/12c3dcf))
162 | * Update plugin generator to v7 ([141c2e4](https://github.com/mister-ben/videojs-seek-buttons/commit/141c2e4))
163 | * Update to Node 14 and Generator 8 packages ([06e56d5](https://github.com/mister-ben/videojs-seek-buttons/commit/06e56d5))
164 |
165 | ### Documentation
166 |
167 | * add css and option to readme ([d08a9df](https://github.com/mister-ben/videojs-seek-buttons/commit/d08a9df))
168 |
169 |
170 | # [1.5.0](https://github.com/mister-ben/videojs-seek-buttons/compare/v1.5.0-beta0...v1.5.0) (2019-04-18)
171 |
172 | ### Documentation
173 |
174 | * add css and option to readme ([d08a9df](https://github.com/mister-ben/videojs-seek-buttons/commit/d08a9df))
175 |
176 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # CONTRIBUTING
2 |
3 | We welcome contributions from everyone!
4 |
5 | ## Getting Started
6 |
7 | Make sure you have Node.js 8 or higher and npm installed.
8 |
9 | 1. Fork this repository and clone your fork
10 | 1. Install dependencies: `npm install`
11 | 1. Run a development server: `npm start`
12 |
13 | ### Making Changes
14 |
15 | Refer to the [video.js plugin conventions][conventions] for more detail on best practices and tooling for video.js plugin authorship.
16 |
17 | When you've made your changes, push your commit(s) to your fork and issue a pull request against the original repository.
18 |
19 | ### Running Tests
20 |
21 | Testing is a crucial part of any software project. For all but the most trivial changes (typos, etc) test cases are expected. Tests are run in actual browsers using [Karma][karma].
22 |
23 | - In all available and supported browsers: `npm test`
24 | - In a specific browser: `npm run test:chrome`, `npm run test:firefox`, etc.
25 | - While development server is running (`npm start`), navigate to [`http://localhost:9999/test/`][local]
26 |
27 |
28 | [karma]: http://karma-runner.github.io/
29 | [local]: http://localhost:9999/test/
30 | [conventions]: https://github.com/videojs/generator-videojs-plugin/blob/master/docs/conventions.md
31 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright mister-ben
2 |
3 | Licensed under the Apache License, Version 2.0 (the "License");
4 | you may not use this file except in compliance with the License.
5 | You may obtain a copy of the License at
6 |
7 | http://www.apache.org/licenses/LICENSE-2.0
8 |
9 | Unless required by applicable law or agreed to in writing, software
10 | distributed under the License is distributed on an "AS IS" BASIS,
11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | See the License for the specific language governing permissions and
13 | limitations under the License.
14 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # videojs-seek-buttons
2 |
3 | Plugin for video.js to add seek buttons to the control bar. These buttons allow the user to skip forward or back by a configured number of seconds.
4 |
5 | ## Table of Contents
6 |
7 |
8 |
9 |
10 |
11 | - [Installation](#installation)
12 | - [Options](#options)
13 | - [Control position](#control-position)
14 | - [Usage](#usage)
15 | - [`
64 |
65 |
85 | ```
86 |
87 | The dist versions will be available from services which host npm packages such as jsdelivr:
88 |
89 | * https://cdn.jsdelivr.net/npm/videojs-seek-buttons/dist/videojs-seek-buttons.min.js
90 | * https://cdn.jsdelivr.net/npm/videojs-seek-buttons/dist/videojs-seek-buttons.css
91 |
92 | ### Browserify/CommonJS
93 |
94 | When using with Browserify, install videojs-seek-buttons via npm and `require` the plugin as you would any other module.
95 | Make sure if using React to also `include "videojs-seek-buttons/dist/videojs-seek-buttons.css"`, otherwise the icons will not appear in the control bar.
96 |
97 | ```js
98 | var videojs = require('video.js');
99 |
100 | // The actual plugin function is exported by this module, but it is also
101 | // attached to the `Player.prototype`; so, there is no need to assign it
102 | // to a variable.
103 | require('videojs-seek-buttons');
104 |
105 | var player = videojs('my-video');
106 |
107 | player.seekButtons({
108 | forward: 30,
109 | back: 10
110 | });
111 | ```
112 |
113 | ### RequireJS/AMD
114 |
115 | When using with RequireJS (or another AMD library), get the script in whatever way you prefer and `require` the plugin as you normally would:
116 |
117 | ```js
118 | require(['video.js', 'videojs-seek-buttons'], function(videojs) {
119 | var player = videojs('my-video');
120 |
121 | player.seekButtons({
122 | forward: 30,
123 | back: 10
124 | });
125 | });
126 | ```
127 |
128 | ## License
129 |
130 | Apache-2.0. Copyright (c) mister-ben <git@misterben.me>
131 |
132 |
133 | [videojs]: http://videojs.com/
134 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | videojs-seek-buttons Demo
6 |
7 |
8 |
9 |
10 |
14 |
18 |
19 |
20 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/lang/de.json:
--------------------------------------------------------------------------------
1 | {
2 | "Seek forward {{seconds}} seconds": "{{seconds}} Sekunden vorspulen",
3 | "Seek back {{seconds}} seconds": "{{seconds}} Sekunden zurückspulen"
4 | }
5 |
--------------------------------------------------------------------------------
/lang/en.json:
--------------------------------------------------------------------------------
1 | {
2 | "Seek forward {{seconds}} seconds": "Seek forward {{seconds}} seconds",
3 | "Seek back {{seconds}} seconds": "Seek back {{seconds}} seconds"
4 | }
--------------------------------------------------------------------------------
/lang/fa.json:
--------------------------------------------------------------------------------
1 | {
2 | "Seek forward {{seconds}} seconds": "{{seconds}} ثانیه بعد",
3 | "Seek back {{seconds}} seconds": "{{seconds}} ثانیه قبل"
4 | }
5 |
--------------------------------------------------------------------------------
/lang/it.json:
--------------------------------------------------------------------------------
1 | {
2 | "Seek forward {{seconds}} seconds": "Avanti di {{seconds}} secondi",
3 | "Seek back {{seconds}} seconds": "Indietro di {{seconds}} secondi"
4 | }
--------------------------------------------------------------------------------
/lang/ja.json:
--------------------------------------------------------------------------------
1 | {
2 | "Seek forward {{seconds}} seconds": "{{seconds}}秒進む",
3 | "Seek back {{seconds}} seconds": "{{seconds}}秒戻る"
4 | }
5 |
--------------------------------------------------------------------------------
/lang/lv.json:
--------------------------------------------------------------------------------
1 | {
2 | "Seek forward {{seconds}} seconds": "Pārtīt uz priekšu {{seconds}} sekundes",
3 | "Seek back {{seconds}} seconds": "Pārtīt atpakaļ {{seconds}} sekundes"
4 | }
5 |
--------------------------------------------------------------------------------
/lang/nl.json:
--------------------------------------------------------------------------------
1 | {
2 | "Seek forward {{seconds}} seconds": "{{seconds}} seconden vooruit",
3 | "Seek back {{seconds}} seconds": "{{seconds}} seconden terug"
4 | }
5 |
--------------------------------------------------------------------------------
/lang/ru.json:
--------------------------------------------------------------------------------
1 | {
2 | "Seek forward {{seconds}} seconds": "На {{seconds}} секунд вперед",
3 | "Seek back {{seconds}} seconds": "На {{seconds}} секунд назад"
4 | }
5 |
--------------------------------------------------------------------------------
/lang/zh-CN.json:
--------------------------------------------------------------------------------
1 | {
2 | "Seek forward {{seconds}} seconds": "快进 {{seconds}} 秒",
3 | "Seek back {{seconds}} seconds": "快退 {{seconds}} 秒"
4 | }
--------------------------------------------------------------------------------
/lang/zh-TW.json:
--------------------------------------------------------------------------------
1 | {
2 | "Seek forward {{seconds}} seconds": "快轉 {{seconds}} 秒",
3 | "Seek back {{seconds}} seconds": "倒轉 {{seconds}} 秒"
4 | }
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "videojs-seek-buttons",
3 | "repository": "https://github.com/mister-ben/videojs-seek-buttons",
4 | "issues": "https://github.com/mister-ben/videojs-seek-buttons/issues",
5 | "version": "4.0.2",
6 | "description": "Plugin for video.js to add seek buttons to the control bar",
7 | "main": "dist/videojs-seek-buttons.cjs.js",
8 | "module": "dist/videojs-seek-buttons.es.js",
9 | "generator-videojs-plugin": {
10 | "version": "8.0.0"
11 | },
12 | "scripts": {
13 | "prebuild": "npm run clean",
14 | "build": "npm-run-all -s clean -p build:*",
15 | "build-prod": "cross-env-shell NO_TEST_BUNDLE=1 'npm run build'",
16 | "build-test": "cross-env-shell TEST_BUNDLE_ONLY=1 'npm run build'",
17 | "build:css": "postcss -o dist/videojs-seek-buttons.css --config scripts/postcss.config.js src/plugin.css",
18 | "build:js": "rollup -c scripts/rollup.config.js",
19 | "build:lang": "vjslang --dir dist/lang",
20 | "clean": "shx rm -rf ./dist ./test/dist ./cjs ./es && shx mkdir -p ./dist ./test/dist ./cjs ./es",
21 | "postclean": "shx mkdir -p ./dist ./test/dist",
22 | "docs": "npm-run-all docs:*",
23 | "docs:api": "jsdoc src -r -d docs/api",
24 | "docs:toc": "doctoc --notitle README.md",
25 | "lint": "vjsstandard",
26 | "server": "karma start scripts/karma.conf.js --singleRun=false --auto-watch",
27 | "start": "npm-run-all -p server watch",
28 | "pretest": "npm-run-all lint build",
29 | "test": "npm-run-all lint build-test && karma start scripts/karma.conf.js",
30 | "posttest": "shx cat test/dist/coverage/text.txt",
31 | "test:unit": "karma start scripts/karma.conf.js",
32 | "test:verify": "vjsverify --skip-es-check --verbose",
33 | "update-changelog": "conventional-changelog -p videojs -i CHANGELOG.md -s",
34 | "preversion": "npm test",
35 | "version": "is-prerelease || npm run update-changelog && git add CHANGELOG.md",
36 | "watch": "npm-run-all -p watch:*",
37 | "watch:css": "npm run build:css -- -w",
38 | "watch:js": "npm run build:js -- -w",
39 | "prepublishOnly": "npm-run-all build-prod && vjsverify --skip-es-check --verbose"
40 | },
41 | "engines": {
42 | "node": ">=14",
43 | "npm": ">=6"
44 | },
45 | "keywords": [
46 | "videojs",
47 | "videojs-plugin"
48 | ],
49 | "author": "mister-ben ",
50 | "license": "Apache-2.0",
51 | "vjsstandard": {
52 | "ignore": [
53 | "es",
54 | "cjs",
55 | "dist",
56 | "docs",
57 | "test/dist"
58 | ]
59 | },
60 | "files": [
61 | "CONTRIBUTING.md",
62 | "cjs/",
63 | "dist/",
64 | "docs/",
65 | "es/",
66 | "index.html",
67 | "scripts/",
68 | "src/",
69 | "test/"
70 | ],
71 | "husky": {
72 | "hooks": {
73 | "pre-commit": "lint-staged",
74 | "pre-push": "npm run test"
75 | }
76 | },
77 | "lint-staged": {
78 | "*.js": "vjsstandard --fix",
79 | "README.md": "doctoc --notitle"
80 | },
81 | "dependencies": {
82 | "global": "^4.4.0"
83 | },
84 | "devDependencies": {
85 | "@babel/cli": "^7.13.16",
86 | "@babel/runtime": "^7.14.0",
87 | "@videojs/babel-config": "^1.0.0",
88 | "@videojs/generator-helpers": "~3.2.0",
89 | "jsdoc": "^4.0.0",
90 | "karma": "^6.3.2",
91 | "postcss": "^8.2.13",
92 | "postcss-cli": "^8.3.1",
93 | "rollup": "^2.46.0",
94 | "sinon": "^15.0.0",
95 | "video.js": "^8.3.0",
96 | "videojs-generate-karma-config": "~8.0.0",
97 | "videojs-generate-postcss-config": "~3.0.0",
98 | "videojs-generate-rollup-config": "^7.0.0",
99 | "videojs-generator-verify": "^4.1.0",
100 | "videojs-languages": "^2.0.0",
101 | "videojs-standard": "^9.0.1"
102 | },
103 | "peerDependencies": {
104 | "video.js": "^8"
105 | },
106 | "browser": "dist/videojs-seek-buttons.js"
107 | }
108 |
--------------------------------------------------------------------------------
/scripts/karma.conf.js:
--------------------------------------------------------------------------------
1 | const generate = require('videojs-generate-karma-config');
2 |
3 | module.exports = function(config) {
4 |
5 | // see https://github.com/videojs/videojs-generate-karma-config
6 | // for options
7 | const options = {};
8 |
9 | config = generate(config, options);
10 |
11 | // any other custom stuff not supported by options here!
12 | };
13 |
--------------------------------------------------------------------------------
/scripts/postcss.config.js:
--------------------------------------------------------------------------------
1 | const generate = require('videojs-generate-postcss-config');
2 |
3 | module.exports = function(context) {
4 | const result = generate({}, context);
5 |
6 | // do custom stuff here
7 |
8 | return result;
9 | };
10 |
--------------------------------------------------------------------------------
/scripts/rollup.config.js:
--------------------------------------------------------------------------------
1 | const generate = require('videojs-generate-rollup-config');
2 |
3 | // see https://github.com/videojs/videojs-generate-rollup-config
4 | // for options
5 | const options = {};
6 | const config = generate(options);
7 |
8 | // Add additonal builds/customization here!
9 |
10 | // export the builds to rollup
11 | export default Object.values(config.builds);
12 |
--------------------------------------------------------------------------------
/src/plugin.css:
--------------------------------------------------------------------------------
1 | .video-js {
2 |
3 | /* This class is added to the video.js element by the plugin by default. */
4 | & .vjs-seek-button {
5 | cursor: pointer;
6 |
7 | &.skip-back .vjs-icon-placeholder::before {
8 | transform: rotate(-45deg);
9 | }
10 |
11 | &.skip-forward .vjs-icon-placeholder::before {
12 | transform: scale(-1, 1) rotate(-45deg);
13 | }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/plugin.js:
--------------------------------------------------------------------------------
1 | import videojs from 'video.js';
2 | import {version as VERSION} from '../package.json';
3 |
4 | const Button = videojs.getComponent('Button');
5 |
6 | // Default options for the plugin.
7 | const defaults = {
8 | forwardIndex: 1,
9 | backIndex: 1
10 | };
11 |
12 | /**
13 | * Set up buttons when the player is ready.
14 | *
15 | * @function onPlayerReady
16 | * @param {Player} player
17 | * A Video.js player object.
18 | *
19 | * @param {Object} [options={}]
20 | * A plain object containing options for the plugin.
21 | */
22 | const onPlayerReady = (player, options) => {
23 |
24 | player.addClass('vjs-seek-buttons');
25 |
26 | if (options.forward && options.forward > 0) {
27 | player.controlBar.seekForward = player.controlBar.addChild('seekButton', {
28 | direction: 'forward',
29 | seconds: options.forward
30 | }, options.forwardIndex);
31 | }
32 |
33 | if (options.back && options.back > 0) {
34 | player.controlBar.seekBack = player.controlBar.addChild('seekButton', {
35 | direction: 'back',
36 | seconds: options.back
37 | }, options.backIndex);
38 | }
39 |
40 | };
41 |
42 | /**
43 | * Plugin init if ready or on ready
44 | *
45 | * @function seekButtons
46 | * @param {Object} [options={}]
47 | * An object of options left to the plugin author to define.
48 | */
49 | const seekButtons = function(options) {
50 | this.ready(() => {
51 | onPlayerReady(this, videojs.obj.merge(defaults, options));
52 | });
53 | };
54 |
55 | // Include the version number.
56 | seekButtons.VERSION = VERSION;
57 |
58 | /**
59 | * Button to seek forward/back
60 | *
61 | * @extends Button
62 | * @class SeekButton
63 | */
64 | class SeekButton extends Button {
65 | /**
66 | * Constructor for class
67 | *
68 | * @param {Player|Object} player The player
69 | * @param {Object=} options Button options
70 | * @param {string} options.direction back or forward
71 | * @param {Int} options.seconds number of seconds to seek
72 | */
73 | constructor(player, options) {
74 | super(player, options);
75 | this.$('.vjs-icon-placeholder').classList.add('vjs-icon-replay');
76 | if (this.options_.direction === 'forward') {
77 | this.controlText(this.localize('Seek forward {{seconds}} seconds')
78 | .replace('{{seconds}}', this.options_.seconds));
79 | } else if (this.options_.direction === 'back') {
80 | this.controlText(this.localize('Seek back {{seconds}} seconds')
81 | .replace('{{seconds}}', this.options_.seconds));
82 | }
83 | }
84 |
85 | /**
86 | * Return button class names which include the seek amount.
87 | *
88 | * @return {string} css cass string
89 | */
90 | buildCSSClass() {
91 | /* Each button will have the classes:
92 | `vjs-seek-button`
93 | `skip-forward` or `skip-back`
94 | `skip-n` where `n` is the number of seconds
95 | So you could have a generic icon for "skip back" and a more
96 | specific one for "skip back 30 seconds"
97 | */
98 | return `vjs-seek-button skip-${this.options_.direction} ` +
99 | `skip-${this.options_.seconds} ${super.buildCSSClass()}`;
100 | }
101 |
102 | /**
103 | * Seek with the button's configured offset
104 | */
105 | handleClick() {
106 | const now = this.player_.currentTime();
107 |
108 | if (this.options_.direction === 'forward') {
109 | let duration = this.player_.duration();
110 |
111 | if (this.player_.liveTracker && this.player_.liveTracker.isLive()) {
112 | duration = this.player_.liveTracker.seekableEnd();
113 | }
114 |
115 | this.player_.currentTime(Math.min(now + this.options_.seconds, duration));
116 | } else if (this.options_.direction === 'back') {
117 | this.player_.currentTime(Math.max(0, now - this.options_.seconds));
118 | }
119 | }
120 | }
121 | videojs.registerComponent('SeekButton', SeekButton);
122 |
123 | // Register the plugin with video.js.
124 | videojs.registerPlugin('seekButtons', seekButtons);
125 |
126 | export default seekButtons;
127 |
--------------------------------------------------------------------------------
/test/plugin.test.js:
--------------------------------------------------------------------------------
1 | import document from 'global/document';
2 |
3 | import QUnit from 'qunit';
4 | import sinon from 'sinon';
5 | import videojs from 'video.js';
6 |
7 | import plugin from '../src/plugin';
8 |
9 | const Player = videojs.getComponent('Player');
10 |
11 | QUnit.test('the environment is sane', function(assert) {
12 | assert.strictEqual(typeof Array.isArray, 'function', 'es5 exists');
13 | assert.strictEqual(typeof sinon, 'object', 'sinon exists');
14 | assert.strictEqual(typeof videojs, 'function', 'videojs exists');
15 | assert.strictEqual(typeof plugin, 'function', 'plugin is a function');
16 | });
17 |
18 | QUnit.module('videojs-seek-buttons', {
19 |
20 | beforeEach() {
21 |
22 | // Mock the environment's timers because certain things - particularly
23 | // player readiness - are asynchronous in video.js 5. This MUST come
24 | // before any player is created; otherwise, timers could get created
25 | // with the actual timer methods!
26 | this.clock = sinon.useFakeTimers();
27 |
28 | this.fixture = document.getElementById('qunit-fixture');
29 | this.video = document.createElement('video');
30 | this.fixture.appendChild(this.video);
31 | this.player = videojs(this.video);
32 | },
33 |
34 | afterEach() {
35 | this.player.dispose();
36 | this.clock.restore();
37 | }
38 | });
39 |
40 | QUnit.test('registers itself with video.js', function(assert) {
41 | assert.expect(2);
42 |
43 | assert.strictEqual(
44 | typeof Player.prototype.seekButtons,
45 | 'function',
46 | 'videojs-seek-buttons plugin was registered'
47 | );
48 |
49 | this.player.seekButtons();
50 |
51 | // Tick the clock forward enough to trigger the player to be "ready".
52 | this.clock.tick(1);
53 |
54 | assert.ok(
55 | this.player.hasClass('vjs-seek-buttons'),
56 | 'the plugin adds a class to the player'
57 | );
58 | });
59 |
60 | QUnit.test('adds buttons with classes', function(assert) {
61 | this.player.seekButtons({
62 | forward: 30,
63 | back: 10
64 | });
65 |
66 | // Tick the clock forward enough to trigger the player to be "ready".
67 | this.clock.tick(1);
68 |
69 | assert.ok(
70 | this.player.controlBar.seekBack,
71 | 'the plugin adds a back button to the player'
72 | );
73 |
74 | assert.ok(
75 | this.player.controlBar.seekForward,
76 | 'the plugin adds a forward button to the player'
77 | );
78 |
79 | assert.ok(
80 | this.player.controlBar.seekBack.hasClass('skip-10'),
81 | 'the plugin adds a seconds class to the button'
82 | );
83 |
84 | assert.ok(
85 | this.player.controlBar.seekBack.hasClass('skip-back'),
86 | 'the plugin adds a direction class to the button'
87 | );
88 | });
89 |
90 | QUnit.test('calls currentTime with the correct time', function(assert) {
91 | this.player.duration(100);
92 |
93 | this.player.seekButtons({
94 | forward: 30,
95 | back: 10
96 | });
97 |
98 | // Tick the clock forward enough to trigger the player to be "ready".
99 | this.clock.tick(1);
100 |
101 | const time = this.player.currentTime();
102 |
103 | const spy = sinon.spy(this.player, 'currentTime');
104 |
105 | this.player.controlBar.seekForward.trigger('click');
106 |
107 | assert.ok(
108 | spy.withArgs(time + 30).calledOnce,
109 | 'forward button triggers seek 30 seconds'
110 | );
111 |
112 | // Fake that the seek happened - it won't have as the test player has no source.
113 | this.player.tech_.currentTime = () => 30;
114 |
115 | this.player.controlBar.seekBack.trigger('click');
116 |
117 | assert.ok(
118 | spy.withArgs(20).calledOnce,
119 | 'back button triggers seek back 10 seconds'
120 | );
121 |
122 | });
123 |
--------------------------------------------------------------------------------