Housekeeping
This commit is contained in:
parent
ba91f23c50
commit
e48b1d11ce
2
.github/issue_template.md
vendored
2
.github/issue_template.md
vendored
@ -1,3 +1,3 @@
|
|||||||
PLEASE USE OUR SPECIFIC ISSUE TEMPLATES for bug reports, features and improvement suggestions.
|
PLEASE USE OUR SPECIFIC ISSUE TEMPLATES for bug reports, features and improvement suggestions.
|
||||||
|
|
||||||
Our issue tracker is not for support questions. If you need help, follow our support instructions: https://github.com/sampotts/plyr/blob/master/contributing.md#support
|
Our issue tracker is not for support questions. If you need help, follow our support instructions: https://github.com/sampotts/plyr/blob/master/CONTRIBUTING.md#support
|
||||||
|
1157
CHANGELOG.md
Normal file
1157
CHANGELOG.md
Normal file
File diff suppressed because it is too large
Load Diff
@ -7,15 +7,17 @@ We welcome bug reports, feature requests and pull requests. If you want to help
|
|||||||
Before asking questions, read our [documentation](https://github.com/sampotts/plyr) and [FAQ](https://github.com/sampotts/plyr/wiki/FAQ).
|
Before asking questions, read our [documentation](https://github.com/sampotts/plyr) and [FAQ](https://github.com/sampotts/plyr/wiki/FAQ).
|
||||||
|
|
||||||
If these doesn't answer your question
|
If these doesn't answer your question
|
||||||
* Use [Stack Overflow](https://stackoverflow.com/) for questions that doesn't directly involve Plyr. This includes for example how to use Javascript, CSS or HTML5 media in general, and how to use other frameworks, libraries and technology.
|
|
||||||
* Use [our Slack](https://bit.ly/plyr-chat) if you need help using Plyr or have questions about Plyr.
|
- Use [Stack Overflow](https://stackoverflow.com/) for questions that doesn't directly involve Plyr. This includes for example how to use Javascript, CSS or HTML5 media in general, and how to use other frameworks, libraries and technology.
|
||||||
|
- Use [our Slack](https://bit.ly/plyr-chat) if you need help using Plyr or have questions about Plyr.
|
||||||
|
|
||||||
## Commenting
|
## Commenting
|
||||||
|
|
||||||
When commenting, keep a civil tone and stay on topic. Don't ask for [support](#support), or post "+1" or "I agree" type of comments. Use the emojis instead.
|
When commenting, keep a civil tone and stay on topic. Don't ask for [support](#support), or post "+1" or "I agree" type of comments. Use the emojis instead.
|
||||||
|
|
||||||
Asking for the status on issues is discouraged. Unless someone has explicitly said in an issue that it's work in progress, most likely that means no one is working on it. We have a lot to do, and it may not be a top priority for us.
|
Asking for the status on issues is discouraged. Unless someone has explicitly said in an issue that it's work in progress, most likely that means no one is working on it. We have a lot to do, and it may not be a top priority for us.
|
||||||
|
|
||||||
We *may* moderate discussions. We do this to avoid threads being "hijacked", to avoid confusion in case the content is misleading or outdated, and to avoid bothering people with github notifications.
|
We _may_ moderate discussions. We do this to avoid threads being "hijacked", to avoid confusion in case the content is misleading or outdated, and to avoid bothering people with github notifications.
|
||||||
|
|
||||||
## Creating issues
|
## Creating issues
|
||||||
|
|
||||||
@ -23,11 +25,11 @@ Please follow the instructions in our issue templates. Don't use github issues t
|
|||||||
|
|
||||||
## Contributing features and documentation
|
## Contributing features and documentation
|
||||||
|
|
||||||
* If you want to add a feature or make critical changes, you may want to ensure that this is something we also want (so you don't waste your time). Ask us about this in the corresponding issue if there is one, or on [our Slack](https://bit.ly/plyr-chat) otherwise.
|
- If you want to add a feature or make critical changes, you may want to ensure that this is something we also want (so you don't waste your time). Ask us about this in the corresponding issue if there is one, or on [our Slack](https://bit.ly/plyr-chat) otherwise.
|
||||||
|
|
||||||
* Fork Plyr, and create a new branch in your fork, based on the **develop** branch
|
- Fork Plyr, and create a new branch in your fork, based on the **develop** branch
|
||||||
|
|
||||||
* To test locally, you can use the demo site. First make sure you have installed the dependencies with `npm install` or `yarn`. Run `gulp` to build and it will run a local web server for development and watch for any changes.
|
- To test locally, you can use the demo site. First make sure you have installed the dependencies with `npm install` or `yarn`. Run `gulp` to build and it will run a local web server for development and watch for any changes.
|
||||||
|
|
||||||
### Online one-click setup for contributing
|
### Online one-click setup for contributing
|
||||||
|
|
||||||
@ -41,12 +43,12 @@ So that you can start straight away.
|
|||||||
|
|
||||||
[](https://gitpod.io/from-referrer/)
|
[](https://gitpod.io/from-referrer/)
|
||||||
|
|
||||||
* Develop and test your modifications.
|
- Develop and test your modifications.
|
||||||
|
|
||||||
* Preferably commit your changes as independent logical chunks, with meaningful messages. Make sure you do not commit unnecessary files or changes, such as the build output, or logging and breakpoints you added for testing.
|
- Preferably commit your changes as independent logical chunks, with meaningful messages. Make sure you do not commit unnecessary files or changes, such as the build output, or logging and breakpoints you added for testing.
|
||||||
|
|
||||||
* If your modifications changes the documented behavior or add new features, document these changes in readme.md.
|
- If your modifications changes the documented behavior or add new features, document these changes in [README.md](README.md).
|
||||||
|
|
||||||
* When finished, push the changes to your GitHub repository and send a pull request to **develop**. Describe what your PR does.
|
- When finished, push the changes to your GitHub repository and send a pull request to **develop**. Describe what your PR does.
|
||||||
|
|
||||||
* If the Travis build fails, or if you get a code review with change requests, you can fix these by pushing new or rebased commits to the branch.
|
- If the Travis build fails, or if you get a code review with change requests, you can fix these by pushing new or rebased commits to the branch.
|
@ -376,7 +376,7 @@ Note the single quotes encapsulating the JSON and double quotes on the object ke
|
|||||||
| -------------------- | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
| -------------------- | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| `enabled` | Boolean | `true` | Completely disable Plyr. This would allow you to do a User Agent check or similar to programmatically enable or disable Plyr for a certain UA. Example below. |
|
| `enabled` | Boolean | `true` | Completely disable Plyr. This would allow you to do a User Agent check or similar to programmatically enable or disable Plyr for a certain UA. Example below. |
|
||||||
| `debug` | Boolean | `false` | Display debugging information in the console |
|
| `debug` | Boolean | `false` | Display debugging information in the console |
|
||||||
| `controls` | Array, Function or Element | `['play-large', 'play', 'progress', 'current-time', 'mute', 'volume', 'captions', 'settings', 'pip', 'airplay', 'fullscreen']` | If a function is passed, it is assumed your method will return either an element or HTML string for the controls. Three arguments will be passed to your function; `id` (the unique id for the player), `seektime` (the seektime step in seconds), and `title` (the media title). See [controls.md](controls.md) for more info on how the html needs to be structured. |
|
| `controls` | Array, Function or Element | `['play-large', 'play', 'progress', 'current-time', 'mute', 'volume', 'captions', 'settings', 'pip', 'airplay', 'fullscreen']` | If a function is passed, it is assumed your method will return either an element or HTML string for the controls. Three arguments will be passed to your function; `id` (the unique id for the player), `seektime` (the seektime step in seconds), and `title` (the media title). See [CONTROLS.md](CONTROLS.md) for more info on how the html needs to be structured. |
|
||||||
| `settings` | Array | `['captions', 'quality', 'speed', 'loop']` | If the default controls are used, you can specify which settings to show in the menu |
|
| `settings` | Array | `['captions', 'quality', 'speed', 'loop']` | If the default controls are used, you can specify which settings to show in the menu |
|
||||||
| `i18n` | Object | See [defaults.js](/src/js/config/defaults.js) | Used for internationalization (i18n) of the text within the UI. |
|
| `i18n` | Object | See [defaults.js](/src/js/config/defaults.js) | Used for internationalization (i18n) of the text within the UI. |
|
||||||
| `loadSprite` | Boolean | `true` | Load the SVG sprite specified as the `iconUrl` option (if a URL). If `false`, it is assumed you are handling sprite loading yourself. |
|
| `loadSprite` | Boolean | `true` | Load the SVG sprite specified as the `iconUrl` option (if a URL). If `false`, it is assumed you are handling sprite loading yourself. |
|
||||||
@ -400,7 +400,7 @@ Note the single quotes encapsulating the JSON and double quotes on the object ke
|
|||||||
| `toggleInvert` | Boolean | `true` | Allow users to click to toggle the above. |
|
| `toggleInvert` | Boolean | `true` | Allow users to click to toggle the above. |
|
||||||
| `listeners` | Object | `null` | Allows binding of event listeners to the controls before the default handlers. See the `defaults.js` for available listeners. If your handler prevents default on the event (`event.preventDefault()`), the default handler will not fire. |
|
| `listeners` | Object | `null` | Allows binding of event listeners to the controls before the default handlers. See the `defaults.js` for available listeners. If your handler prevents default on the event (`event.preventDefault()`), the default handler will not fire. |
|
||||||
| `captions` | Object | `{ active: false, language: 'auto', update: false }` | `active`: Toggles if captions should be active by default. `language`: Sets the default language to load (if available). 'auto' uses the browser language. `update`: Listen to changes to tracks and update menu. This is needed for some streaming libraries, but can result in unselectable language options). |
|
| `captions` | Object | `{ active: false, language: 'auto', update: false }` | `active`: Toggles if captions should be active by default. `language`: Sets the default language to load (if available). 'auto' uses the browser language. `update`: Listen to changes to tracks and update menu. This is needed for some streaming libraries, but can result in unselectable language options). |
|
||||||
| `fullscreen` | Object | `{ enabled: true, fallback: true, iosNative: false, container: null }` | `enabled`: Toggles whether fullscreen should be enabled. `fallback`: Allow fallback to a full-window solution (`true`/`false`/`'force'`). `iosNative`: whether to use native iOS fullscreen when entering fullscreen (no custom controls). `container`: A selector for an ancestor of the player element, allows contextual content to remain visual in fullscreen mode. Non-ancestors are ignored. |
|
| `fullscreen` | Object | `{ enabled: true, fallback: true, iosNative: false, container: null }` | `enabled`: Toggles whether fullscreen should be enabled. `fallback`: Allow fallback to a full-window solution (`true`/`false`/`'force'`). `iosNative`: whether to use native iOS fullscreen when entering fullscreen (no custom controls). `container`: A selector for an ancestor of the player element, allows contextual content to remain visual in fullscreen mode. Non-ancestors are ignored. |
|
||||||
| `ratio` | String | `null` | Force an aspect ratio for all videos. The format is `'w:h'` - e.g. `'16:9'` or `'4:3'`. If this is not specified then the default for HTML5 and Vimeo is to use the native resolution of the video. As dimensions are not available from YouTube via SDK, 16:9 is forced as a sensible default. |
|
| `ratio` | String | `null` | Force an aspect ratio for all videos. The format is `'w:h'` - e.g. `'16:9'` or `'4:3'`. If this is not specified then the default for HTML5 and Vimeo is to use the native resolution of the video. As dimensions are not available from YouTube via SDK, 16:9 is forced as a sensible default. |
|
||||||
| `storage` | Object | `{ enabled: true, key: 'plyr' }` | `enabled`: Allow use of local storage to store user settings. `key`: The key name to use. |
|
| `storage` | Object | `{ enabled: true, key: 'plyr' }` | `enabled`: Allow use of local storage to store user settings. `key`: The key name to use. |
|
||||||
| `speed` | Object | `{ selected: 1, options: [0.5, 0.75, 1, 1.25, 1.5, 1.75, 2] }` | `selected`: The default speed for playback. `options`: The speed options to display in the UI. YouTube and Vimeo will ignore any options outside of the 0.5-2 range, so options outside of this range will be hidden automatically. |
|
| `speed` | Object | `{ selected: 1, options: [0.5, 0.75, 1, 1.25, 1.5, 1.75, 2] }` | `selected`: The default speed for playback. `options`: The speed options to display in the UI. YouTube and Vimeo will ignore any options outside of the 0.5-2 range, so options outside of this range will be hidden automatically. |
|
||||||
@ -876,4 +876,4 @@ Support this project with your organization. Your logo will show up here with a
|
|||||||
|
|
||||||
# Copyright and License
|
# Copyright and License
|
||||||
|
|
||||||
[The MIT license](license.md)
|
[The MIT license](LICENSE.md)
|
1153
changelog.md
1153
changelog.md
File diff suppressed because it is too large
Load Diff
@ -1,7 +1,7 @@
|
|||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
// Plyr.io demo
|
// Plyr.io demo
|
||||||
// This code is purely for the https://plyr.io website
|
// This code is purely for the https://plyr.io website
|
||||||
// Please see readme.md in the root or github.com/sampotts/plyr
|
// Please see README.md in the root or github.com/sampotts/plyr
|
||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
|
|
||||||
import './tab-focus';
|
import './tab-focus';
|
||||||
|
20
deploy.json
20
deploy.json
@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"cdn": {
|
"cdn": {
|
||||||
"bucket": "plyr",
|
"bucket": "plyr",
|
||||||
"domain": "cdn.plyr.io",
|
"domain": "cdn.plyr.io",
|
||||||
"region": "us-east-1"
|
"region": "us-east-1"
|
||||||
},
|
},
|
||||||
"demo": {
|
"demo": {
|
||||||
"bucket": "plyr.io",
|
"bucket": "plyr.io",
|
||||||
"domain": "plyr.io",
|
"domain": "plyr.io",
|
||||||
"region": "us-west-1"
|
"region": "us-west-1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,37 +1,37 @@
|
|||||||
{
|
{
|
||||||
"folders": [
|
"folders": [
|
||||||
{
|
{
|
||||||
"path": "."
|
"path": "."
|
||||||
}
|
|
||||||
],
|
|
||||||
"settings": {
|
|
||||||
"search.exclude": {
|
|
||||||
"**/node_modules": true,
|
|
||||||
"**/dist": true
|
|
||||||
},
|
|
||||||
|
|
||||||
// Linting
|
|
||||||
"stylelint.enable": true,
|
|
||||||
"css.validate": false,
|
|
||||||
"scss.validate": false,
|
|
||||||
"javascript.validate.enable": false,
|
|
||||||
|
|
||||||
// Formatting
|
|
||||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
|
||||||
"editor.tabSize": 4,
|
|
||||||
"editor.insertSpaces": true,
|
|
||||||
"editor.formatOnSave": true,
|
|
||||||
|
|
||||||
// Trim on save
|
|
||||||
"files.trimTrailingWhitespace": true,
|
|
||||||
|
|
||||||
// Special file associations
|
|
||||||
"files.associations": {
|
|
||||||
".eslintrc": "jsonc"
|
|
||||||
},
|
|
||||||
|
|
||||||
"editor.codeActionsOnSave": {
|
|
||||||
"source.fixAll": true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
],
|
||||||
|
"settings": {
|
||||||
|
"search.exclude": {
|
||||||
|
"**/node_modules": true,
|
||||||
|
"**/dist": true
|
||||||
|
},
|
||||||
|
|
||||||
|
// Linting
|
||||||
|
"stylelint.enable": true,
|
||||||
|
"css.validate": false,
|
||||||
|
"scss.validate": false,
|
||||||
|
"javascript.validate.enable": false,
|
||||||
|
|
||||||
|
// Formatting
|
||||||
|
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||||
|
"editor.tabSize": 4,
|
||||||
|
"editor.insertSpaces": true,
|
||||||
|
"editor.formatOnSave": true,
|
||||||
|
|
||||||
|
// Trim on save
|
||||||
|
"files.trimTrailingWhitespace": true,
|
||||||
|
|
||||||
|
// Special file associations
|
||||||
|
"files.associations": {
|
||||||
|
".eslintrc": "jsonc"
|
||||||
|
},
|
||||||
|
|
||||||
|
"editor.codeActionsOnSave": {
|
||||||
|
"source.fixAll": true
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
2
src/js/plyr.d.ts
vendored
2
src/js/plyr.d.ts
vendored
@ -321,7 +321,7 @@ declare namespace Plyr {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* If a function is passed, it is assumed your method will return either an element or HTML string for the controls. Three arguments will be passed to your function;
|
* If a function is passed, it is assumed your method will return either an element or HTML string for the controls. Three arguments will be passed to your function;
|
||||||
* id (the unique id for the player), seektime (the seektime step in seconds), and title (the media title). See controls.md for more info on how the html needs to be structured.
|
* id (the unique id for the player), seektime (the seektime step in seconds), and title (the media title). See CONTROLS.md for more info on how the html needs to be structured.
|
||||||
* Defaults to ['play-large', 'play', 'progress', 'current-time', 'mute', 'volume', 'captions', 'settings', 'pip', 'airplay', 'fullscreen']
|
* Defaults to ['play-large', 'play', 'progress', 'current-time', 'mute', 'volume', 'captions', 'settings', 'pip', 'airplay', 'fullscreen']
|
||||||
*/
|
*/
|
||||||
controls?: string[] | ((id: string, seektime: number, title: string) => unknown) | Element;
|
controls?: string[] | ((id: string, seektime: number, title: string) => unknown) | Element;
|
||||||
|
258
tasks/build.js
258
tasks/build.js
@ -37,37 +37,37 @@ const minSuffix = '.min';
|
|||||||
// Paths
|
// Paths
|
||||||
const root = path.join(__dirname, '..');
|
const root = path.join(__dirname, '..');
|
||||||
const paths = {
|
const paths = {
|
||||||
plyr: {
|
plyr: {
|
||||||
// Source paths
|
// Source paths
|
||||||
src: {
|
src: {
|
||||||
sass: path.join(root, 'src/sass/**/*.scss'),
|
sass: path.join(root, 'src/sass/**/*.scss'),
|
||||||
js: path.join(root, 'src/js/**/*.js'),
|
js: path.join(root, 'src/js/**/*.js'),
|
||||||
sprite: path.join(root, 'src/sprite/*.svg'),
|
sprite: path.join(root, 'src/sprite/*.svg'),
|
||||||
},
|
|
||||||
|
|
||||||
// Output paths
|
|
||||||
output: path.join(root, 'dist/'),
|
|
||||||
},
|
},
|
||||||
demo: {
|
|
||||||
// Source paths
|
|
||||||
src: {
|
|
||||||
sass: path.join(root, 'demo/src/sass/**/*.scss'),
|
|
||||||
js: path.join(root, 'demo/src/js/**/*.js'),
|
|
||||||
},
|
|
||||||
|
|
||||||
// Output paths
|
// Output paths
|
||||||
output: path.join(root, 'demo/dist/'),
|
output: path.join(root, 'dist/'),
|
||||||
|
},
|
||||||
// Demo
|
demo: {
|
||||||
root: path.join(root, 'demo/'),
|
// Source paths
|
||||||
|
src: {
|
||||||
|
sass: path.join(root, 'demo/src/sass/**/*.scss'),
|
||||||
|
js: path.join(root, 'demo/src/js/**/*.js'),
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// Output paths
|
||||||
|
output: path.join(root, 'demo/dist/'),
|
||||||
|
|
||||||
|
// Demo
|
||||||
|
root: path.join(root, 'demo/'),
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
// Task lists
|
// Task lists
|
||||||
const tasks = {
|
const tasks = {
|
||||||
css: [],
|
css: [],
|
||||||
js: [],
|
js: [],
|
||||||
sprite: [],
|
sprite: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
// Size plugin
|
// Size plugin
|
||||||
@ -75,115 +75,115 @@ const sizeOptions = { showFiles: true, gzip: true };
|
|||||||
|
|
||||||
// Clean out /dist
|
// Clean out /dist
|
||||||
gulp.task('clean', done => {
|
gulp.task('clean', done => {
|
||||||
const dirs = [paths.plyr.output, paths.demo.output].map(dir => path.join(dir, '**/*'));
|
const dirs = [paths.plyr.output, paths.demo.output].map(dir => path.join(dir, '**/*'));
|
||||||
|
|
||||||
// Don't delete the mp4
|
// Don't delete the mp4
|
||||||
dirs.push(`!${path.join(paths.plyr.output, '**/*.mp4')}`);
|
dirs.push(`!${path.join(paths.plyr.output, '**/*.mp4')}`);
|
||||||
|
|
||||||
del(dirs);
|
del(dirs);
|
||||||
|
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|
||||||
// JavaScript
|
// JavaScript
|
||||||
Object.entries(build.js).forEach(([filename, entry]) => {
|
Object.entries(build.js).forEach(([filename, entry]) => {
|
||||||
const { dist, formats, namespace, polyfill, src } = entry;
|
const { dist, formats, namespace, polyfill, src } = entry;
|
||||||
|
|
||||||
formats.forEach(format => {
|
formats.forEach(format => {
|
||||||
const name = `js:${filename}:${format}`;
|
const name = `js:${filename}:${format}`;
|
||||||
const extension = format === 'es' ? 'mjs' : 'js';
|
const extension = format === 'es' ? 'mjs' : 'js';
|
||||||
tasks.js.push(name);
|
tasks.js.push(name);
|
||||||
|
|
||||||
gulp.task(name, () =>
|
gulp.task(name, () =>
|
||||||
gulp
|
gulp
|
||||||
.src(src)
|
.src(src)
|
||||||
.pipe(plumber())
|
.pipe(plumber())
|
||||||
.pipe(sourcemaps.init())
|
.pipe(sourcemaps.init())
|
||||||
.pipe(
|
.pipe(
|
||||||
rollup(
|
rollup(
|
||||||
{
|
{
|
||||||
plugins: [
|
plugins: [
|
||||||
resolve(),
|
resolve(),
|
||||||
commonjs(),
|
commonjs(),
|
||||||
babel({
|
babel({
|
||||||
presets: [
|
presets: [
|
||||||
[
|
[
|
||||||
'@babel/env',
|
'@babel/env',
|
||||||
{
|
{
|
||||||
// debug: true,
|
// debug: true,
|
||||||
useBuiltIns: polyfill ? 'usage' : false,
|
useBuiltIns: polyfill ? 'usage' : false,
|
||||||
corejs: polyfill ? 3 : undefined,
|
corejs: polyfill ? 3 : undefined,
|
||||||
bugfixes: true,
|
bugfixes: true,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
babelrc: false,
|
babelrc: false,
|
||||||
exclude: [/\/core-js\//],
|
exclude: [/\/core-js\//],
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: namespace,
|
name: namespace,
|
||||||
format,
|
format,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.pipe(header('typeof navigator === "object" && ')) // "Support" SSR (#935)
|
.pipe(header('typeof navigator === "object" && ')) // "Support" SSR (#935)
|
||||||
.pipe(
|
.pipe(
|
||||||
rename({
|
rename({
|
||||||
extname: `.${extension}`,
|
extname: `.${extension}`,
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.pipe(gulp.dest(dist))
|
.pipe(gulp.dest(dist))
|
||||||
.pipe(filter(`**/*.${extension}`))
|
.pipe(filter(`**/*.${extension}`))
|
||||||
.pipe(terser())
|
.pipe(terser())
|
||||||
.pipe(rename({ suffix: minSuffix }))
|
.pipe(rename({ suffix: minSuffix }))
|
||||||
.pipe(size(sizeOptions))
|
.pipe(size(sizeOptions))
|
||||||
.pipe(sourcemaps.write(''))
|
.pipe(sourcemaps.write(''))
|
||||||
.pipe(gulp.dest(dist)),
|
.pipe(gulp.dest(dist)),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// CSS
|
// CSS
|
||||||
Object.entries(build.css).forEach(([filename, entry]) => {
|
Object.entries(build.css).forEach(([filename, entry]) => {
|
||||||
const { dist, src } = entry;
|
const { dist, src } = entry;
|
||||||
const name = `css:${filename}`;
|
const name = `css:${filename}`;
|
||||||
tasks.css.push(name);
|
tasks.css.push(name);
|
||||||
|
|
||||||
gulp.task(name, () =>
|
gulp.task(name, () =>
|
||||||
gulp
|
gulp
|
||||||
.src(src)
|
.src(src)
|
||||||
.pipe(plumber())
|
.pipe(plumber())
|
||||||
.pipe(sass())
|
.pipe(sass())
|
||||||
.pipe(postcss([customprops(), autoprefixer(), clean()]))
|
.pipe(postcss([customprops(), autoprefixer(), clean()]))
|
||||||
.pipe(size(sizeOptions))
|
.pipe(size(sizeOptions))
|
||||||
.pipe(gulp.dest(dist)),
|
.pipe(gulp.dest(dist)),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
// SVG Sprites
|
// SVG Sprites
|
||||||
Object.entries(build.sprite).forEach(([filename, entry]) => {
|
Object.entries(build.sprite).forEach(([filename, entry]) => {
|
||||||
const { dist, src } = entry;
|
const { dist, src } = entry;
|
||||||
const name = `sprite:${filename}`;
|
const name = `sprite:${filename}`;
|
||||||
tasks.sprite.push(name);
|
tasks.sprite.push(name);
|
||||||
|
|
||||||
gulp.task(name, () =>
|
gulp.task(name, () =>
|
||||||
gulp
|
gulp
|
||||||
.src(src)
|
.src(src)
|
||||||
.pipe(plumber())
|
.pipe(plumber())
|
||||||
.pipe(
|
.pipe(
|
||||||
imagemin([
|
imagemin([
|
||||||
imagemin.svgo({
|
imagemin.svgo({
|
||||||
plugins: [{ removeViewBox: false }],
|
plugins: [{ removeViewBox: false }],
|
||||||
}),
|
}),
|
||||||
]),
|
]),
|
||||||
)
|
)
|
||||||
.pipe(svgstore())
|
.pipe(svgstore())
|
||||||
.pipe(rename({ basename: path.parse(filename).name }))
|
.pipe(rename({ basename: path.parse(filename).name }))
|
||||||
.pipe(size(sizeOptions))
|
.pipe(size(sizeOptions))
|
||||||
.pipe(gulp.dest(dist)),
|
.pipe(gulp.dest(dist)),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Build all tasks
|
// Build all tasks
|
||||||
@ -193,26 +193,26 @@ gulp.task('sprites', gulp.parallel(...tasks.sprite));
|
|||||||
|
|
||||||
// Watch for file changes
|
// Watch for file changes
|
||||||
gulp.task('watch', () => {
|
gulp.task('watch', () => {
|
||||||
// Plyr core
|
// Plyr core
|
||||||
gulp.watch(paths.plyr.src.js, gulp.parallel('js'));
|
gulp.watch(paths.plyr.src.js, gulp.parallel('js'));
|
||||||
gulp.watch(paths.plyr.src.sass, gulp.parallel('css'));
|
gulp.watch(paths.plyr.src.sass, gulp.parallel('css'));
|
||||||
gulp.watch(paths.plyr.src.sprite, gulp.parallel('sprites'));
|
gulp.watch(paths.plyr.src.sprite, gulp.parallel('sprites'));
|
||||||
|
|
||||||
// Demo
|
// Demo
|
||||||
gulp.watch(paths.demo.src.js, gulp.parallel('js'));
|
gulp.watch(paths.demo.src.js, gulp.parallel('js'));
|
||||||
gulp.watch(paths.demo.src.sass, gulp.parallel('css'));
|
gulp.watch(paths.demo.src.sass, gulp.parallel('css'));
|
||||||
});
|
});
|
||||||
|
|
||||||
// Serve via browser sync
|
// Serve via browser sync
|
||||||
gulp.task('serve', () =>
|
gulp.task('serve', () =>
|
||||||
browserSync.init({
|
browserSync.init({
|
||||||
server: {
|
server: {
|
||||||
baseDir: paths.demo.root,
|
baseDir: paths.demo.root,
|
||||||
},
|
},
|
||||||
notify: false,
|
notify: false,
|
||||||
watch: true,
|
watch: true,
|
||||||
ghostMode: false,
|
ghostMode: false,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
// Build distribution
|
// Build distribution
|
||||||
|
317
tasks/deploy.js
317
tasks/deploy.js
@ -28,244 +28,245 @@ const minSuffix = '.min';
|
|||||||
|
|
||||||
// Get AWS config
|
// Get AWS config
|
||||||
Object.values(deploy).forEach(target => {
|
Object.values(deploy).forEach(target => {
|
||||||
Object.assign(target, {
|
Object.assign(target, {
|
||||||
publisher: publish.create({
|
publisher: publish.create({
|
||||||
region: target.region,
|
region: target.region,
|
||||||
params: {
|
params: {
|
||||||
Bucket: target.bucket,
|
Bucket: target.bucket,
|
||||||
},
|
},
|
||||||
credentials: new aws.SharedIniFileCredentials({ profile: 'plyr' }),
|
credentials: new aws.SharedIniFileCredentials({ profile: 'plyr' }),
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Paths
|
// Paths
|
||||||
const root = path.join(__dirname, '..');
|
const root = path.join(__dirname, '..');
|
||||||
const paths = {
|
const paths = {
|
||||||
upload: [
|
upload: [
|
||||||
path.join(root, `dist/*${minSuffix}.*`),
|
path.join(root, `dist/*${minSuffix}.*`),
|
||||||
path.join(root, 'dist/*.css'),
|
path.join(root, 'dist/*.css'),
|
||||||
path.join(root, 'dist/*.svg'),
|
path.join(root, 'dist/*.svg'),
|
||||||
path.join(root, `demo/dist/*${minSuffix}.*`),
|
path.join(root, `demo/dist/*${minSuffix}.*`),
|
||||||
path.join(root, 'demo/dist/*.css'),
|
path.join(root, 'demo/dist/*.css'),
|
||||||
path.join(root, 'demo/dist/*.svg'),
|
path.join(root, 'demo/dist/*.svg'),
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
// Get credentials
|
// Get credentials
|
||||||
let credentials = {};
|
let credentials = {};
|
||||||
try {
|
try {
|
||||||
credentials = require('../credentials.json'); //eslint-disable-line
|
credentials = require('../credentials.json'); //eslint-disable-line
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// Do nothing
|
// Do nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get branch info
|
// Get branch info
|
||||||
const branch = {
|
const branch = {
|
||||||
current: gitbranch.sync(),
|
current: gitbranch.sync(),
|
||||||
master: 'master',
|
master: 'master',
|
||||||
beta: 'beta',
|
beta: 'beta',
|
||||||
};
|
};
|
||||||
|
|
||||||
const maxAge = 31536000; // 1 year
|
const maxAge = 31536000; // 1 year
|
||||||
const options = {
|
const options = {
|
||||||
cdn: {
|
cdn: {
|
||||||
headers: {
|
headers: {
|
||||||
'Cache-Control': `max-age=${maxAge}, immutable`,
|
'Cache-Control': `max-age=${maxAge}, immutable`,
|
||||||
},
|
|
||||||
},
|
},
|
||||||
demo: {
|
},
|
||||||
uploadPath: branch.current === branch.beta ? '/beta' : null,
|
demo: {
|
||||||
headers: {
|
uploadPath: branch.current === branch.beta ? '/beta' : null,
|
||||||
'Cache-Control': 'no-cache, no-store, must-revalidate, max-age=0',
|
headers: {
|
||||||
},
|
'Cache-Control': 'no-cache, no-store, must-revalidate, max-age=0',
|
||||||
},
|
|
||||||
symlinks(ver, filename) {
|
|
||||||
return {
|
|
||||||
headers: {
|
|
||||||
// http://stackoverflow.com/questions/2272835/amazon-s3-object-redirect
|
|
||||||
'x-amz-website-redirect-location': `/${ver}/${filename}`,
|
|
||||||
'Cache-Control': 'no-cache, no-store, must-revalidate, max-age=0',
|
|
||||||
},
|
|
||||||
};
|
|
||||||
},
|
},
|
||||||
|
},
|
||||||
|
symlinks(ver, filename) {
|
||||||
|
return {
|
||||||
|
headers: {
|
||||||
|
// http://stackoverflow.com/questions/2272835/amazon-s3-object-redirect
|
||||||
|
'x-amz-website-redirect-location': `/${ver}/${filename}`,
|
||||||
|
'Cache-Control': 'no-cache, no-store, must-revalidate, max-age=0',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
// Size plugin
|
// Size plugin
|
||||||
const sizeOptions = { showFiles: true, gzip: true };
|
const sizeOptions = { showFiles: true, gzip: true };
|
||||||
|
|
||||||
const regex =
|
const regex =
|
||||||
'(?:0|[1-9][0-9]*)\\.(?:0|[1-9][0-9]*).(?:0|[1-9][0-9]*)(?:-[\\da-z\\-]+(?:.[\\da-z\\-]+)*)?(?:\\+[\\da-z\\-]+(?:.[\\da-z\\-]+)*)?';
|
'(?:0|[1-9][0-9]*)\\.(?:0|[1-9][0-9]*).(?:0|[1-9][0-9]*)(?:-[\\da-z\\-]+(?:.[\\da-z\\-]+)*)?(?:\\+[\\da-z\\-]+(?:.[\\da-z\\-]+)*)?';
|
||||||
const semver = new RegExp(`v${regex}`, 'gi');
|
const semver = new RegExp(`v${regex}`, 'gi');
|
||||||
const localPath = new RegExp('(../)?dist', 'gi');
|
const localPath = new RegExp('(../)?dist', 'gi');
|
||||||
const versionPath = `https://${deploy.cdn.domain}/${version}`;
|
const versionPath = `https://${deploy.cdn.domain}/${version}`;
|
||||||
const cdnpath = new RegExp(`${deploy.cdn.domain}/${regex}/`, 'gi');
|
const cdnpath = new RegExp(`${deploy.cdn.domain}/${regex}/`, 'gi');
|
||||||
|
|
||||||
const renameFile = rename(p => {
|
const renameFile = rename(p => {
|
||||||
p.basename = p.basename.replace(minSuffix, ''); // eslint-disable-line
|
p.basename = p.basename.replace(minSuffix, ''); // eslint-disable-line
|
||||||
p.dirname = p.dirname.replace('.', version); // eslint-disable-line
|
p.dirname = p.dirname.replace('.', version); // eslint-disable-line
|
||||||
});
|
});
|
||||||
|
|
||||||
// Check we're on the correct branch to deploy
|
// Check we're on the correct branch to deploy
|
||||||
const canDeploy = () => {
|
const canDeploy = () => {
|
||||||
const allowed = [branch.master, branch.beta];
|
const allowed = [branch.master, branch.beta];
|
||||||
|
|
||||||
if (!allowed.includes(branch.current)) {
|
if (!allowed.includes(branch.current)) {
|
||||||
console.error(`Must be on ${allowed.join(', ')} to publish! (current: ${branch.current})`);
|
console.error(`Must be on ${allowed.join(', ')} to publish! (current: ${branch.current})`);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
gulp.task('version', done => {
|
gulp.task('version', done => {
|
||||||
if (!canDeploy()) {
|
if (!canDeploy()) {
|
||||||
done();
|
done();
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { domain } = deploy.cdn;
|
const { domain } = deploy.cdn;
|
||||||
|
|
||||||
log(`Uploading ${ansi.green.bold(version)} to ${ansi.cyan(domain)}...`);
|
log(`Uploading ${ansi.green.bold(version)} to ${ansi.cyan(domain)}...`);
|
||||||
|
|
||||||
// Replace versioned URLs in source
|
// Replace versioned URLs in source
|
||||||
const files = ['plyr.js', 'plyr.polyfilled.js', 'config/defaults.js'];
|
const files = ['plyr.js', 'plyr.polyfilled.js', 'config/defaults.js'];
|
||||||
|
|
||||||
return gulp
|
return gulp
|
||||||
.src(
|
.src(
|
||||||
files.map(file => path.join(__dirname, `src/js/${file}`)),
|
files.map(file => path.join(__dirname, `src/js/${file}`)),
|
||||||
{ base: '.' },
|
{ base: '.' },
|
||||||
)
|
)
|
||||||
.pipe(replace(semver, `v${version}`))
|
.pipe(replace(semver, `v${version}`))
|
||||||
.pipe(replace(cdnpath, `${domain}/${version}/`))
|
.pipe(replace(cdnpath, `${domain}/${version}/`))
|
||||||
.pipe(gulp.dest('./'));
|
.pipe(gulp.dest('./'));
|
||||||
});
|
});
|
||||||
|
|
||||||
// Publish version to CDN bucket
|
// Publish version to CDN bucket
|
||||||
gulp.task('cdn', done => {
|
gulp.task('cdn', done => {
|
||||||
if (!canDeploy()) {
|
if (!canDeploy()) {
|
||||||
done();
|
done();
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { domain, publisher } = deploy.cdn;
|
const { domain, publisher } = deploy.cdn;
|
||||||
|
|
||||||
if (!publisher) {
|
if (!publisher) {
|
||||||
throw new Error('No publisher instance. Check AWS configuration.');
|
throw new Error('No publisher instance. Check AWS configuration.');
|
||||||
}
|
}
|
||||||
|
|
||||||
log(`Uploading ${ansi.green.bold(pkg.version)} to ${ansi.cyan(domain)}...`);
|
log(`Uploading ${ansi.green.bold(pkg.version)} to ${ansi.cyan(domain)}...`);
|
||||||
|
|
||||||
// Upload to CDN
|
// Upload to CDN
|
||||||
return (
|
return (
|
||||||
gulp
|
gulp
|
||||||
.src(paths.upload)
|
.src(paths.upload)
|
||||||
.pipe(renameFile)
|
.pipe(renameFile)
|
||||||
// Remove min suffix from source map URL
|
// Remove min suffix from source map URL
|
||||||
.pipe(
|
.pipe(
|
||||||
replace(
|
replace(
|
||||||
/sourceMappingURL=([\w-?.]+)/,
|
/sourceMappingURL=([\w-?.]+)/,
|
||||||
(match, filename) => `sourceMappingURL=${filename.replace(minSuffix, '')}`,
|
(match, filename) => `sourceMappingURL=${filename.replace(minSuffix, '')}`,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.pipe(size(sizeOptions))
|
.pipe(size(sizeOptions))
|
||||||
.pipe(replace(localPath, versionPath))
|
.pipe(replace(localPath, versionPath))
|
||||||
.pipe(publisher.publish(options.cdn.headers))
|
.pipe(publisher.publish(options.cdn.headers))
|
||||||
.pipe(publish.reporter())
|
.pipe(publish.reporter())
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Purge the fastly cache incase any 403/404 are cached
|
// Purge the fastly cache incase any 403/404 are cached
|
||||||
gulp.task('purge', () => {
|
gulp.task('purge', () => {
|
||||||
if (!Object.keys(credentials).includes('fastly')) {
|
if (!Object.keys(credentials).includes('fastly')) {
|
||||||
throw new Error('Fastly credentials required to purge cache.');
|
throw new Error('Fastly credentials required to purge cache.');
|
||||||
}
|
}
|
||||||
|
|
||||||
const { fastly } = credentials;
|
const { fastly } = credentials;
|
||||||
const list = [];
|
const list = [];
|
||||||
|
|
||||||
return gulp
|
return gulp
|
||||||
.src(paths.upload)
|
.src(paths.upload)
|
||||||
.pipe(
|
.pipe(
|
||||||
through.obj((file, enc, cb) => {
|
through.obj((file, enc, cb) => {
|
||||||
const filename = file.path.split('/').pop();
|
const filename = file.path.split('/').pop();
|
||||||
list.push(`${versionPath}/${filename.replace(minSuffix, '')}`);
|
list.push(`${versionPath}/${filename.replace(minSuffix, '')}`);
|
||||||
cb(null);
|
cb(null);
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.on('end', () => {
|
.on('end', () => {
|
||||||
const purge = new FastlyPurge(fastly.token);
|
const purge = new FastlyPurge(fastly.token);
|
||||||
|
|
||||||
list.forEach(url => {
|
list.forEach(url => {
|
||||||
log(`Purging ${ansi.cyan(url)}...`);
|
log(`Purging ${ansi.cyan(url)}...`);
|
||||||
|
|
||||||
purge.url(url, (error, result) => {
|
purge.url(url, (error, result) => {
|
||||||
if (error) {
|
if (error) {
|
||||||
log.error(error);
|
log.error(error);
|
||||||
} else if (result) {
|
} else if (result) {
|
||||||
log(result);
|
log(result);
|
||||||
}
|
}
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Publish to demo bucket
|
// Publish to demo bucket
|
||||||
gulp.task('demo', done => {
|
gulp.task('demo', done => {
|
||||||
if (!canDeploy()) {
|
if (!canDeploy()) {
|
||||||
done();
|
done();
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { publisher } = deploy.demo;
|
const { publisher } = deploy.demo;
|
||||||
const { domain } = deploy.cdn;
|
const { domain } = deploy.cdn;
|
||||||
|
|
||||||
if (!publisher) {
|
if (!publisher) {
|
||||||
throw new Error('No publisher instance. Check AWS configuration.');
|
throw new Error('No publisher instance. Check AWS configuration.');
|
||||||
}
|
}
|
||||||
|
|
||||||
log(`Uploading ${ansi.green.bold(pkg.version)} to ${ansi.cyan(domain)}...`);
|
log(`Uploading ${ansi.green.bold(pkg.version)} to ${ansi.cyan(domain)}...`);
|
||||||
|
|
||||||
// Replace versioned files in readme.md
|
// Replace versioned files in README.md
|
||||||
gulp.src([`${__dirname}/readme.md`])
|
gulp
|
||||||
.pipe(replace(cdnpath, `${domain}/${version}/`))
|
.src([`${__dirname}/README.md`])
|
||||||
.pipe(gulp.dest(__dirname));
|
.pipe(replace(cdnpath, `${domain}/${version}/`))
|
||||||
|
.pipe(gulp.dest(__dirname));
|
||||||
|
|
||||||
// Replace local file paths with remote paths in demo HTML
|
// Replace local file paths with remote paths in demo HTML
|
||||||
// e.g. "../dist/plyr.js" to "https://cdn.plyr.io/x.x.x/plyr.js"
|
// e.g. "../dist/plyr.js" to "https://cdn.plyr.io/x.x.x/plyr.js"
|
||||||
const index = `${paths.demo.root}index.html`;
|
const index = `${paths.demo.root}index.html`;
|
||||||
const error = `${paths.demo.root}error.html`;
|
const error = `${paths.demo.root}error.html`;
|
||||||
const pages = [index];
|
const pages = [index];
|
||||||
|
|
||||||
if (branch.current === branch.master) {
|
if (branch.current === branch.master) {
|
||||||
pages.push(error);
|
pages.push(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
return gulp
|
return gulp
|
||||||
.src(pages)
|
.src(pages)
|
||||||
.pipe(replace(localPath, versionPath))
|
.pipe(replace(localPath, versionPath))
|
||||||
.pipe(
|
.pipe(
|
||||||
rename(p => {
|
rename(p => {
|
||||||
if (options.demo.uploadPath) {
|
if (options.demo.uploadPath) {
|
||||||
// eslint-disable-next-line no-param-reassign
|
// eslint-disable-next-line no-param-reassign
|
||||||
p.dirname += options.demo.uploadPath;
|
p.dirname += options.demo.uploadPath;
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.pipe(publisher.publish(options.demo.headers))
|
.pipe(publisher.publish(options.demo.headers))
|
||||||
.pipe(publish.reporter());
|
.pipe(publish.reporter());
|
||||||
});
|
});
|
||||||
|
|
||||||
// Open the demo site to check it's ok
|
// Open the demo site to check it's ok
|
||||||
gulp.task('open', () => {
|
gulp.task('open', () => {
|
||||||
const { domain } = deploy.demo;
|
const { domain } = deploy.demo;
|
||||||
|
|
||||||
return gulp.src(__filename).pipe(
|
return gulp.src(__filename).pipe(
|
||||||
open({
|
open({
|
||||||
uri: `https://${domain}/${branch.current === branch.beta ? 'beta' : ''}`,
|
uri: `https://${domain}/${branch.current === branch.beta ? 'beta' : ''}`,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Do everything
|
// Do everything
|
||||||
|
Loading…
x
Reference in New Issue
Block a user