Compare commits
708 Commits
Author | SHA1 | Date | |
---|---|---|---|
8584f6a1db | |||
08df96a149 | |||
cc3c0b5448 | |||
3c9c1b4cdc | |||
599883e684 | |||
f1b4db4f36 | |||
d4abb4b143 | |||
828ce66942 | |||
ccc2608cf6 | |||
de45de0e0b | |||
99c10aa1fc | |||
2a186e425b | |||
64bb206d85 | |||
2d6732d580 | |||
8f359adf9c | |||
1f09493ba2 | |||
115f352ade | |||
2af60c5c0d | |||
aab2817ddc | |||
f1c4752036 | |||
88735e3146 | |||
c373ed72d7 | |||
213cfe8c84 | |||
87ea5e14b4 | |||
2aa967aba9 | |||
d522e40594 | |||
3cd2b9a6c3 | |||
19e412a73a | |||
cf5f77c709 | |||
4811e3333f | |||
8257857075 | |||
e3e4e60fdb | |||
6ce9a94932 | |||
fa5d0ad316 | |||
6bff6b317d | |||
99ac8d4c52 | |||
019e1f80ca | |||
2fe98f3721 | |||
5c08363400 | |||
927326f715 | |||
53933dff7e | |||
f15c1344b0 | |||
fb48b330cc | |||
5dddf8b0ec | |||
0ecf7e3854 | |||
aae1092bac | |||
7158e507ad | |||
70f3390ffe | |||
392dfd024c | |||
87170ab460 | |||
ee4c044d27 | |||
0b09b8ee6f | |||
db95b3234f | |||
6d2dad5810 | |||
81ee3f759c | |||
ed606c28ab | |||
f15e07f7f5 | |||
cd14c3086d | |||
41184b82ee | |||
6a6f3914c0 | |||
840e31a693 | |||
1bc452c349 | |||
3fad6ed42c | |||
38f954ef17 | |||
abd1182303 | |||
efe70ab48e | |||
62c263bda3 | |||
4c1337b4c5 | |||
38f10d4cc6 | |||
1ad76800b0 | |||
cc97d7be6a | |||
f951cb372c | |||
37a3ab202a | |||
b148adc0af | |||
16828e975a | |||
7d26f41d64 | |||
f37f465ce4 | |||
b199215525 | |||
94699f3255 | |||
d3e98eb27e | |||
41012a9843 | |||
c83487a293 | |||
1fab4919c0 | |||
9dc0f28800 | |||
b57784d1a5 | |||
a80b31bf98 | |||
7c6d4666e9 | |||
76bb299c68 | |||
0c03accd41 | |||
b12eeb0eb7 | |||
8e634862ff | |||
1e1874d86b | |||
16624b90d3 | |||
ed14b656a8 | |||
1d0cf16254 | |||
84424f7f67 | |||
c95d9923f7 | |||
05b85da3f4 | |||
a4caba120c | |||
969a877a34 | |||
fb22a90d33 | |||
108bd3dfa0 | |||
5a445ae647 | |||
56668f58b6 | |||
eec96e5879 | |||
c6c9d877e4 | |||
61f4b998e1 | |||
25a319d884 | |||
4bf678fe6c | |||
359acd6bb9 | |||
2fce385691 | |||
a82c61c539 | |||
a8fa125a96 | |||
6435ced707 | |||
94dc0d176c | |||
23c21252e8 | |||
41c7dff0e8 | |||
e3bae562fc | |||
1c1668bfc3 | |||
e0c09c51f2 | |||
8de06fb862 | |||
64412868d8 | |||
450958c290 | |||
963fe11ad6 | |||
ce199e4b6b | |||
9d798893b5 | |||
64399e0717 | |||
f58e23b325 | |||
812e07b734 | |||
c9298fde76 | |||
0109454a34 | |||
813f703211 | |||
7aad747c25 | |||
d70a787af1 | |||
69bb0917ad | |||
90c5735904 | |||
6f256d09b2 | |||
e9684c2021 | |||
bf91a0e73f | |||
14b6309aef | |||
6391ced99f | |||
fac8a185ba | |||
c69aa8a42b | |||
f34bf22125 | |||
f0be913dc3 | |||
cd51788b98 | |||
edd67b0da3 | |||
d733454d7f | |||
41f9a87e0e | |||
f4858f0c62 | |||
121093ae71 | |||
aa8fc313a9 | |||
723298a07b | |||
f8c89e3e95 | |||
333435a9c2 | |||
3ab2295fe7 | |||
c41bb657ac | |||
55bbf64f2b | |||
3bba65f2c2 | |||
1bab0d07b5 | |||
602353f4d9 | |||
51814249af | |||
37c5fbfe16 | |||
d7356726a1 | |||
4db6bf7a2e | |||
28826f6402 | |||
c845558d96 | |||
16c3a7d9e5 | |||
90d5b48845 | |||
d1acc4abb3 | |||
797b70998f | |||
4a01027da0 | |||
7ca2169790 | |||
054f522aa9 | |||
f2fc3f5ea5 | |||
765c01e83d | |||
33a11fb53a | |||
d1d41ca49a | |||
c06e0ee5e9 | |||
83f80ccc40 | |||
069065ea3a | |||
1672e78041 | |||
34401de3d0 | |||
f687b81b70 | |||
bbb11e611e | |||
90919411e9 | |||
1491b017a0 | |||
1655150092 | |||
ceb6c9a100 | |||
00bbce08fb | |||
91a4b86860 | |||
5aece6fa06 | |||
a70b94afe2 | |||
9ebc2719d3 | |||
b46aae1833 | |||
30e6a40865 | |||
403df36af6 | |||
5ca769807e | |||
72a71a605b | |||
24d833a5d1 | |||
44b30380f7 | |||
261cd086c7 | |||
9e19b526b9 | |||
6c617a0ef1 | |||
a812650fea | |||
fec7a77d6f | |||
971e261067 | |||
27407ba021 | |||
ef8e58ede4 | |||
f13260c10a | |||
e1183d6049 | |||
f1b275aedc | |||
b647af256c | |||
d2e9ed3467 | |||
5b39986835 | |||
a97b08e8ea | |||
56d1be9447 | |||
a241cb5215 | |||
042b1a8294 | |||
6d79b8cd4c | |||
88d766aeae | |||
119b471b84 | |||
7f079e0ec3 | |||
46fe3eecff | |||
3061a701d5 | |||
e45109e1d7 | |||
e138e6d51e | |||
aef1363b04 | |||
766dd03d81 | |||
ab393651ec | |||
ffd265d0ae | |||
72155472dd | |||
9b7170834e | |||
3e57a87bf7 | |||
a15d1c9f1c | |||
a095a64f90 | |||
2374d6b1c4 | |||
5ed3ff9084 | |||
385be55510 | |||
3082d0d128 | |||
f7e242f054 | |||
2874505004 | |||
ed9e0c13d7 | |||
10be94fa99 | |||
ee79c46145 | |||
384010a2c0 | |||
1e47019122 | |||
536c65e82c | |||
cdf14932ec | |||
3b20dbd9fd | |||
e4d975af00 | |||
2782a00e7c | |||
91d192dd7c | |||
b1e3abc795 | |||
3395e8df90 | |||
cce143a7da | |||
d593005b32 | |||
7be9d5d4d3 | |||
d7141d5ed7 | |||
0d0ece94d3 | |||
1c06f6d06d | |||
dda8e30b92 | |||
c4e2e24643 | |||
e020a105a3 | |||
2b7fe9a4f9 | |||
951df64b7f | |||
0976afe282 | |||
7b1e4abda7 | |||
0cf75eed3f | |||
d96957d086 | |||
1a032ea498 | |||
5d079da1b8 | |||
9c1bc6ab08 | |||
3d2ba8c009 | |||
e872ce3f77 | |||
b77756da04 | |||
9b23e13ce8 | |||
5eafe9baff | |||
c251c94131 | |||
17041efc71 | |||
05b8e8a6e0 | |||
f998b996fa | |||
958b47c435 | |||
a27248d3b6 | |||
1b1f7be7ff | |||
59d4a27240 | |||
75e9f3c2e3 | |||
7132eccf50 | |||
e953c6398c | |||
bb7eea27e5 | |||
595c5e95bc | |||
43e6dcd41d | |||
b06c8ae43f | |||
c7ea13c0c7 | |||
0f8c6e147b | |||
e566365288 | |||
a06e0f5890 | |||
3bccc0da01 | |||
a0173d991e | |||
600f0eb8a3 | |||
5db73b1327 | |||
5cb1628cd8 | |||
c74b75e8e1 | |||
0538476d6f | |||
5ebe18d081 | |||
207adde36d | |||
1b13ddaa54 | |||
9981c349be | |||
b3365a7373 | |||
9a0c1c830d | |||
ef27ba16f4 | |||
e206edc1f6 | |||
c734bc4957 | |||
572b8a7aca | |||
eebae4a227 | |||
e0562752ea | |||
6a2ca534d2 | |||
7adc2bc6c8 | |||
ba8d7831a7 | |||
69ffcbad27 | |||
819f7d1080 | |||
409b588458 | |||
e90a603d57 | |||
6f061621ad | |||
0300610108 | |||
2fba5f152c | |||
317b08c703 | |||
e6db374a72 | |||
bfb550b8d0 | |||
174234c166 | |||
24b4220de5 | |||
f1895a4cce | |||
c2a6306d46 | |||
7ac732f45b | |||
c90f1bdf08 | |||
6a9be8d16b | |||
58c2c52c95 | |||
73a39769d4 | |||
7221e26eca | |||
98adb8e784 | |||
a59dcb2f53 | |||
d21b58e1c9 | |||
d6e84cbabb | |||
fcccf1d479 | |||
211db12a3d | |||
ab7f277a1b | |||
ce1d5a60d6 | |||
f67315e20c | |||
2150c44036 | |||
70c9fbdde3 | |||
f3ea31c515 | |||
1ee88cba16 | |||
af3ae75229 | |||
d76ef3ff91 | |||
2691c7c9d6 | |||
26b1d8ce8f | |||
6fae148fc1 | |||
bb51647fe2 | |||
71efbe7a92 | |||
afd695cb39 | |||
c4eb4c97ac | |||
d5a1a7ca1c | |||
8f7a8940f3 | |||
5e68f8c8dd | |||
b4e22e2e7b | |||
d4234da9aa | |||
1f53b27d4e | |||
cc128e6088 | |||
3c8acb4e9e | |||
ebf53d14b1 | |||
b298587c0b | |||
26e9aaceb8 | |||
384f3d6eda | |||
3aa5747c90 | |||
5671235fd9 | |||
1dd5c9efd9 | |||
5fad152cbf | |||
f33ca846f2 | |||
986c802acd | |||
98dd818bf6 | |||
021f6c8460 | |||
392f837398 | |||
6831c30534 | |||
ed6048034b | |||
8af312fe3c | |||
d87ada4f58 | |||
31c8166562 | |||
0cb2f95888 | |||
896ea7c689 | |||
1d1eb02bd7 | |||
3583165b30 | |||
d822f0c6bf | |||
9e52296dc6 | |||
12a7a4142c | |||
8348f79742 | |||
ec73d34bd3 | |||
1cef48d4f8 | |||
c24c05226d | |||
4b0005c28e | |||
8064405dbc | |||
22e8892993 | |||
cfc86bcb7c | |||
5f96ec6ac2 | |||
bbdf225d7b | |||
025fc1090b | |||
d9ec1d1b8e | |||
2e5d06ad85 | |||
bacd049eb0 | |||
6fd7b26bb2 | |||
1df79cf7f8 | |||
e6badacf0d | |||
a0d9d5eca8 | |||
8786377a75 | |||
f0322e8d94 | |||
3f2ac3fca0 | |||
9872207e87 | |||
58d942e737 | |||
dd190155c4 | |||
ebb3b83b27 | |||
79a43120ae | |||
2b36ab7ef5 | |||
eb38e0394d | |||
b79ffacd9c | |||
e14e2cfaff | |||
04119b27e6 | |||
92cb9e22e2 | |||
888c6773d0 | |||
cfd653f02a | |||
6b9106ddb1 | |||
838bd49a1d | |||
800e0dedfb | |||
965fc0b2f5 | |||
98ac98b4c2 | |||
178b0d8020 | |||
3bd1c1ff56 | |||
7d4bf91a35 | |||
ac3d1d1242 | |||
742018a716 | |||
a2ef691b4b | |||
9e0c406a4a | |||
f3df7aba15 | |||
6bc3592381 | |||
6864149989 | |||
aab53fa91f | |||
423f67b4f4 | |||
82f81f4f73 | |||
c8990bd379 | |||
e6cc4ba1f5 | |||
de54929bb7 | |||
fd77831303 | |||
cda574e627 | |||
fda1977119 | |||
f7bf0961cf | |||
61325bbad1 | |||
921cefd212 | |||
de6f0f1b77 | |||
7382553a78 | |||
4b82e89845 | |||
d3b31e595a | |||
f33bc5a5c6 | |||
f518ec108b | |||
edfc6cd475 | |||
92cd67effb | |||
da1e987444 | |||
2d4a166218 | |||
feae00224e | |||
000afdd300 | |||
0dc9681ae8 | |||
dc391c98c6 | |||
4b62a5c74d | |||
3f744ef63a | |||
5a244b7fed | |||
4dca4bf93c | |||
6984d6fb16 | |||
d7a1c44281 | |||
c64b8f6940 | |||
9c4b53d761 | |||
022b436c3f | |||
6058bb0245 | |||
3ade86537d | |||
d80be3b903 | |||
1a26681d87 | |||
9171297764 | |||
ebd1a52e5d | |||
743c84188e | |||
4879bea4a0 | |||
66917fd39b | |||
fd97607e55 | |||
f878581c8f | |||
f9602acf61 | |||
86a5724bdb | |||
63c963d726 | |||
88bfa35b99 | |||
bb66be98da | |||
c948e95ade | |||
1a5f4b1b9e | |||
3f41a0cf54 | |||
966ca1acc3 | |||
e2c7491ccd | |||
0ec0addbda | |||
fae4ca12e0 | |||
84505da84b | |||
2497e25b3c | |||
9c4b7e7094 | |||
3a9beaed59 | |||
1578525ee3 | |||
62c1b368cf | |||
f8ecea8fb7 | |||
0068710740 | |||
d206b8ab34 | |||
51c011b733 | |||
5fe477340b | |||
45df319823 | |||
6bebbe4153 | |||
374de800a4 | |||
60084a17f8 | |||
4d417d0396 | |||
e2d8bd2b73 | |||
1c693df00b | |||
8aaa932050 | |||
3cd6c2acf6 | |||
3930ebb339 | |||
b102714067 | |||
13d3037a53 | |||
1e7a60ee5c | |||
8d80f6b05d | |||
597b3fe0db | |||
d920de2a25 | |||
069c8093ae | |||
1cc2930dc0 | |||
3d50936b47 | |||
dd9d5c8898 | |||
e06b689f5c | |||
71db66d802 | |||
959b5a20e3 | |||
9de5c0cf39 | |||
1a3868a6c6 | |||
378aa159b8 | |||
6876a9163d | |||
34d28a69ad | |||
0715d3ae67 | |||
542095f5eb | |||
57517a9dcc | |||
751708ff23 | |||
fcf944788a | |||
36a84c5c2d | |||
4392abfc49 | |||
3238b6a36a | |||
18a5edef0e | |||
02cb093f7b | |||
d6977473b1 | |||
15cffad89e | |||
0d96601d1a | |||
7959297a98 | |||
6dd010ea34 | |||
f89ddb2f1b | |||
2e5cc272e3 | |||
ebd13c63e8 | |||
ec091266aa | |||
ad105877ed | |||
c84f666b55 | |||
2bba1f30e2 | |||
2196665495 | |||
0148c76c30 | |||
18b2cbb2e9 | |||
f6a7555a1d | |||
f7144dc0cb | |||
a9957211f4 | |||
7b60e473fa | |||
dfc516baf6 | |||
b0d3bcd15a | |||
03c3960e93 | |||
21f444ed61 | |||
40b4f8e840 | |||
bc61dac4c5 | |||
3605989226 | |||
a49d77afab | |||
7daa08c32f | |||
aaab9ad082 | |||
86c9004183 | |||
857dfe838c | |||
e1a19faf26 | |||
f3bda17fa0 | |||
966c3d875d | |||
fe9383bed5 | |||
2c31770030 | |||
8d3e160166 | |||
408cfe5b97 | |||
279fee3595 | |||
28dddfcff2 | |||
9e2580ec6a | |||
aba5a9dc0e | |||
9999828505 | |||
b04301c211 | |||
97157efcfa | |||
3756476809 | |||
b3d798eeee | |||
b499622eb8 | |||
04b8d0bac8 | |||
8ea4cbd942 | |||
7889ae1126 | |||
897d49ad87 | |||
1960d35d8b | |||
0b7d0dedf6 | |||
948e2cc66c | |||
396b816a1f | |||
0a58cbfd59 | |||
bbe4b7e565 | |||
2ecca2cbe3 | |||
f5d80fa888 | |||
f2bbe4eb12 | |||
60e51b7077 | |||
01d1ac9ab9 | |||
9b2396f5ff | |||
da15980b8a | |||
452678867f | |||
ff2d27f8e5 | |||
546cdaad92 | |||
5d38497f07 | |||
808a3af3cf | |||
889712761a | |||
46fab972a0 | |||
535c046b62 | |||
55dfab8394 | |||
18bf4d84b9 | |||
ef1d73df15 | |||
684107da5c | |||
2a97a9a9c5 | |||
ca12343b16 | |||
a974fbf31c | |||
6eaf33ec6c | |||
33fef7faee | |||
b083bf4297 | |||
ebc7ed538a | |||
a60868bfe8 | |||
4a2866d05f | |||
1a05f352c7 | |||
ba27de0669 | |||
e21e7054ce | |||
bc323e905c | |||
afa1fe9d5f | |||
2444efc834 | |||
7b6257ff20 | |||
13973125fb | |||
ddf9104349 | |||
47b53fffb4 | |||
9ba3753f80 | |||
a353194fe1 | |||
c205c47509 | |||
9c867edfbc | |||
9919d80782 | |||
8464ffe6ad | |||
6537225c61 | |||
dcbf59bd89 | |||
21d478d396 | |||
054c243416 | |||
d57e453541 | |||
3f45ef4908 | |||
1fd742464d | |||
9c599884a8 | |||
cbef45841c | |||
96d9f302c2 | |||
afcdf17a72 | |||
1bcdbe4c00 | |||
45c0ded88c | |||
ea30ad9494 | |||
7608615702 | |||
cc5f37392f | |||
413fcbcb8c | |||
c49d0a99e4 | |||
5a0cb9289c | |||
bce1d983cb | |||
047fc43f8f | |||
0cbfc9252c | |||
d02e57bdb3 | |||
663c1fb627 | |||
a7969b8e9e | |||
4ca3f030cc | |||
02bc8c8445 | |||
7965b82cca | |||
bae04a492a | |||
72404e77e5 | |||
c7310c21fb | |||
ed9e27b64f | |||
801ed63be5 | |||
2aa9b267ab | |||
90338d9600 | |||
5cecf16d4f | |||
21a30f1b6f | |||
613c45ede9 | |||
8743c6a08d | |||
eba0831538 | |||
1ad103c29f | |||
ca37b4c9ac | |||
d3bbf09d12 | |||
f608317eec | |||
c8b9c9bcaa | |||
d638cdcdd3 | |||
46f82a4af3 | |||
42a2642d40 | |||
37840c3844 | |||
28335ef3d8 | |||
78ec5b3322 | |||
ac7e1ab299 | |||
ea60fd0f45 | |||
c291e8c5d9 | |||
f0ac542a7f | |||
a412085785 |
10
.editorconfig
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
# See editorconfig.org
|
||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
charset = utf-8
|
||||||
|
end_of_line = lf
|
||||||
|
indent_size = 4
|
||||||
|
indent_style = space
|
||||||
|
insert_final_newline = true
|
||||||
|
trim_trailing_whitespace = true
|
40
.eslintrc.json
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
{
|
||||||
|
"parser": "babel-eslint",
|
||||||
|
"extends": ["airbnb-base", "prettier"],
|
||||||
|
"env": {
|
||||||
|
"browser": true,
|
||||||
|
"es6": true
|
||||||
|
},
|
||||||
|
"globals": { "Plyr": false, "jQuery": false },
|
||||||
|
"rules": {
|
||||||
|
"no-const-assign": 1,
|
||||||
|
"no-shadow": 0,
|
||||||
|
"no-this-before-super": 1,
|
||||||
|
"no-undef": 1,
|
||||||
|
"no-unreachable": 1,
|
||||||
|
"no-unused-vars": 1,
|
||||||
|
"constructor-super": 1,
|
||||||
|
"valid-typeof": 1,
|
||||||
|
"indent": [2, 4, { "SwitchCase": 1 }],
|
||||||
|
"quotes": [2, "single", "avoid-escape"],
|
||||||
|
"semi": [2, "always"],
|
||||||
|
"eqeqeq": [2, "always"],
|
||||||
|
"one-var": [2, "never"],
|
||||||
|
"comma-dangle": [2, "always-multiline"],
|
||||||
|
"no-restricted-globals": [
|
||||||
|
"error",
|
||||||
|
{
|
||||||
|
"name": "event",
|
||||||
|
"message": "Use local parameter instead."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "error",
|
||||||
|
"message": "Use local parameter instead."
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"no-param-reassign": [2, { "props": false }]
|
||||||
|
},
|
||||||
|
"parserOptions": {
|
||||||
|
"sourceType": "module"
|
||||||
|
}
|
||||||
|
}
|
11
.github/issue_template.md
vendored
@ -2,9 +2,6 @@
|
|||||||
Please use this issue template as it makes replicating and fixing the issue easier!
|
Please use this issue template as it makes replicating and fixing the issue easier!
|
||||||
--->
|
--->
|
||||||
|
|
||||||
- [ ] Issue does not already exist
|
|
||||||
- [ ] Issue observed on https://plyr.io
|
|
||||||
|
|
||||||
### Expected behaviour
|
### Expected behaviour
|
||||||
|
|
||||||
### Actual behaviour
|
### Actual behaviour
|
||||||
@ -16,13 +13,5 @@ Please use this issue template as it makes replicating and fixing the issue easi
|
|||||||
- Operating System:
|
- Operating System:
|
||||||
- Version:
|
- Version:
|
||||||
|
|
||||||
Players affected:
|
|
||||||
- [ ] HTML5 Video
|
|
||||||
- [ ] HTML5 Audio
|
|
||||||
- [ ] YouTube
|
|
||||||
- [ ] Vimeo
|
|
||||||
|
|
||||||
### Steps to reproduce
|
### Steps to reproduce
|
||||||
-
|
-
|
||||||
|
|
||||||
### Relevant links
|
|
||||||
|
10
.github/pull_request_template.md
vendored
@ -1,8 +1,8 @@
|
|||||||
### Link to related issue (if applicable)
|
### Link to related issue (if applicable)
|
||||||
|
|
||||||
### Sumary of proposed changes
|
### Summary of proposed changes
|
||||||
|
|
||||||
### Task list
|
### Checklist
|
||||||
|
- [ ] Use `develop` as the base branch
|
||||||
- [ ] Tested on [supported browsers](https://github.com/sampotts/plyr#browser-support)
|
- [ ] Exclude the gulp build from the PR
|
||||||
- [ ] Gulp build completed
|
- [ ] Test on [supported browsers](https://github.com/sampotts/plyr#browser-support)
|
||||||
|
14
.gitignore
vendored
@ -1,11 +1,11 @@
|
|||||||
node_modules
|
node_modules
|
||||||
*.sublime-project
|
|
||||||
*.sublime-workspace
|
|
||||||
.DS_Store
|
.DS_Store
|
||||||
aws.json
|
aws.json
|
||||||
docs/index.dev.html
|
|
||||||
*.mp4
|
*.mp4
|
||||||
index-dev.html
|
!dist/blank.mp4
|
||||||
notes.txt
|
index-*.html
|
||||||
*.vtt
|
npm-debug.log
|
||||||
docs/index.dev.php
|
*.webm
|
||||||
|
/package-lock.json
|
||||||
|
.idea/
|
||||||
|
|
||||||
|
@ -1,11 +0,0 @@
|
|||||||
{
|
|
||||||
"html": {
|
|
||||||
"allowed_file_extensions": []
|
|
||||||
},
|
|
||||||
"css": {
|
|
||||||
"allowed_file_extensions": []
|
|
||||||
},
|
|
||||||
"js": {
|
|
||||||
"allowed_file_extensions": []
|
|
||||||
}
|
|
||||||
}
|
|
55
.jshintrc
@ -1,55 +0,0 @@
|
|||||||
{
|
|
||||||
// Settings
|
|
||||||
"passfail" : false, // Stop on first error.
|
|
||||||
"maxerr" : 100, // Maximum error before stopping.
|
|
||||||
|
|
||||||
// Predefined globals whom JSHint will ignore.
|
|
||||||
"browser" : true, // Standard browser globals e.g. `window`, `document`.
|
|
||||||
"node" : false,
|
|
||||||
"rhino" : false,
|
|
||||||
"couch" : false,
|
|
||||||
"wsh" : false, // Windows Scripting Host.
|
|
||||||
"jquery" : false,
|
|
||||||
|
|
||||||
// Development.
|
|
||||||
"debug" : true, // Allow debugger statements e.g. browser breakpoints.
|
|
||||||
"devel" : true, // Allow developments statements e.g. `console.log();`.
|
|
||||||
|
|
||||||
// ECMAScript 5.
|
|
||||||
"strict" : false, // Require `use strict` pragma in every file.
|
|
||||||
"globalstrict" : false, // Allow global "use strict" (also enables 'strict').
|
|
||||||
|
|
||||||
// The Good Parts.
|
|
||||||
"asi" : true, // Tolerate Automatic Semicolon Insertion (no semicolons).
|
|
||||||
"laxbreak" : true, // Tolerate unsafe line breaks e.g. `return [\n] x` without semicolons.
|
|
||||||
"bitwise" : false, // Prohibit bitwise operators (&, |, ^, etc.).
|
|
||||||
"boss" : false, // Tolerate assignments inside if, for & while. Usually conditions & loops are for comparison, not assignments.
|
|
||||||
"curly" : true, // Require {} for every new block or scope.
|
|
||||||
"eqeqeq" : true, // Require triple equals i.e. `===`.
|
|
||||||
"eqnull" : false, // Tolerate use of `== null`.
|
|
||||||
"evil" : false, // Tolerate use of `eval`.
|
|
||||||
"expr" : false, // Tolerate `ExpressionStatement` as Programs.
|
|
||||||
"forin" : false, // Tolerate `for in` loops without `hasOwnPrototype`.
|
|
||||||
"immed" : true, // Require immediate invocations to be wrapped in parens e.g. `( function(){}() );`
|
|
||||||
"latedef" : false, // Prohipit variable use before definition.
|
|
||||||
"loopfunc" : true, // Allow functions to be defined within loops.
|
|
||||||
"noarg" : true, // Prohibit use of `arguments.caller` and `arguments.callee`.
|
|
||||||
"regexp" : true, // Prohibit `.` and `[^...]` in regular expressions.
|
|
||||||
"regexdash" : false, // Tolerate unescaped last dash i.e. `[-...]`.
|
|
||||||
"scripturl" : true, // Tolerate script-targeted URLs.
|
|
||||||
"shadow" : false, // Allows re-define variables later in code e.g. `var x=1; x=2;`.
|
|
||||||
"supernew" : false, // Tolerate `new function () { ... };` and `new Object;`.
|
|
||||||
"undef" : true, // Require all non-global variables be declared before they are used.
|
|
||||||
|
|
||||||
// Personal styling preferences.
|
|
||||||
"newcap" : true, // Require capitalization of all constructor functions e.g. `new F()`.
|
|
||||||
"noempty" : true, // Prohibit use of empty blocks.
|
|
||||||
"nonew" : true, // Prohibit use of constructors for side-effects.
|
|
||||||
"nomen" : true, // Prohibit use of initial or trailing underbars in names.
|
|
||||||
"onevar" : false, // Allow only one `var` statement per function.
|
|
||||||
"plusplus" : false, // Prohibit use of `++` & `--`.
|
|
||||||
"sub" : false, // Tolerate all forms of subscript notation besides dot notation e.g. `dict['key']` instead of `dict.key`.
|
|
||||||
"trailing" : true, // Prohibit trailing whitespaces.
|
|
||||||
"white" : true, // Check against strict whitespace and indentation rules.
|
|
||||||
"indent" : 4 // Specify indentation spacing
|
|
||||||
}
|
|
4
.npmignore
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
demo
|
||||||
|
.github
|
||||||
|
.vscode
|
||||||
|
*.code-workspace
|
7
.prettierrc
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"useTabs": false,
|
||||||
|
"tabWidth": 4,
|
||||||
|
"printWidth": 120,
|
||||||
|
"singleQuote": true,
|
||||||
|
"trailingComma": "all"
|
||||||
|
}
|
25
.stylelintrc.json
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
{
|
||||||
|
"plugins": ["stylelint-selector-bem-pattern", "stylelint-scss"],
|
||||||
|
"extends": ["stylelint-config-recommended", "stylelint-config-sass-guidelines", "stylelint-config-prettier"],
|
||||||
|
"rules": {
|
||||||
|
"selector-class-pattern": null,
|
||||||
|
"selector-no-qualifying-type": [
|
||||||
|
true,
|
||||||
|
{
|
||||||
|
"ignore": ["attribute", "class"]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"string-no-newline": null,
|
||||||
|
"indentation": 4,
|
||||||
|
"string-quotes": "single",
|
||||||
|
"max-nesting-depth": 2,
|
||||||
|
"plugin/selector-bem-pattern": {
|
||||||
|
"preset": "bem",
|
||||||
|
"componentName": "(([a-z0-9]+(?!-$)-?)+)",
|
||||||
|
"componentSelectors": {
|
||||||
|
"initial": "\\.{componentName}(((__|--)(([a-z0-9\\[\\]'=]+(?!-$)-?)+))+)?$"
|
||||||
|
},
|
||||||
|
"ignoreSelectors": [".*\\.has-.*", ".*\\.is-.*"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
7
.travis.yml
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
language: node_js
|
||||||
|
node_js:
|
||||||
|
- 'lts/*'
|
||||||
|
|
||||||
|
script:
|
||||||
|
- npm run lint
|
||||||
|
- npm run build
|
12
.vscode/extensions.json
vendored
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
// See http://go.microsoft.com/fwlink/?LinkId=827846
|
||||||
|
// for the documentation about the extensions.json format
|
||||||
|
"recommendations": [
|
||||||
|
// Extension identifier format: ${publisher}.${name}. Example: vscode.csharp
|
||||||
|
"dbaeumer.vscode-eslint",
|
||||||
|
"wix.vscode-import-cost",
|
||||||
|
"esbenp.prettier-vscode",
|
||||||
|
"shinnn.stylelint",
|
||||||
|
"wayou.vscode-todo-highlight"
|
||||||
|
]
|
||||||
|
}
|
15
.vscode/launch.json
vendored
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
// Use IntelliSense to learn about possible attributes.
|
||||||
|
// Hover to view descriptions of existing attributes.
|
||||||
|
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"type": "chrome",
|
||||||
|
"request": "launch",
|
||||||
|
"name": "Launch Chrome against localhost",
|
||||||
|
"url": "http://localhost/dev/plyr/demo",
|
||||||
|
"webRoot": "${workspaceFolder}"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
3
.vscode/settings.json
vendored
@ -1,2 +1 @@
|
|||||||
{
|
{}
|
||||||
}
|
|
61
CONTRIBUTING.md
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
# Contributing
|
||||||
|
|
||||||
|
We welcome bug reports, feature requests and pull requests. If you want to help us out, please follow these guidelines, in order to avoid redundant work.
|
||||||
|
|
||||||
|
## Commenting
|
||||||
|
When commenting, keep a civil tone and stay on topic. Don't ask for support (use [Stack Overflow](https://stackoverflow.com/) or [our Slack](https://bit.ly/plyr-chat) for that), 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.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
## Reporting issues
|
||||||
|
|
||||||
|
Our GitHub issue tracker is for bug reports and feature requests. Don't ask for support here. Use [Stack Overflow](https://stackoverflow.com/) or [our Slack](https://bit.ly/plyr-chat) for that.
|
||||||
|
|
||||||
|
Please verify that your issue hasn't already been answered by our [FAQ](https://github.com/sampotts/plyr/wiki/FAQ), and that there isn't already an open issue for it.
|
||||||
|
|
||||||
|
When applicable, check that your problem doesn't happen without Plyr (see [FAQ#1](https://github.com/sampotts/plyr/wiki/FAQ#1-does-plyr-work-with--)).
|
||||||
|
|
||||||
|
Verify that you are following the documentation, are using the latest version of Plyr, and aren't getting any errors in your own code, causing the issues.
|
||||||
|
|
||||||
|
Create one issue per problem or request (i.e. don't combine multiple problems to one git issue). Describe the issue as detailed as possible (see [Replication](#replication))
|
||||||
|
|
||||||
|
## Replication
|
||||||
|
|
||||||
|
In order to solve a problem, we first need to understand it. Please answer these questions when reporting issues or asking for help in [our Slack](https://bit.ly/plyr-chat).
|
||||||
|
|
||||||
|
* Does it happen only with specific options and/or specific browsers?
|
||||||
|
* Does is happen only with HTML5 video, audio, YouTube, Vimeo or a specific library?
|
||||||
|
* Does the issue happen on [our demo](https://plyr.io/)? If not, please recreate it with a **minimal** example online. You can use our Codepen templates to get started:
|
||||||
|
* [HTML5 video](https://codepen.io/pen?template=bKeqpr)
|
||||||
|
* [HTML5 audio](https://codepen.io/pen?template=rKLywR)
|
||||||
|
* [YouTube](https://codepen.io/pen?template=GGqbbJ)
|
||||||
|
* [Vimeo](https://codepen.io/pen?template=bKeXNq)
|
||||||
|
* [Dash.js integration](https://codepen.io/pen?template=zaBgBy)
|
||||||
|
* [Hls.js integration](https://codepen.io/pen?template=oyLKQb)
|
||||||
|
* [Shaka Player integration](https://codepen.io/pen?template=ZRpzZO)
|
||||||
|
|
||||||
|
It's important that you keep the issue description and replication demo **minimal**. If your replication includes frameworks, libraries or customizations, this makes it harder to debug and understand the issue. While it may be relevant to bring this up (ex: "I need Plyr to trigger the event sooner or it breaks Framework X"), please keep these out of your replication demo if they aren't strictly needed to reproduce the issue. If the issue is caused by something a library does that Plyr doesn't handle, it's more helpful for us if you find out what it is, and replicate the same problem without the library. Otherwise any developer who is willing to help out with the issue has to understand the frameworks, libraries and customizations of *your* choice, or no one will try to fix your issue because it's too much work.
|
||||||
|
|
||||||
|
## Requesting features and improvements
|
||||||
|
|
||||||
|
If you are missing something in Plyr, you can create a GitHub issue for this as well. Since we prioritize fixing bugs first, and may have a lot of other suggestions and architectural changes to work on as well, these may not be at the top of our list.
|
||||||
|
|
||||||
|
If your suggestion is important or urgent to you, you may want to first ensure it's something we want to have in Plyr, and then contribute it as a pull request. [Our Slack](https://bit.ly/plyr-chat) is the best place for questions like this.
|
||||||
|
|
||||||
|
## Contributing features and documentation
|
||||||
|
|
||||||
|
* Fork Plyr, and create a new branch in your fork, based on the **develop** branch
|
||||||
|
|
||||||
|
* To test locally, you can use the demo. First make sure you have installed the dependencies with `npm install` or `yarn`. Run `gulp` to build while you are working, and run a local server from the repository root directory. If you have Python installed, this command should work: `python -m SimpleHTTPServer 8080`. Then go to `http://localhost:8080/demo/`
|
||||||
|
|
||||||
|
* 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.
|
||||||
|
|
||||||
|
* If your modifications changes the documented behavior or add new features, document these changes in readme.md.
|
||||||
|
|
||||||
|
* 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.
|
@ -6,7 +6,7 @@
|
|||||||
"Audio",
|
"Audio",
|
||||||
"Video",
|
"Video",
|
||||||
"HTML5 Audio",
|
"HTML5 Audio",
|
||||||
"HTml5 Video"
|
"HTML5 Video"
|
||||||
],
|
],
|
||||||
"authors": [
|
"authors": [
|
||||||
"Sam Potts <sam@potts.es>"
|
"Sam Potts <sam@potts.es>"
|
||||||
|
20
bundles.json
@ -1,24 +1,20 @@
|
|||||||
{
|
{
|
||||||
"plyr": {
|
"plyr": {
|
||||||
"less": {
|
"sass": {
|
||||||
"plyr.css": ["src/less/plyr.less"]
|
"plyr.css": "src/sass/plyr.scss"
|
||||||
},
|
|
||||||
"scss": {
|
|
||||||
"plyr.css": ["src/scss/plyr.scss"]
|
|
||||||
},
|
},
|
||||||
"js": {
|
"js": {
|
||||||
"plyr.js": ["src/js/plyr.js"]
|
"plyr.js": "src/js/plyr.js",
|
||||||
|
"plyr.polyfilled.js": "src/js/plyr.polyfilled.js"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"demo": {
|
"demo": {
|
||||||
"less": {
|
"sass": {
|
||||||
"demo.css": ["demo/src/less/demo.less"]
|
"demo.css": "demo/src/sass/bundles/demo.scss",
|
||||||
|
"error.css": "demo/src/sass/bundles/error.scss"
|
||||||
},
|
},
|
||||||
"js": {
|
"js": {
|
||||||
"demo.js": [
|
"demo.js": "demo/src/js/demo.js"
|
||||||
"demo/src/js/lib/classlist.js",
|
|
||||||
"demo/src/js/main.js"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
450
changelog.md
@ -1,6 +1,294 @@
|
|||||||
# Changelog
|
# v3.3.14
|
||||||
|
|
||||||
|
- Fix sprite loading regression
|
||||||
|
|
||||||
|
# v3.3.13
|
||||||
|
|
||||||
|
You guessed it, a load of awesome changes from contributors:
|
||||||
|
|
||||||
|
Thanks @friday for the following:
|
||||||
|
|
||||||
|
- Captions fixes
|
||||||
|
- Fix poster race conditions
|
||||||
|
- Minor code improvements for quality switching
|
||||||
|
- Minor event changes
|
||||||
|
- Fix condition in events.toggleListener to allow non-elements
|
||||||
|
- Suggestion: Remove array newline rule
|
||||||
|
- Contributions improvements
|
||||||
|
|
||||||
|
- fix: html5.cancelRequest not remove source tag correctly (thanks @a60814billy)
|
||||||
|
- remove event listeners in destroy() (thanks @cky917)
|
||||||
|
- Fix markdown in README (thanks @azu)
|
||||||
|
- Some parts of the accessibility improvements outlined in #905 (more on the way...)
|
||||||
|
- Fix for bug where volume slider didn't always show
|
||||||
|
|
||||||
|
# v3.3.12
|
||||||
|
|
||||||
|
- Fix synthetic event bubble/proxy loses detail (thanks @friday!)
|
||||||
|
- Make utils static (thanks @friday!)
|
||||||
|
- Fix for YouTube and Vimeo pausing after seek (thanks @friday!)
|
||||||
|
- Vimeo: Update playback state and assure events are triggered on load (thanks @friday!)
|
||||||
|
- Captions rewrite (use index internally to support missing or duplicate languages) (thanks @friday and @philipgiuliani!)
|
||||||
|
- Contributing document and codepen demo updates (thanks @friday!)
|
||||||
|
- Fix for after clicking on the progress bar, keyboard operations will not work (thanks @cky917!)
|
||||||
|
|
||||||
|
# v3.3.10
|
||||||
|
|
||||||
|
- Fix for buffer display alignment and incorrect BEM classname
|
||||||
|
- Fix for playback not resuming position after quality swap (fixes #991, thanks @philipgiuliani!)
|
||||||
|
- Travis integration (thanks @friday!)
|
||||||
|
- Translate quality badges and quality names (thanks @philipgiuliani!)
|
||||||
|
- Improve captions handling for streaming (thanks @friday!)
|
||||||
|
- Call duration update method manually if user config has duration (thanks @friday!)
|
||||||
|
|
||||||
|
# v3.3.9
|
||||||
|
|
||||||
|
Again, more changes from @friday!
|
||||||
|
|
||||||
|
- Restore window reference in `is.cue()`
|
||||||
|
- Fix InvalidStateError and IE11 issues
|
||||||
|
- Respect storage being disabled for storage getter
|
||||||
|
|
||||||
|
# v3.3.8
|
||||||
|
|
||||||
|
Many changes here thanks to @friday:
|
||||||
|
|
||||||
|
- Added missing URL polyfill
|
||||||
|
- Pause while seeking to mimic default HTML5 behaviour
|
||||||
|
- Add `seeked` event listener to update progress (fixes #966)
|
||||||
|
- Trigger seeked event in youtube plugin if either playing or paused (fixes #921)
|
||||||
|
- Fix for YouTube and Vimeo autoplays on seek (fixes #876)
|
||||||
|
- Toggle controls improvements
|
||||||
|
- Cleanup unused code
|
||||||
|
- Poster image loading improvements
|
||||||
|
- Fix for seek tooltip vs click accuracy
|
||||||
|
|
||||||
|
# v3.3.7
|
||||||
|
|
||||||
|
- Poster fixes (thanks @friday)
|
||||||
|
- Grid tweak
|
||||||
|
|
||||||
|
# v3.3.6
|
||||||
|
|
||||||
|
- Vimeo fixes for mute state
|
||||||
|
- Vimeo ID fix (fixes #945)
|
||||||
|
- Use `<div>` for poster container
|
||||||
|
- Tooltip fixes for unicode languages (fixes #943)
|
||||||
|
|
||||||
|
# v3.3.5
|
||||||
|
|
||||||
|
- Removed `.load()` call as it breaks HLS (see #870)
|
||||||
|
|
||||||
|
# v3.3.4
|
||||||
|
|
||||||
|
- Fix for controls sometimes not showing while video is playing
|
||||||
|
- Fixed logic for show home tab on option select
|
||||||
|
|
||||||
|
# v3.3.3
|
||||||
|
|
||||||
|
- Reverted change to show home tab on option select due to usability regression
|
||||||
|
|
||||||
|
# v3.3.2
|
||||||
|
|
||||||
|
- Fix for ads running in audio
|
||||||
|
- Fix for setting poster on source change
|
||||||
|
|
||||||
|
## v3.3.0
|
||||||
|
|
||||||
|
- Now using a custom poster image element to hide the YouTube play button and give more control over when the poster image shows
|
||||||
|
- Renamed `showPosterOnEnd` to `resetOnEnd` as it makes more sense and now works for all players and does not reload media
|
||||||
|
- Fix for same domain SVG URLs (raised by Jochem in Slack)
|
||||||
|
- [`URL`](https://developer.mozilla.org/en-US/docs/Web/API/Window/URL) is polyfill now required
|
||||||
|
- Added pause className (fixes #941)
|
||||||
|
- Button height set in CSS (auto) (fixes #928)
|
||||||
|
- Don't autoplay cloned original media (fixes #936)
|
||||||
|
- Return to the home menu pane after selecting an option
|
||||||
|
|
||||||
|
## v3.2.4
|
||||||
|
|
||||||
|
- Fix issue wher player never reports as ready if controls is empty array
|
||||||
|
- Fix issue where screen reader labels were removed from time displays
|
||||||
|
- Fix issue where custom controls placeholders were not populated
|
||||||
|
- Custom controls HTML example updated
|
||||||
|
- Fix for aria-label being set to the initial state on toggle buttons, overriding the inner labels
|
||||||
|
- Fix for hidden mute button on iOS (not functional for Vimeo due to API limitations) (fixes #656)
|
||||||
|
|
||||||
|
## v3.2.3
|
||||||
|
|
||||||
|
- Fix for iOS 9 throwing error for `name` property in fullscreen API (fixes #908)
|
||||||
|
|
||||||
|
## v3.2.2
|
||||||
|
|
||||||
|
- Fix for regression in 3.2.1 resulting in hidden buffer display (fixes #920)
|
||||||
|
- Cleaned up incorrect use of `aria-hidden` attribute
|
||||||
|
|
||||||
|
## v3.2.1
|
||||||
|
|
||||||
|
- Accessibility improvements for the controls (part of #905 fixes)
|
||||||
|
- Fix for context menu showing on YouTube (thanks Anthony Recenello in Slack)
|
||||||
|
- Vimeo fix for their API not returning the right duration until playback begins (fixes #891)
|
||||||
|
|
||||||
|
## v3.2.0
|
||||||
|
|
||||||
|
- Fullscreen fixes (thanks @friday)
|
||||||
|
- Menu fix for if speed not in config
|
||||||
|
- Menu z-index fix (thanks @danielsarin)
|
||||||
|
- i18n fix for missing "Normal" string (thanks @danielsarin)
|
||||||
|
- Safer check for active caption (thanks @Antonio-Laguna)
|
||||||
|
- Add custom property fallback (thanks @friday)
|
||||||
|
- Fixed bug for captions with no srclang and labels and improved logic (fixes #875)
|
||||||
|
- Fix for `playing` false positive (fixes #898)
|
||||||
|
- Fix for IE issue with navigator.language (thanks @nicolasthy) (fixes #893)
|
||||||
|
- Fix for Vimeo controls missing on iOS (thanks @verde-io) (fixes #807)
|
||||||
|
- Fix for double vimeo caption rendering (fixes #877)
|
||||||
|
|
||||||
|
## v3.1.0
|
||||||
|
|
||||||
|
- Styling fixes
|
||||||
|
|
||||||
|
## v3.1.0-beta.2
|
||||||
|
|
||||||
|
- YouTube playback speed fixes
|
||||||
|
|
||||||
|
## v3.1.0-beta.1
|
||||||
|
|
||||||
|
- HTML5 quality selection
|
||||||
|
- Improvements to the YouTube quality selection
|
||||||
|
|
||||||
|
## v3.0.11
|
||||||
|
|
||||||
|
- Muted and autoplay fixes
|
||||||
|
- Small bug fixes from Sentry logs
|
||||||
|
|
||||||
|
## v3.0.10
|
||||||
|
|
||||||
|
- Docs fix
|
||||||
|
- Package upgrades
|
||||||
|
|
||||||
|
## v3.0.9
|
||||||
|
|
||||||
|
- Demo fix
|
||||||
|
- Fix Vimeo regression
|
||||||
|
|
||||||
|
## v3.0.8
|
||||||
|
|
||||||
|
- Vimeo hotfix for private videos
|
||||||
|
|
||||||
|
## v3.0.7
|
||||||
|
|
||||||
|
- Fix for keyboard shortcut error with fast forward
|
||||||
|
- Fix for Vimeo trying to set playback rate when not allowed
|
||||||
|
|
||||||
|
## v3.0.6
|
||||||
|
|
||||||
|
- Improved the logic for the custom handlers preventing default handlers
|
||||||
|
|
||||||
|
## v3.0.5
|
||||||
|
|
||||||
|
- Removed console messages
|
||||||
|
|
||||||
|
## v3.0.4
|
||||||
|
|
||||||
|
- Fixes for fullscreen not working inside iframes
|
||||||
|
- Fixes for custom handlers being able to prevent default
|
||||||
|
- Fixes for controls not hiding/showing correctly on Mobile Safari
|
||||||
|
|
||||||
|
## v3.0.3
|
||||||
|
|
||||||
|
- Vimeo offset tweak (fixes #826)
|
||||||
|
- Fix for .stop() method (fixes #819)
|
||||||
|
- Check for array for speed options (fixes #817)
|
||||||
|
- Restore as float (fixes #828)
|
||||||
|
- Fix for Firefox fullscreen oddness (Fixes #821)
|
||||||
|
- Improve Sprite checking (fixes #827)
|
||||||
|
- Fix fast-forward control (thanks @saadshahd)
|
||||||
|
- Fix the options link in the readme (thanks @DanielRuf)
|
||||||
|
|
||||||
|
## v3.0.2
|
||||||
|
|
||||||
|
- Fix for Safari not firing error events when trying to load blocked scripts
|
||||||
|
|
||||||
|
## v3.0.1
|
||||||
|
|
||||||
|
- Fix for trying to accessing local storage when it's blocked
|
||||||
|
|
||||||
|
# v3.0.0
|
||||||
|
|
||||||
|
This is a massive release. A _mostly_ complete rewrite in ES6. What started out as a few changes quickly snowballed. There's many breaking changes so be careful upgrading.
|
||||||
|
|
||||||
|
### Big changes
|
||||||
|
|
||||||
|
- New settings menu complete with funky animations
|
||||||
|
- Ability to adjust speed of playback
|
||||||
|
- Ability to toggle caption language (HTML5 and Vimeo only)
|
||||||
|
- Ability to set YouTube quality (HTML5 will follow)
|
||||||
|
- Added support for Vimeo captions
|
||||||
|
- Added Picture-in-Picture support (Safari only)
|
||||||
|
- Added AirPlay support (again, Safari only)
|
||||||
|
- Added `playsinline` support for iOS 10+
|
||||||
|
- Soundcloud removed until I can work on a plugin framework
|
||||||
|
- Embedded players are now progressively enhanced - no more empty `<div>`s!
|
||||||
|
|
||||||
|
### Other stuff
|
||||||
|
|
||||||
|
- Now using SASS exclusively. Sorry, LESS folk it just made sense to maintain one method as SASS is what the cool kids use. It may come back if we work out an automated way to convert the SASS
|
||||||
|
- Moved to ES6. All the rage these days. You'll need to look at polyfills. The demo uses [polyfill.io](https://polyfill.io)
|
||||||
|
- Added basic looping support
|
||||||
|
- Added an aspect ratio option for those that can't leave the 90s and want 4:3
|
||||||
|
- `controlshidden` and `controlsshown` events added for when the controls show or hide
|
||||||
|
- `qualityrequested` and `qualitychange` events for YouTube quality control (HTML5 will follow)
|
||||||
|
- Volume is now `0` to `1` as per HTML5 spec
|
||||||
|
- No longer bodging a `<progress>` behind the `<input type="range">` to make up for WebKit's lack of lower fill styling
|
||||||
|
- Captions now render with line breaks as intended
|
||||||
|
- Captions now render without AJAX using the native events etc
|
||||||
|
- Added a fallback for getting YouTube video data incase `.getVideoData()` disappears when one of their developers randomly deletes it again
|
||||||
|
- Setup and building of the UI should be way "snappier"
|
||||||
|
- Click to toggle inverted time (e.g. 0:01 or -2:59 for a 3 minute video at 1 seconds) - new `toggleInvert` and `invertTime` options
|
||||||
|
- Added `autopause` option for Vimeo
|
||||||
|
- Added `muted` option for you guessed it, muted playback
|
||||||
|
- Restored the `.off()` API method
|
||||||
|
- `.play()` will now return a promise to prevent that pesky uncaught promise issue in Chrome etc
|
||||||
|
- Pressing and hold the seek bar no longer freezes all other updates of the UI
|
||||||
|
|
||||||
|
...plus loads of bug fixes.
|
||||||
|
|
||||||
|
### Breaking changes
|
||||||
|
|
||||||
|
You gotta break eggs to make an omelette. Sadly, there's quite a few breaking changes:
|
||||||
|
|
||||||
|
- Setup now uses proper constructor, accepts a single selector/element/node and returns a single instance - much simpler than before
|
||||||
|
- Much of the API is now using getters and setters rather than methods (where it makes sense) to match the HTML5 API - see the docs for more info
|
||||||
|
- The data attributes for the embeds are now `data-plyr-provider` and `data-plyr-embed-id` to prevent compatibility issues. These can be changed under `config.attributes.embed` if required
|
||||||
|
- `blankUrl` -> `blankVideo`
|
||||||
|
- `volume` is now `0` to `1` as per HTML5 spec
|
||||||
|
- `keyboardShorcuts` (typo) is now just `keyboard`
|
||||||
|
- `loop` is now `loop.active` in preparation for loop enhancements later
|
||||||
|
- `html` option for custom controls removed in favour of the `controls` option which now accepts an array (to use built in controls) or a string of HTML for custom controls.
|
||||||
|
- `classes` -> `classNames`
|
||||||
|
- `classes.videoWrapper` -> `classNames.video`
|
||||||
|
- `classes.embedWrapper` -> `classNames.embed`
|
||||||
|
- `classes.ready` removed
|
||||||
|
- `classes.setup` removed
|
||||||
|
- `classes.muted` removed
|
||||||
|
- `classes.fullscreen.active` removed in favour of the `:fullscreen` selector
|
||||||
|
- `selectors.html5` removed
|
||||||
|
- `selectors.embed` removed
|
||||||
|
- `selectors.buttons.seek` -> `selectors.inputs.seek`
|
||||||
|
- `selectors.volume.input` -> `selectors.inputs.volume`
|
||||||
|
- `selectors.volume.display` -> `selectors.display.volume`
|
||||||
|
- `selectors.currentTime` -> `selectors.display.currentTime`
|
||||||
|
- `selectors.duration` -> `selectors.display.duration`
|
||||||
|
|
||||||
|
### Polyfilling
|
||||||
|
|
||||||
|
Because we're using the fancy new ES6 syntax, you will need to polyfill for vintage browsers if you want to use Plyr and still support them. Luckily there's a decent service for this that makes it painless, [polyfill.io](https://polyfill.io). Alternatively, you can use the prebuilt polyfilled build but bear in mind this is 20kb larger. I'd suggest working our your own polyfill strategy.
|
||||||
|
|
||||||
|
## v2.0.18
|
||||||
|
|
||||||
|
- Fix for YouTube .getVideoData() issue (fixes #709)
|
||||||
|
|
||||||
## v2.0.17
|
## v2.0.17
|
||||||
|
|
||||||
- Vimeo controls fix (fixes #697)
|
- Vimeo controls fix (fixes #697)
|
||||||
- SVG4everybody compatibility fix
|
- SVG4everybody compatibility fix
|
||||||
- Allow Plyr.setup event listeners to be set up as separate event listeners (https://github.com/sampotts/plyr/pull/703)
|
- Allow Plyr.setup event listeners to be set up as separate event listeners (https://github.com/sampotts/plyr/pull/703)
|
||||||
@ -9,33 +297,42 @@
|
|||||||
- fix #684 memory leaks issues after destroy (https://github.com/sampotts/plyr/pull/700)
|
- fix #684 memory leaks issues after destroy (https://github.com/sampotts/plyr/pull/700)
|
||||||
|
|
||||||
## v2.0.16
|
## v2.0.16
|
||||||
|
|
||||||
- Fullscreen bug fix (fixes #664)
|
- Fullscreen bug fix (fixes #664)
|
||||||
|
|
||||||
## v2.0.15
|
## v2.0.15
|
||||||
|
|
||||||
- Demo fix
|
- Demo fix
|
||||||
|
|
||||||
## v2.0.14
|
## v2.0.14
|
||||||
|
|
||||||
- CDN URL updates. Sorry, still working on V3 as hard as I can...
|
- CDN URL updates. Sorry, still working on V3 as hard as I can...
|
||||||
|
|
||||||
## v2.0.13
|
## v2.0.13
|
||||||
|
|
||||||
- Repo moved and Vimeo demo fix
|
- Repo moved and Vimeo demo fix
|
||||||
|
|
||||||
## v2.0.12
|
## v2.0.12
|
||||||
|
|
||||||
- Ability to set custom `blankUrl` for source changes (https://github.com/sampotts/plyr/pull/504)
|
- Ability to set custom `blankUrl` for source changes (https://github.com/sampotts/plyr/pull/504)
|
||||||
- Ability to set caption button listener (https://github.com/sampotts/plyr/pull/468)
|
- Ability to set caption button listener (https://github.com/sampotts/plyr/pull/468)
|
||||||
|
|
||||||
## v2.0.11
|
## v2.0.11
|
||||||
|
|
||||||
- Fix for `cleanUp` being called twice (thanks to @sebastiancarlsson)
|
- Fix for `cleanUp` being called twice (thanks to @sebastiancarlsson)
|
||||||
- Fix for YouTube controls on iPad (fixes #391)
|
- Fix for YouTube controls on iPad (fixes #391)
|
||||||
|
|
||||||
## v2.0.10
|
## v2.0.10
|
||||||
|
|
||||||
- Added seek event fixes for Vimeo and YouTube (fixes #409)
|
- Added seek event fixes for Vimeo and YouTube (fixes #409)
|
||||||
- Added support for embed URLs rather than ID only (fixes #345)
|
- Added support for embed URLs rather than ID only (fixes #345)
|
||||||
|
|
||||||
## v2.0.9
|
## v2.0.9
|
||||||
|
|
||||||
- Temporary patch for the YouTube API issues with `getDuration()` (relates to #374)
|
- Temporary patch for the YouTube API issues with `getDuration()` (relates to #374)
|
||||||
|
|
||||||
## v2.0.8
|
## v2.0.8
|
||||||
|
|
||||||
- Added `isPaused()` API method (thanks to @darrena092)
|
- Added `isPaused()` API method (thanks to @darrena092)
|
||||||
- Allowed `.on()` API method to be chainable (thanks to @gurupras) (fixes #357)
|
- Allowed `.on()` API method to be chainable (thanks to @gurupras) (fixes #357)
|
||||||
- Improved the "awful" rendering of captions on small screens in fullscreen mode (fixes #390)
|
- Improved the "awful" rendering of captions on small screens in fullscreen mode (fixes #390)
|
||||||
@ -44,49 +341,49 @@
|
|||||||
- Added Issue and PR templates with the aim of reducing duplicate or duff issues
|
- Added Issue and PR templates with the aim of reducing duplicate or duff issues
|
||||||
|
|
||||||
## v2.0.7
|
## v2.0.7
|
||||||
|
|
||||||
- Fixed `getCurrentTime()` method (fixes #351)
|
- Fixed `getCurrentTime()` method (fixes #351)
|
||||||
- Added `getVolume()` , `isMuted()` and `getDuration()` API methods (fixes #346)
|
- Added `getVolume()` , `isMuted()` and `getDuration()` API methods (fixes #346)
|
||||||
|
|
||||||
## v2.0.6
|
## v2.0.6
|
||||||
|
|
||||||
- Fixed merge issue with `Updated define to work with AMD imports #326` PR
|
- Fixed merge issue with `Updated define to work with AMD imports #326` PR
|
||||||
- Code formatting
|
- Code formatting
|
||||||
|
|
||||||
## v2.0.5
|
## v2.0.5
|
||||||
|
|
||||||
- Fix for Vimeo in IE9 & IE10
|
- Fix for Vimeo in IE9 & IE10
|
||||||
- Fix for HTML5 elements not firing `ready` event
|
- Fix for HTML5 elements not firing `ready` event
|
||||||
|
|
||||||
## v2.0.4
|
## v2.0.4
|
||||||
|
|
||||||
- Fix for Firefox full screen (fixes #343)
|
- Fix for Firefox full screen (fixes #343)
|
||||||
|
|
||||||
## v2.0.3
|
## v2.0.3
|
||||||
|
|
||||||
- Set 'global' keyboard shortcut option to false as default, added `<textarea>` to editable elements to be ignored
|
- Set 'global' keyboard shortcut option to false as default, added `<textarea>` to editable elements to be ignored
|
||||||
|
|
||||||
## v2.0.2
|
## v2.0.2
|
||||||
|
|
||||||
- Added 'global' keyboard shortcut option
|
- Added 'global' keyboard shortcut option
|
||||||
|
|
||||||
## v2.0.1
|
## v2.0.1
|
||||||
|
|
||||||
- Version bump for NPM (sorry for folks who upgraded to the now deleted v1.9.0 through NPM)
|
- Version bump for NPM (sorry for folks who upgraded to the now deleted v1.9.0 through NPM)
|
||||||
|
|
||||||
# v2.0.0
|
# v2.0.0
|
||||||
This version contains several potential ***breaking changes***:
|
|
||||||
|
|
||||||
- `setup()` has been reverted to pre v1.8.0 behaviour; meaning it will return the *instance* rather than the *element*. This is because the reference to the instance is no longer added to the original element (see below).
|
This version contains several potential **_breaking changes_**:
|
||||||
|
|
||||||
|
- `setup()` has been reverted to pre v1.8.0 behaviour; meaning it will return the _instance_ rather than the _element_. This is because the reference to the instance is no longer added to the original element (see below).
|
||||||
- The reference to the `plyr` instance is now added to the media element rather than original container. This is because if a container with multiple children was passed to `setup()` the references to all instances would have been added to the container, creating issues. I would recommend using the return value from `setup()` or the new `get()` method to access the instance.
|
- The reference to the `plyr` instance is now added to the media element rather than original container. This is because if a container with multiple children was passed to `setup()` the references to all instances would have been added to the container, creating issues. I would recommend using the return value from `setup()` or the new `get()` method to access the instance.
|
||||||
- Players will always be wrapped in their own div now - this makes `setup()` and `destroy()` cleaner. This *may* break any custom styling based on DOM position.
|
- Players will always be wrapped in their own div now - this makes `setup()` and `destroy()` cleaner. This _may_ break any custom styling based on DOM position.
|
||||||
- Players no longer seek to 0 on 'ended' - this is to fix a bug with Microsoft Edge as it triggers 'ended' on media change for whatever reason. They'll never change ;-)
|
- Players no longer seek to 0 on 'ended' - this is to fix a bug with Microsoft Edge as it triggers 'ended' on media change for whatever reason. They'll never change ;-)
|
||||||
|
|
||||||
And some other changes and bug fixes:
|
And some other changes and bug fixes:
|
||||||
|
|
||||||
- New `get()` method on the global plyr object to get all instances inside a container
|
- New `get()` method on the global plyr object to get all instances inside a container
|
||||||
- New API methods:
|
- New API methods: - `getOriginal()` to get the original, _unmodified_ element plyr was setup on (`<video>`, `<audio>` or empty `<div>` for YouTube and Vimeo) - `getContainer()` to get the players outer wrapper element - `getMedia()` to get the players media element (`<video>`, `<audio>` or empty `<div>` for YouTube and Vimeo) - `getEmbed()` to access the YouTube or Vimeo API directly - `getType()` to get the type of the player - `isReady()` to determine if an instance has completed setup and necessary APIs are loaded (for YouTube / Vimeo) - `on()` to provide an easy way to listen to events - `stop()` to, you guessed it, stop the player
|
||||||
- `getOriginal()` to get the original, *unmodified* element plyr was setup on (`<video>`, `<audio>` or empty `<div>` for YouTube and Vimeo)
|
|
||||||
- `getContainer()` to get the players outer wrapper element
|
|
||||||
- `getMedia()` to get the players media element (`<video>`, `<audio>` or empty `<div>` for YouTube and Vimeo)
|
|
||||||
- `getEmbed()` to access the YouTube or Vimeo API directly
|
|
||||||
- `getType()` to get the type of the player
|
|
||||||
- `isReady()` to determine if an instance has completed setup and necessary APIs are loaded (for YouTube / Vimeo)
|
|
||||||
- `on()` to provide an easy way to listen to events
|
|
||||||
- `stop()` to, you guessed it, stop the player
|
|
||||||
- `destroy()` now works correctly for YouTube and Vimeo (fixes #272)
|
- `destroy()` now works correctly for YouTube and Vimeo (fixes #272)
|
||||||
- New `destroyed` event when `destroy()` has completed (original element is passed as event.target)
|
- New `destroyed` event when `destroy()` has completed (original element is passed as event.target)
|
||||||
- Default volume is now 10 (max) rather than 5
|
- Default volume is now 10 (max) rather than 5
|
||||||
@ -98,10 +395,12 @@ And some other changes and bug fixes:
|
|||||||
- Change to AMD (fixes #298)
|
- Change to AMD (fixes #298)
|
||||||
|
|
||||||
## v1.8.12
|
## v1.8.12
|
||||||
|
|
||||||
- Vimeo keyboard focus fix (Fixes #317)
|
- Vimeo keyboard focus fix (Fixes #317)
|
||||||
- Fix for Vimeo on basic support devices
|
- Fix for Vimeo on basic support devices
|
||||||
|
|
||||||
## v1.8.11
|
## v1.8.11
|
||||||
|
|
||||||
- Fix for keyboard navigation on Vimeo (Fixes #317)
|
- Fix for keyboard navigation on Vimeo (Fixes #317)
|
||||||
- Fix for bug introduced in v1.8.9 related to additional controls
|
- Fix for bug introduced in v1.8.9 related to additional controls
|
||||||
- Vimeo API upgrade
|
- Vimeo API upgrade
|
||||||
@ -109,31 +408,39 @@ And some other changes and bug fixes:
|
|||||||
- Added support for passing array to .setup() (Fixes #319)
|
- Added support for passing array to .setup() (Fixes #319)
|
||||||
|
|
||||||
## v1.8.10
|
## v1.8.10
|
||||||
|
|
||||||
- Fix for seek issues introduced in v1.8.9
|
- Fix for seek issues introduced in v1.8.9
|
||||||
|
|
||||||
## v1.8.9
|
## v1.8.9
|
||||||
|
|
||||||
- Fix for fullscreen not being defined (Fixes #295)
|
- Fix for fullscreen not being defined (Fixes #295)
|
||||||
- Fix for multiline captions (Fixes #314)
|
- Fix for multiline captions (Fixes #314)
|
||||||
- Clean up of type checks and fix for `restart()` (Fixes #315)
|
- Clean up of type checks and fix for `restart()` (Fixes #315)
|
||||||
- Fix for `MEDIA_ERR_SRC_NOT_SUPPORTED` when calling `.source()` API method
|
- Fix for `MEDIA_ERR_SRC_NOT_SUPPORTED` when calling `.source()` API method
|
||||||
|
|
||||||
## v1.8.8
|
## v1.8.8
|
||||||
|
|
||||||
- Added getCurrentTime API method (fixes #292)
|
- Added getCurrentTime API method (fixes #292)
|
||||||
- Fix for !hideControls on touch devices (fixes #303)
|
- Fix for !hideControls on touch devices (fixes #303)
|
||||||
|
|
||||||
## v1.8.7
|
## v1.8.7
|
||||||
|
|
||||||
- Line height fix
|
- Line height fix
|
||||||
|
|
||||||
## v1.8.6
|
## v1.8.6
|
||||||
|
|
||||||
- Reverted font size change
|
- Reverted font size change
|
||||||
|
|
||||||
## v1.8.5
|
## v1.8.5
|
||||||
|
|
||||||
- Fixed overflow issues (fixes #286)
|
- Fixed overflow issues (fixes #286)
|
||||||
|
|
||||||
## v1.8.4
|
## v1.8.4
|
||||||
|
|
||||||
- Fix for large play button on small videos
|
- Fix for large play button on small videos
|
||||||
|
|
||||||
## v1.8.3
|
## v1.8.3
|
||||||
|
|
||||||
- Disabled iPad support for YouTube and Vimeo due to iOS limitations with iFrame playback
|
- Disabled iPad support for YouTube and Vimeo due to iOS limitations with iFrame playback
|
||||||
- Fixed IE11 icon loading (fixes #269)
|
- Fixed IE11 icon loading (fixes #269)
|
||||||
- Updated screenshot (fixes #281)
|
- Updated screenshot (fixes #281)
|
||||||
@ -143,84 +450,107 @@ And some other changes and bug fixes:
|
|||||||
- Improvements for controls hiding and showing on touch devices
|
- Improvements for controls hiding and showing on touch devices
|
||||||
|
|
||||||
## v1.8.2
|
## v1.8.2
|
||||||
|
|
||||||
- Fixed event bubbling
|
- Fixed event bubbling
|
||||||
|
|
||||||
## v1.8.1
|
## v1.8.1
|
||||||
|
|
||||||
- Fixed inaccurate log message
|
- Fixed inaccurate log message
|
||||||
|
|
||||||
# v1.8.0
|
# v1.8.0
|
||||||
- ***(Important)*** `setup()` now returns the element Plyr was setup on rather than the `plyr` object. This means `var player = plyr.setup()[0];` would now be `var player = plyr.setup()[0].plyr;`. This improves support for React and other virtual dom frameworks as mentioned in #254
|
|
||||||
|
- **_(Important)_** `setup()` now returns the element Plyr was setup on rather than the `plyr` object. This means `var player = plyr.setup()[0];` would now be `var player = plyr.setup()[0].plyr;`. This improves support for React and other virtual dom frameworks as mentioned in #254
|
||||||
- Fixed using a relative URL for `iconUrl` in IE (fixes #269)
|
- Fixed using a relative URL for `iconUrl` in IE (fixes #269)
|
||||||
|
|
||||||
# v1.7.0
|
# v1.7.0
|
||||||
|
|
||||||
- SASS cleanup (fixes #265)
|
- SASS cleanup (fixes #265)
|
||||||
- Docs tidy up to help quick start (fixes #253)
|
- Docs tidy up to help quick start (fixes #253)
|
||||||
- Fix for issues with data attribute options passing (fixes #257)
|
- Fix for issues with data attribute options passing (fixes #257)
|
||||||
- ***(Important)*** Removed the requirement for a wrapper div to setup Plyr and removed the dependency on the `plyr` classname as a JS hook. By default it will now look for `<video>`, `<audio>` and `[data-type]` elements. If you are just calling `setup()` with a `<div class="plyr">` you may want to give it a good test after upgrading. You can probably remove the wrapper div. The reason behind this is to make setup easier for newcomers and prevent the styling being used on unsupported players (because the plyr classname was used as a CSS and JS hook - which isn't ideal)
|
- **_(Important)_** Removed the requirement for a wrapper div to setup Plyr and removed the dependency on the `plyr` classname as a JS hook. By default it will now look for `<video>`, `<audio>` and `[data-type]` elements. If you are just calling `setup()` with a `<div class="plyr">` you may want to give it a good test after upgrading. You can probably remove the wrapper div. The reason behind this is to make setup easier for newcomers and prevent the styling being used on unsupported players (because the plyr classname was used as a CSS and JS hook - which isn't ideal)
|
||||||
- Renamed the 'docs' folder to `demo` to avoid confusion - the readme is the docs after all
|
- Renamed the 'docs' folder to `demo` to avoid confusion - the readme is the docs after all
|
||||||
|
|
||||||
## v1.6.20
|
## v1.6.20
|
||||||
|
|
||||||
- Fix for multiple sprites being requested (fixes #259)
|
- Fix for multiple sprites being requested (fixes #259)
|
||||||
|
|
||||||
## v1.6.19
|
## v1.6.19
|
||||||
|
|
||||||
- Fix for scroll direction issues on volume control (fixes #258)
|
- Fix for scroll direction issues on volume control (fixes #258)
|
||||||
|
|
||||||
## v1.6.18
|
## v1.6.18
|
||||||
|
|
||||||
- Reduced rounding of seek value from 1 decimal point to 4 (fixes #242)
|
- Reduced rounding of seek value from 1 decimal point to 4 (fixes #242)
|
||||||
|
|
||||||
## v1.6.17
|
## v1.6.17
|
||||||
|
|
||||||
- Added `disableContextMenu` option to hide the right click context menu (fixes #248 and #225)
|
- Added `disableContextMenu` option to hide the right click context menu (fixes #248 and #225)
|
||||||
|
|
||||||
## v1.6.16
|
## v1.6.16
|
||||||
|
|
||||||
- Always hide standard controls (fixes #225)
|
- Always hide standard controls (fixes #225)
|
||||||
- Fix for Tooltips overflowing (fixes #230)
|
- Fix for Tooltips overflowing (fixes #230)
|
||||||
|
|
||||||
## v1.6.15
|
## v1.6.15
|
||||||
|
|
||||||
- Restore scroll position when exiting full screen (fixes #236)
|
- Restore scroll position when exiting full screen (fixes #236)
|
||||||
|
|
||||||
## v1.6.14
|
## v1.6.14
|
||||||
|
|
||||||
- SVG sprite loading automatically for an easier setup
|
- SVG sprite loading automatically for an easier setup
|
||||||
- Touch devices now show controls on touch rather than pausing playback
|
- Touch devices now show controls on touch rather than pausing playback
|
||||||
|
|
||||||
## v1.6.13
|
## v1.6.13
|
||||||
|
|
||||||
- Decreased sensitivity and inverted scroll on volume slider (scroll up to increase, down to decrease)
|
- Decreased sensitivity and inverted scroll on volume slider (scroll up to increase, down to decrease)
|
||||||
|
|
||||||
## v1.6.12
|
## v1.6.12
|
||||||
|
|
||||||
- Fix for undefined buffer error
|
- Fix for undefined buffer error
|
||||||
- Add scroll listener on volume slider (PR #227 bty @igoradamenko)
|
- Add scroll listener on volume slider (PR #227 bty @igoradamenko)
|
||||||
|
|
||||||
## v1.6.11
|
## v1.6.11
|
||||||
|
|
||||||
- Fix for Vimeo fullscreen (fixes #214)
|
- Fix for Vimeo fullscreen (fixes #214)
|
||||||
|
|
||||||
## v1.6.10
|
## v1.6.10
|
||||||
|
|
||||||
- Changed default icon prefix from 'icon' to 'plyr' to avoid clashes
|
- Changed default icon prefix from 'icon' to 'plyr' to avoid clashes
|
||||||
|
|
||||||
## v1.6.9
|
## v1.6.9
|
||||||
|
|
||||||
- Added 'latest' CDN option
|
- Added 'latest' CDN option
|
||||||
- Renamed `sprite.svg` to `plyr.svg` to be inline with the other package files
|
- Renamed `sprite.svg` to `plyr.svg` to be inline with the other package files
|
||||||
|
|
||||||
## v1.6.8
|
## v1.6.8
|
||||||
|
|
||||||
- Fix for bug introduced in v1.6.7
|
- Fix for bug introduced in v1.6.7
|
||||||
|
|
||||||
## v1.6.7
|
## v1.6.7
|
||||||
|
|
||||||
- Fixes for using `source` API method on iOS
|
- Fixes for using `source` API method on iOS
|
||||||
|
|
||||||
## v1.6.6
|
## v1.6.6
|
||||||
|
|
||||||
- Icons cleaned up
|
- Icons cleaned up
|
||||||
- IE11 button fix for tooltips (fixes #210)
|
- IE11 button fix for tooltips (fixes #210)
|
||||||
|
|
||||||
## v1.6.5
|
## v1.6.5
|
||||||
|
|
||||||
- IE UI bug fixes
|
- IE UI bug fixes
|
||||||
|
|
||||||
## v1.6.4
|
## v1.6.4
|
||||||
|
|
||||||
- Bug fix for undefined progress bar
|
- Bug fix for undefined progress bar
|
||||||
|
|
||||||
## v1.6.3
|
## v1.6.3
|
||||||
|
|
||||||
- Seek back to 0 for all media on ended
|
- Seek back to 0 for all media on ended
|
||||||
- Check for HTML5 video on ended reload
|
- Check for HTML5 video on ended reload
|
||||||
- Update to docs for `showPosterOnEnd` option
|
- Update to docs for `showPosterOnEnd` option
|
||||||
|
|
||||||
## v1.6.2
|
## v1.6.2
|
||||||
|
|
||||||
- Fix for tooltip displaying when duration is not set (fixes #177)
|
- Fix for tooltip displaying when duration is not set (fixes #177)
|
||||||
- `showPosterOnEnd` option to show poster when HTML5 video ended (fixes #59)
|
- `showPosterOnEnd` option to show poster when HTML5 video ended (fixes #59)
|
||||||
- Error handler for YouTube (fixes #189)
|
- Error handler for YouTube (fixes #189)
|
||||||
@ -228,15 +558,12 @@ And some other changes and bug fixes:
|
|||||||
- Other minor bug fixes
|
- Other minor bug fixes
|
||||||
|
|
||||||
## v1.6.1
|
## v1.6.1
|
||||||
|
|
||||||
- Tooltip changes for accessibility
|
- Tooltip changes for accessibility
|
||||||
|
|
||||||
## v1.6.0
|
## v1.6.0
|
||||||
- New, cleaner, UI:
|
|
||||||
- Controls are now overlaid, maintaining the video's ratio and making sizing easier
|
- New, cleaner, UI: - Controls are now overlaid, maintaining the video's ratio and making sizing easier - A large play button can now be overlaid over videos - Default number of control buttons reduced - New play, pause, rewind and fast forward icons - Flexbox all the things!
|
||||||
- A large play button can now be overlaid over videos
|
|
||||||
- Default number of control buttons reduced
|
|
||||||
- New play, pause, rewind and fast forward icons
|
|
||||||
- Flexbox all the things!
|
|
||||||
- Tidied up the LESS (and SCSS) as part of the above, variables and mixins in seprate files amking customization and upgrades easier
|
- Tidied up the LESS (and SCSS) as part of the above, variables and mixins in seprate files amking customization and upgrades easier
|
||||||
- Toggle mute bug fix; if a player was muted previously and the user refreshed, unmuting would have meant volume was still zero (effectively muted), now the config default value is used. Not ideal but good for now
|
- Toggle mute bug fix; if a player was muted previously and the user refreshed, unmuting would have meant volume was still zero (effectively muted), now the config default value is used. Not ideal but good for now
|
||||||
- New `iconUrl` option allowing specifying a same origin SVG sprite location. Loading this way means you don't need the AJAX sprite loading JavaScript
|
- New `iconUrl` option allowing specifying a same origin SVG sprite location. Loading this way means you don't need the AJAX sprite loading JavaScript
|
||||||
@ -245,76 +572,95 @@ And some other changes and bug fixes:
|
|||||||
- `sass` folder in `src` renamed from to `scss`
|
- `sass` folder in `src` renamed from to `scss`
|
||||||
|
|
||||||
## v1.5.21
|
## v1.5.21
|
||||||
|
|
||||||
- Bug fix for embeds: `play` not being defined (fixes #185 and #186)
|
- Bug fix for embeds: `play` not being defined (fixes #185 and #186)
|
||||||
|
|
||||||
## v1.5.20
|
## v1.5.20
|
||||||
|
|
||||||
- Bug fix for autoplay option
|
- Bug fix for autoplay option
|
||||||
|
|
||||||
## v1.5.19
|
## v1.5.19
|
||||||
|
|
||||||
- Fix for accessing `embed` property after `ready` event fired
|
- Fix for accessing `embed` property after `ready` event fired
|
||||||
|
|
||||||
## v1.5.18
|
## v1.5.18
|
||||||
|
|
||||||
- Added 'ready' event for initial setup complete or source change occurs
|
- Added 'ready' event for initial setup complete or source change occurs
|
||||||
- Fixed SASS stylesheet references to transparentize
|
- Fixed SASS stylesheet references to transparentize
|
||||||
- Added default font stack to controls
|
- Added default font stack to controls
|
||||||
- Docs fixes inc controls HTML (fixes #180)
|
- Docs fixes inc controls HTML (fixes #180)
|
||||||
|
|
||||||
## v1.5.17
|
## v1.5.17
|
||||||
|
|
||||||
- Expose YouTube and Vimeo API (docs update required) (fixes #176)
|
- Expose YouTube and Vimeo API (docs update required) (fixes #176)
|
||||||
- Auto set title based on YouTube getVideoData() title property
|
- Auto set title based on YouTube getVideoData() title property
|
||||||
- Bug fix for Vimeo API change (Uncaught TypeError: Cannot read property 'value' of undefined) due to a change their end
|
- Bug fix for Vimeo API change (Uncaught TypeError: Cannot read property 'value' of undefined) due to a change their end
|
||||||
|
|
||||||
## v1.5.16
|
## v1.5.16
|
||||||
|
|
||||||
- Cancel requests on source change (fixes #174)
|
- Cancel requests on source change (fixes #174)
|
||||||
|
|
||||||
## v1.5.15
|
## v1.5.15
|
||||||
|
|
||||||
- Fix for CustomEvent polyfill and related bug (see #172)
|
- Fix for CustomEvent polyfill and related bug (see #172)
|
||||||
|
|
||||||
## v1.5.14
|
## v1.5.14
|
||||||
|
|
||||||
- Volume storage fix (fixes #171)
|
- Volume storage fix (fixes #171)
|
||||||
|
|
||||||
## v1.5.13
|
## v1.5.13
|
||||||
|
|
||||||
- Fix for manual caption rendering
|
- Fix for manual caption rendering
|
||||||
|
|
||||||
## v1.5.12
|
## v1.5.12
|
||||||
|
|
||||||
- Added a duration option to pass the duration of the file
|
- Added a duration option to pass the duration of the file
|
||||||
- Added the ability to set options per element by setting a data-plyr attribute on the target elements (this might be useful for the duration option for example)
|
- Added the ability to set options per element by setting a data-plyr attribute on the target elements (this might be useful for the duration option for example)
|
||||||
- Fixes for Chrome and Safari caption rendering, they now use the default texttrack and cuechange events
|
- Fixes for Chrome and Safari caption rendering, they now use the default texttrack and cuechange events
|
||||||
- Firefox bug fix for event not defined
|
- Firefox bug fix for event not defined
|
||||||
|
|
||||||
## v1.5.11
|
## v1.5.11
|
||||||
|
|
||||||
- iOS embed bug fixes (fixes #166)
|
- iOS embed bug fixes (fixes #166)
|
||||||
- Hide IE/Edge <input type='range'> tooltip (since we have a styled one) (fixes #160)
|
- Hide IE/Edge <input type='range'> tooltip (since we have a styled one) (fixes #160)
|
||||||
- SASS bug fix for default values (fixes #158)
|
- SASS bug fix for default values (fixes #158)
|
||||||
|
|
||||||
## v1.5.9 + v1.5.10
|
## v1.5.9 + v1.5.10
|
||||||
|
|
||||||
- NPM bug fixes
|
- NPM bug fixes
|
||||||
|
|
||||||
## v1.5.8
|
## v1.5.8
|
||||||
|
|
||||||
- Fix for touch device seek tooltip
|
- Fix for touch device seek tooltip
|
||||||
- Seek improvements
|
- Seek improvements
|
||||||
|
|
||||||
## v1.5.7
|
## v1.5.7
|
||||||
|
|
||||||
- Fix for control tooltips always showing
|
- Fix for control tooltips always showing
|
||||||
|
|
||||||
## v1.5.6
|
## v1.5.6
|
||||||
|
|
||||||
- Seek tooltip (option for tooltips changed, please check docs)
|
- Seek tooltip (option for tooltips changed, please check docs)
|
||||||
- SASS compile error fixes (fixes #148)
|
- SASS compile error fixes (fixes #148)
|
||||||
- Fullscreen fixes for controls not always hiding/showing (fixes #149)
|
- Fullscreen fixes for controls not always hiding/showing (fixes #149)
|
||||||
- Screen reader icon fixes (title was being read twice due to the tooltip/hidden label)
|
- Screen reader icon fixes (title was being read twice due to the tooltip/hidden label)
|
||||||
|
|
||||||
## v1.5.5
|
## v1.5.5
|
||||||
|
|
||||||
- Fixed controls.md example
|
- Fixed controls.md example
|
||||||
- Bug fix for docs error page
|
- Bug fix for docs error page
|
||||||
- Bug fix for controls tooltips
|
- Bug fix for controls tooltips
|
||||||
|
|
||||||
## v1.5.4
|
## v1.5.4
|
||||||
|
|
||||||
- Minor bug fix for clicking video to play/pause after source change
|
- Minor bug fix for clicking video to play/pause after source change
|
||||||
|
|
||||||
## v1.5.3
|
## v1.5.3
|
||||||
|
|
||||||
- Minor bug fix for occasional display of 0:00 as the media duration
|
- Minor bug fix for occasional display of 0:00 as the media duration
|
||||||
|
|
||||||
## v1.5.2
|
## v1.5.2
|
||||||
|
|
||||||
- `handlers` option renamed to `listeners`
|
- `handlers` option renamed to `listeners`
|
||||||
- Added event listeners for all types to the plyr container (playback, fullscreen, captions etc - see docs)
|
- Added event listeners for all types to the plyr container (playback, fullscreen, captions etc - see docs)
|
||||||
- Removed onSetup config option (use the 'setup' event instead, plyr element is event.plyr)
|
- Removed onSetup config option (use the 'setup' event instead, plyr element is event.plyr)
|
||||||
@ -323,9 +669,11 @@ And some other changes and bug fixes:
|
|||||||
- Fix for fullscreen player (using class hook, not browser fullscreen)
|
- Fix for fullscreen player (using class hook, not browser fullscreen)
|
||||||
|
|
||||||
## v1.5.1
|
## v1.5.1
|
||||||
|
|
||||||
- Fix for event listeners being duplicated on source change
|
- Fix for event listeners being duplicated on source change
|
||||||
|
|
||||||
# v1.5.0
|
# v1.5.0
|
||||||
|
|
||||||
- Vimeo support (fixes #8)
|
- Vimeo support (fixes #8)
|
||||||
- New options for initialization (you can now pass a selector, HTMLElement or NodeList) (fixes #118)
|
- New options for initialization (you can now pass a selector, HTMLElement or NodeList) (fixes #118)
|
||||||
- Switched to BEM methodology (you will need to change CSS and probably HTML)
|
- Switched to BEM methodology (you will need to change CSS and probably HTML)
|
||||||
@ -342,209 +690,269 @@ And some other changes and bug fixes:
|
|||||||
- Keyboard navigation improvements (focus on seek, focus trap in fullscreen) (fixes #135)
|
- Keyboard navigation improvements (focus on seek, focus trap in fullscreen) (fixes #135)
|
||||||
|
|
||||||
## v1.3.5
|
## v1.3.5
|
||||||
|
|
||||||
- Fixed bug with API use on basic supported browsers
|
- Fixed bug with API use on basic supported browsers
|
||||||
|
|
||||||
## v1.3.4
|
## v1.3.4
|
||||||
|
|
||||||
- Code cleanup by @calvintam236
|
- Code cleanup by @calvintam236
|
||||||
|
|
||||||
## v1.3.3
|
## v1.3.3
|
||||||
|
|
||||||
- Removed captions being read by screen readers
|
- Removed captions being read by screen readers
|
||||||
|
|
||||||
## v1.3.2
|
## v1.3.2
|
||||||
|
|
||||||
- Voiceover fix for captions
|
- Voiceover fix for captions
|
||||||
|
|
||||||
## v1.3.1
|
## v1.3.1
|
||||||
|
|
||||||
- ARIA improvements for captions being read
|
- ARIA improvements for captions being read
|
||||||
|
|
||||||
## v1.3.0
|
## v1.3.0
|
||||||
|
|
||||||
- Internationalization support (i18n) using default controls (required markup changes to controls)
|
- Internationalization support (i18n) using default controls (required markup changes to controls)
|
||||||
- ARIA enhancements for controls (required markup changes to controls)
|
- ARIA enhancements for controls (required markup changes to controls)
|
||||||
- Captions legibility improvements
|
- Captions legibility improvements
|
||||||
- YouTube bug fixes
|
- YouTube bug fixes
|
||||||
|
|
||||||
## v1.2.6
|
## v1.2.6
|
||||||
|
|
||||||
- SASS updates and fixes (cheers @ChristianPV)
|
- SASS updates and fixes (cheers @ChristianPV)
|
||||||
|
|
||||||
## v1.2.5
|
## v1.2.5
|
||||||
|
|
||||||
- Fix for YouTube quality (let them decide quality)
|
- Fix for YouTube quality (let them decide quality)
|
||||||
|
|
||||||
## v1.2.4
|
## v1.2.4
|
||||||
|
|
||||||
- Fix for omitted kind attribute on <track> (fixes #88)
|
- Fix for omitted kind attribute on <track> (fixes #88)
|
||||||
|
|
||||||
## v1.2.3
|
## v1.2.3
|
||||||
|
|
||||||
- Fix for YouTube on iPhone or unsupported browsers (fallback to YouTube native)
|
- Fix for YouTube on iPhone or unsupported browsers (fallback to YouTube native)
|
||||||
- Docs tidy up
|
- Docs tidy up
|
||||||
- Fullscreen for Safari fix (fixes #96)
|
- Fullscreen for Safari fix (fixes #96)
|
||||||
|
|
||||||
## v1.2.2
|
## v1.2.2
|
||||||
|
|
||||||
- Fix for :focus keyboard vs mouse (fixes #61)
|
- Fix for :focus keyboard vs mouse (fixes #61)
|
||||||
- Fix for caption positioning in full screen (fixes #92)
|
- Fix for caption positioning in full screen (fixes #92)
|
||||||
|
|
||||||
## v1.2.1
|
## v1.2.1
|
||||||
|
|
||||||
- Tooltip bug fix
|
- Tooltip bug fix
|
||||||
|
|
||||||
# v1.2.0
|
# v1.2.0
|
||||||
|
|
||||||
- Added YouTube support
|
- Added YouTube support
|
||||||
|
|
||||||
## v1.1.13
|
## v1.1.13
|
||||||
|
|
||||||
- Added icon prefix option for when using default controls
|
- Added icon prefix option for when using default controls
|
||||||
|
|
||||||
## v1.1.13
|
## v1.1.13
|
||||||
|
|
||||||
- Logic tweaks for hiding controls in fullscreen
|
- Logic tweaks for hiding controls in fullscreen
|
||||||
|
|
||||||
## v1.1.12
|
## v1.1.12
|
||||||
|
|
||||||
- Bug fix for Chrome Canary
|
- Bug fix for Chrome Canary
|
||||||
|
|
||||||
## v1.1.11
|
## v1.1.11
|
||||||
|
|
||||||
- Bug fix
|
- Bug fix
|
||||||
|
|
||||||
## v1.1.10
|
## v1.1.10
|
||||||
|
|
||||||
- Bug fix
|
- Bug fix
|
||||||
|
|
||||||
## v1.1.9
|
## v1.1.9
|
||||||
|
|
||||||
- Bug fix for 1.1.8
|
- Bug fix for 1.1.8
|
||||||
|
|
||||||
## v1.1.8
|
## v1.1.8
|
||||||
|
|
||||||
- setVolume API method improvements (fixes #83)
|
- setVolume API method improvements (fixes #83)
|
||||||
|
|
||||||
## v1.1.7
|
## v1.1.7
|
||||||
|
|
||||||
- Restore classname on destroy()
|
- Restore classname on destroy()
|
||||||
|
|
||||||
## v1.1.6
|
## v1.1.6
|
||||||
|
|
||||||
- New API methods (fixes #77), Fix for non strict mode (fixes #78)
|
- New API methods (fixes #77), Fix for non strict mode (fixes #78)
|
||||||
|
|
||||||
## v1.1.5
|
## v1.1.5
|
||||||
|
|
||||||
- Fix for incorrect `isFullscreen()` return value in Mozilla (fixes #38)
|
- Fix for incorrect `isFullscreen()` return value in Mozilla (fixes #38)
|
||||||
|
|
||||||
## v1.1.4
|
## v1.1.4
|
||||||
|
|
||||||
- Minor bug fixes
|
- Minor bug fixes
|
||||||
|
|
||||||
## v1.1.3
|
## v1.1.3
|
||||||
|
|
||||||
- Fixes for random id used in controls with multiple instances and one call to setup
|
- Fixes for random id used in controls with multiple instances and one call to setup
|
||||||
- Audio player UI improvements
|
- Audio player UI improvements
|
||||||
|
|
||||||
## v1.1.2
|
## v1.1.2
|
||||||
|
|
||||||
- Added an onSetup callback option
|
- Added an onSetup callback option
|
||||||
- Added fullscreen API methods `toggleFullscreen()` (must be user iniated), and `isFullscreen()`
|
- Added fullscreen API methods `toggleFullscreen()` (must be user iniated), and `isFullscreen()`
|
||||||
|
|
||||||
## v1.1.1
|
## v1.1.1
|
||||||
|
|
||||||
- Fix for unsupported browser handling
|
- Fix for unsupported browser handling
|
||||||
- Fix for config.controls having no effect
|
- Fix for config.controls having no effect
|
||||||
|
|
||||||
## v1.1.0
|
## v1.1.0
|
||||||
|
|
||||||
- Added config option to set which controls are shown (if using the default controls html) and better handling of missing controls
|
- Added config option to set which controls are shown (if using the default controls html) and better handling of missing controls
|
||||||
|
|
||||||
## v1.0.31
|
## v1.0.31
|
||||||
|
|
||||||
- Display duration on `metadataloaded`
|
- Display duration on `metadataloaded`
|
||||||
|
|
||||||
## v1.0.30
|
## v1.0.30
|
||||||
|
|
||||||
- Fixed bug with media longer than 60 minutes (fixes #69)
|
- Fixed bug with media longer than 60 minutes (fixes #69)
|
||||||
|
|
||||||
## v1.0.29
|
## v1.0.29
|
||||||
|
|
||||||
- Added option to hide controls on fullscreen (default `true`) while palying, after 1s. Pause, mouse hover on progress, or focus on a child control re-shows the controls. On touch a tap of the video (which plays/pauses the video by default) is required. (fixes #47)
|
- Added option to hide controls on fullscreen (default `true`) while palying, after 1s. Pause, mouse hover on progress, or focus on a child control re-shows the controls. On touch a tap of the video (which plays/pauses the video by default) is required. (fixes #47)
|
||||||
- Fixed a bug with caption toggle in 1.0.28
|
- Fixed a bug with caption toggle in 1.0.28
|
||||||
|
|
||||||
## v1.0.28
|
## v1.0.28
|
||||||
|
|
||||||
- Added API support for browsers that don't have full plyr support (pretty much <=IE9 and `<video>` on iPhone/iPod)
|
- Added API support for browsers that don't have full plyr support (pretty much <=IE9 and `<video>` on iPhone/iPod)
|
||||||
|
|
||||||
## v1.0.27
|
## v1.0.27
|
||||||
|
|
||||||
- Keyboard accessibility improvements (fixes #66)
|
- Keyboard accessibility improvements (fixes #66)
|
||||||
|
|
||||||
## v1.0.26
|
## v1.0.26
|
||||||
|
|
||||||
- Fixes for SASS (cheers @brunowego)
|
- Fixes for SASS (cheers @brunowego)
|
||||||
- Indentation reset to 4 spaces
|
- Indentation reset to 4 spaces
|
||||||
|
|
||||||
## v1.0.25
|
## v1.0.25
|
||||||
|
|
||||||
- Fixes for iOS volume controls (hidden)
|
- Fixes for iOS volume controls (hidden)
|
||||||
- Classnames for left/right controls changed
|
- Classnames for left/right controls changed
|
||||||
|
|
||||||
## v1.0.24
|
## v1.0.24
|
||||||
|
|
||||||
- Added tooltip option to display labels as tooltips (fixes #50)
|
- Added tooltip option to display labels as tooltips (fixes #50)
|
||||||
|
|
||||||
## v1.0.23
|
## v1.0.23
|
||||||
|
|
||||||
- Handling loading states in the UI (fixes #36)
|
- Handling loading states in the UI (fixes #36)
|
||||||
|
|
||||||
## v1.0.22
|
## v1.0.22
|
||||||
|
|
||||||
- Added support() API method for checking mimetype support
|
- Added support() API method for checking mimetype support
|
||||||
- Added source() API method for setting media source(s) (fixes #44)
|
- Added source() API method for setting media source(s) (fixes #44)
|
||||||
- Added poster() API method for setting poster source
|
- Added poster() API method for setting poster source
|
||||||
- Refactored captions logic for manual captions
|
- Refactored captions logic for manual captions
|
||||||
|
|
||||||
## v1.0.21
|
## v1.0.21
|
||||||
|
|
||||||
- Added an <input type="range"> for seeking to improve experience (and support dragging) (fixes #40, #42)
|
- Added an <input type="range"> for seeking to improve experience (and support dragging) (fixes #40, #42)
|
||||||
- Icons for restart and captions improved (and some IDs changed) (fixes #49)
|
- Icons for restart and captions improved (and some IDs changed) (fixes #49)
|
||||||
|
|
||||||
## v1.0.20
|
## v1.0.20
|
||||||
|
|
||||||
- Default controls included (Fixes #45)
|
- Default controls included (Fixes #45)
|
||||||
- Volume changes on `input` as well as `change` (fixes #43)
|
- Volume changes on `input` as well as `change` (fixes #43)
|
||||||
- Fix for undefined Play text
|
- Fix for undefined Play text
|
||||||
- License changed to MIT
|
- License changed to MIT
|
||||||
|
|
||||||
## v1.0.19
|
## v1.0.19
|
||||||
|
|
||||||
- Fixed firefox fullscreen issue (fixes #38)
|
- Fixed firefox fullscreen issue (fixes #38)
|
||||||
|
|
||||||
## v1.0.18
|
## v1.0.18
|
||||||
|
|
||||||
- Added CDN references
|
- Added CDN references
|
||||||
|
|
||||||
## v1.0.17
|
## v1.0.17
|
||||||
|
|
||||||
- SASS support added (thanks to @brunowego)
|
- SASS support added (thanks to @brunowego)
|
||||||
- Docs completely separated to avoid any confusion
|
- Docs completely separated to avoid any confusion
|
||||||
- New gulp tasks (will add more documentation for this)
|
- New gulp tasks (will add more documentation for this)
|
||||||
|
|
||||||
## v1.0.16
|
## v1.0.16
|
||||||
|
|
||||||
- Aria label is now dynamic
|
- Aria label is now dynamic
|
||||||
|
|
||||||
## v1.0.15
|
## v1.0.15
|
||||||
|
|
||||||
- Fix for seek time display in controls
|
- Fix for seek time display in controls
|
||||||
- More documentation for controls html
|
- More documentation for controls html
|
||||||
|
|
||||||
## v1.0.14
|
## v1.0.14
|
||||||
|
|
||||||
- Minor change for bootstrap compatibility
|
- Minor change for bootstrap compatibility
|
||||||
|
|
||||||
## v1.0.13
|
## v1.0.13
|
||||||
|
|
||||||
- Minor tweaks
|
- Minor tweaks
|
||||||
|
|
||||||
## v1.0.12
|
## v1.0.12
|
||||||
|
|
||||||
- Handle native events (issue #34)
|
- Handle native events (issue #34)
|
||||||
|
|
||||||
## v1.0.11
|
## v1.0.11
|
||||||
|
|
||||||
- Bug fixes for fullscreen mode
|
- Bug fixes for fullscreen mode
|
||||||
|
|
||||||
## v1.0.10
|
## v1.0.10
|
||||||
|
|
||||||
- Bower includes src files now
|
- Bower includes src files now
|
||||||
- Folder re-arrangement
|
- Folder re-arrangement
|
||||||
|
|
||||||
## v1.0.9
|
## v1.0.9
|
||||||
|
|
||||||
- Added buffer progress bar
|
- Added buffer progress bar
|
||||||
- Fixed Safari 8 caption track (it needs to be removed from the DOM like in Safari 7)
|
- Fixed Safari 8 caption track (it needs to be removed from the DOM like in Safari 7)
|
||||||
- Added validation (it works or it doesn't basically) of the `html` option passed
|
- Added validation (it works or it doesn't basically) of the `html` option passed
|
||||||
|
|
||||||
## v1.0.8
|
## v1.0.8
|
||||||
|
|
||||||
- Bug fix
|
- Bug fix
|
||||||
|
|
||||||
## v1.0.7
|
## v1.0.7
|
||||||
|
|
||||||
- Storing user selected volume in local storage
|
- Storing user selected volume in local storage
|
||||||
|
|
||||||
## v1.0.6
|
## v1.0.6
|
||||||
|
|
||||||
- Fullscreen fallback for older browsers to use "full window"
|
- Fullscreen fallback for older browsers to use "full window"
|
||||||
|
|
||||||
## v1.0.5
|
## v1.0.5
|
||||||
|
|
||||||
- More minor bug fixes and improvements
|
- More minor bug fixes and improvements
|
||||||
|
|
||||||
## v1.0.4
|
## v1.0.4
|
||||||
|
|
||||||
- Fixed caption legibility issues
|
- Fixed caption legibility issues
|
||||||
|
|
||||||
## v1.0.3
|
## v1.0.3
|
||||||
|
|
||||||
- Minor bug fixes
|
- Minor bug fixes
|
||||||
|
|
||||||
## v1.0.2
|
## v1.0.2
|
||||||
|
|
||||||
- Added OGG to <audio> example for Firefox
|
- Added OGG to <audio> example for Firefox
|
||||||
- Fixed IE11 fullscreen issues
|
- Fixed IE11 fullscreen issues
|
||||||
|
|
||||||
## v1.0.1
|
## v1.0.1
|
||||||
|
|
||||||
- Bug fixes for IE (as per usual)
|
- Bug fixes for IE (as per usual)
|
||||||
- Added CSS hooks for media type
|
- Added CSS hooks for media type
|
||||||
- Return instances of Plyr to the element
|
- Return instances of Plyr to the element
|
||||||
|
|
||||||
## v1.0.0
|
## v1.0.0
|
||||||
|
|
||||||
- Initial release
|
- Initial release
|
||||||
|
202
controls.md
@ -1,27 +1,73 @@
|
|||||||
# Controls
|
# Controls
|
||||||
|
|
||||||
This is the markup that is rendered for the Plyr controls. You can use the default controls or provide a customized version of markup based on your needs.
|
This is the markup that is rendered for the Plyr controls. You can use the default controls or provide a customized version of markup based on your needs. You can pass the following to the `controls` option:
|
||||||
|
|
||||||
## Internationalization using default controls
|
- `Array` of options (this builds the default controls based on your choices)
|
||||||
|
- `String` containing the desired HTML
|
||||||
|
- `Function` that will be executed and should return one of the above
|
||||||
|
|
||||||
|
## Using default controls
|
||||||
|
|
||||||
|
If you want to use the standard controls as they are, you don't need to pass any options. If you want to turn on off controls, here's the full list:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
controls: [
|
||||||
|
'play-large', // The large play button in the center
|
||||||
|
'restart', // Restart playback
|
||||||
|
'rewind', // Rewind by the seek time (default 10 seconds)
|
||||||
|
'play', // Play/pause playback
|
||||||
|
'fast-forward', // Fast forward by the seek time (default 10 seconds)
|
||||||
|
'progress', // The progress bar and scrubber for playback and buffering
|
||||||
|
'current-time', // The current time of playback
|
||||||
|
'duration', // The full duration of the media
|
||||||
|
'mute', // Toggle mute
|
||||||
|
'volume', // Volume control
|
||||||
|
'captions', // Toggle captions
|
||||||
|
'settings', // Settings menu
|
||||||
|
'pip', // Picture-in-picture (currently Safari only)
|
||||||
|
'airplay', // Airplay (currently Safari only)
|
||||||
|
'fullscreen', // Toggle fullscreen
|
||||||
|
];
|
||||||
|
```
|
||||||
|
|
||||||
|
### Internationalization using default controls
|
||||||
|
|
||||||
You can provide an `i18n` object as one of your options when initialising the plugin which we be used when rendering the controls.
|
You can provide an `i18n` object as one of your options when initialising the plugin which we be used when rendering the controls.
|
||||||
|
|
||||||
### Example
|
#### Example
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
i18n: {
|
i18n: {
|
||||||
restart: "Restart",
|
restart: 'Restart',
|
||||||
rewind: "Rewind {seektime} secs",
|
rewind: 'Rewind {seektime} secs',
|
||||||
play: "Play",
|
play: 'Play',
|
||||||
pause: "Pause",
|
pause: 'Pause',
|
||||||
forward: "Forward {seektime} secs",
|
fastForward: 'Forward {seektime} secs',
|
||||||
buffered: "buffered",
|
seek: 'Seek',
|
||||||
currentTime: "Current time",
|
played: 'Played',
|
||||||
duration: "Duration",
|
buffered: 'Buffered',
|
||||||
volume: "Volume",
|
currentTime: 'Current time',
|
||||||
toggleMute: "Toggle Mute",
|
duration: 'Duration',
|
||||||
toggleCaptions: "Toggle Captions",
|
volume: 'Volume',
|
||||||
toggleFullscreen: "Toggle Fullscreen"
|
mute: 'Mute',
|
||||||
|
unmute: 'Unmute',
|
||||||
|
enableCaptions: 'Enable captions',
|
||||||
|
disableCaptions: 'Disable captions',
|
||||||
|
enterFullscreen: 'Enter fullscreen',
|
||||||
|
exitFullscreen: 'Exit fullscreen',
|
||||||
|
frameTitle: 'Player for {title}',
|
||||||
|
captions: 'Captions',
|
||||||
|
settings: 'Settings',
|
||||||
|
speed: 'Speed',
|
||||||
|
normal: 'Normal',
|
||||||
|
quality: 'Quality',
|
||||||
|
loop: 'Loop',
|
||||||
|
start: 'Start',
|
||||||
|
end: 'End',
|
||||||
|
all: 'All',
|
||||||
|
reset: 'Reset',
|
||||||
|
disabled: 'Disabled',
|
||||||
|
advertisement: 'Ad',
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -29,85 +75,77 @@ Note: `{seektime}` will be replaced with your configured seek time or the defaul
|
|||||||
|
|
||||||
## Using custom HTML
|
## Using custom HTML
|
||||||
|
|
||||||
You can specify the HTML for the controls using the `html` option.
|
You can specify the HTML as a `String` or your `Function` return for the controls using the `controls` option.
|
||||||
|
|
||||||
The classes and data attributes used in your template should match the `selectors` option.
|
The classes and data attributes used in your template should match the `selectors` option if you change any.
|
||||||
|
|
||||||
You need to add several placeholders to your html template that are replaced when rendering:
|
You need to add several placeholders to your HTML template that are replaced when rendering:
|
||||||
|
|
||||||
- `{id}` - the dynamically generated ID for the player (for form controls)
|
- `{id}` - the dynamically generated ID for the player (for form controls)
|
||||||
- `{seektime}` - the seek time specified in options for fast forward and rewind
|
- `{seektime}` - the seek time specified in options for fast forward and rewind
|
||||||
- `{title}` - the title of your media, if specified
|
- `{title}` - the title of your media, if specified
|
||||||
|
|
||||||
You can include only the controls you need when specifying custom html.
|
### Limitations
|
||||||
|
|
||||||
|
- Currently the settings menus are not supported with custom controls HTML
|
||||||
|
- AirPlay and PiP buttons can be added but you will have to manage feature detection
|
||||||
|
|
||||||
### Example
|
### Example
|
||||||
|
|
||||||
This is an example `html` option with all controls.
|
Here's an example of custom controls markup (this is just all default controls shown).
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
var controls = ["<div class='plyr__controls'>",
|
const controls = `
|
||||||
"<button type='button' data-plyr='restart'>",
|
<div class="plyr__controls">
|
||||||
"<svg><use xlink:href='#plyr-restart'></use></svg>",
|
<button type="button" class="plyr__control" data-plyr="restart">
|
||||||
"<span class='plyr__sr-only'>Restart</span>",
|
<svg role="presentation"><use xlink:href="#plyr-restart"></use></svg>
|
||||||
"</button>",
|
<span class="plyr__tooltip" role="tooltip">Restart</span>
|
||||||
"<button type='button' data-plyr='rewind'>",
|
</button>
|
||||||
"<svg><use xlink:href='#plyr-rewind'></use></svg>",
|
<button type="button" class="plyr__control" data-plyr="rewind">
|
||||||
"<span class='plyr__sr-only'>Rewind {seektime} secs</span>",
|
<svg role="presentation"><use xlink:href="#plyr-rewind"></use></svg>
|
||||||
"</button>",
|
<span class="plyr__tooltip" role="tooltip">Rewind {seektime} secs</span>
|
||||||
"<button type='button' data-plyr='play'>",
|
</button>
|
||||||
"<svg><use xlink:href='#plyr-play'></use></svg>",
|
<button type="button" class="plyr__control" aria-label="Play, {title}" data-plyr="play">
|
||||||
"<span class='plyr__sr-only'>Play</span>",
|
<svg class="icon--pressed" role="presentation"><use xlink:href="#plyr-pause"></use></svg>
|
||||||
"</button>",
|
<svg class="icon--not-pressed" role="presentation"><use xlink:href="#plyr-play"></use></svg>
|
||||||
"<button type='button' data-plyr='pause'>",
|
<span class="label--pressed plyr__tooltip" role="tooltip">Pause</span>
|
||||||
"<svg><use xlink:href='#plyr-pause'></use></svg>",
|
<span class="label--not-pressed plyr__tooltip" role="tooltip">Play</span>
|
||||||
"<span class='plyr__sr-only'>Pause</span>",
|
</button>
|
||||||
"</button>",
|
<button type="button" class="plyr__control" data-plyr="fast-forward">
|
||||||
"<button type='button' data-plyr='fast-forward'>",
|
<svg role="presentation"><use xlink:href="#plyr-fast-forward"></use></svg>
|
||||||
"<svg><use xlink:href='#plyr-fast-forward'></use></svg>",
|
<span class="plyr__tooltip" role="tooltip">Forward {seektime} secs</span>
|
||||||
"<span class='plyr__sr-only'>Forward {seektime} secs</span>",
|
</button>
|
||||||
"</button>",
|
<div class="plyr__progress">
|
||||||
"<span class='plyr__progress'>",
|
<input data-plyr="seek" type="range" min="0" max="100" step="0.01" value="0" aria-label="Seek">
|
||||||
"<label for='seek{id}' class='plyr__sr-only'>Seek</label>",
|
<progress class="plyr__progress__buffer" min="0" max="100" value="0">% buffered</progress>
|
||||||
"<input id='seek{id}' class='plyr__progress--seek' type='range' min='0' max='100' step='0.1' value='0' data-plyr='seek'>",
|
<span role="tooltip" class="plyr__tooltip">00:00</span>
|
||||||
"<progress class='plyr__progress--played' max='100' value='0' role='presentation'></progress>",
|
</div>
|
||||||
"<progress class='plyr__progress--buffer' max='100' value='0'>",
|
<div class="plyr__time plyr__time--current" aria-label="Current time">00:00</div>
|
||||||
"<span>0</span>% buffered",
|
<div class="plyr__time plyr__time--duration" aria-label="Duration">00:00</div>
|
||||||
"</progress>",
|
<button type="button" class="plyr__control" aria-label="Mute" data-plyr="mute">
|
||||||
"<span class='plyr__tooltip'>00:00</span>",
|
<svg class="icon--pressed" role="presentation"><use xlink:href="#plyr-muted"></use></svg>
|
||||||
"</span>",
|
<svg class="icon--not-pressed" role="presentation"><use xlink:href="#plyr-volume"></use></svg>
|
||||||
"<span class='plyr__time'>",
|
<span class="label--pressed plyr__tooltip" role="tooltip">Unmute</span>
|
||||||
"<span class='plyr__sr-only'>Current time</span>",
|
<span class="label--not-pressed plyr__tooltip" role="tooltip">Mute</span>
|
||||||
"<span class='plyr__time--current'>00:00</span>",
|
</button>
|
||||||
"</span>",
|
<div class="plyr__volume">
|
||||||
"<span class='plyr__time'>",
|
<input data-plyr="volume" type="range" min="0" max="1" step="0.05" value="1" autocomplete="off" aria-label="Volume">
|
||||||
"<span class='plyr__sr-only'>Duration</span>",
|
</div>
|
||||||
"<span class='plyr__time--duration'>00:00</span>",
|
<button type="button" class="plyr__control" data-plyr="captions">
|
||||||
"</span>",
|
<svg class="icon--pressed" role="presentation"><use xlink:href="#plyr-captions-on"></use></svg>
|
||||||
"<button type='button' data-plyr='mute'>",
|
<svg class="icon--not-pressed" role="presentation"><use xlink:href="#plyr-captions-off"></use></svg>
|
||||||
"<svg class='icon--muted'><use xlink:href='#plyr-muted'></use></svg>",
|
<span class="label--pressed plyr__tooltip" role="tooltip">Disable captions</span>
|
||||||
"<svg><use xlink:href='#plyr-volume'></use></svg>",
|
<span class="label--not-pressed plyr__tooltip" role="tooltip">Enable captions</span>
|
||||||
"<span class='plyr__sr-only'>Toggle Mute</span>",
|
</button>
|
||||||
"</button>",
|
<button type="button" class="plyr__control" data-plyr="fullscreen">
|
||||||
"<span class='plyr__volume'>",
|
<svg class="icon--pressed" role="presentation"><use xlink:href="#plyr-exit-fullscreen"></use></svg>
|
||||||
"<label for='volume{id}' class='plyr__sr-only'>Volume</label>",
|
<svg class="icon--not-pressed" role="presentation"><use xlink:href="#plyr-enter-fullscreen"></use></svg>
|
||||||
"<input id='volume{id}' class='plyr__volume--input' type='range' min='0' max='10' value='5' data-plyr='volume'>",
|
<span class="label--pressed plyr__tooltip" role="tooltip">Exit fullscreen</span>
|
||||||
"<progress class='plyr__volume--display' max='10' value='0' role='presentation'></progress>",
|
<span class="label--not-pressed plyr__tooltip" role="tooltip">Enter fullscreen</span>
|
||||||
"</span>",
|
</button>
|
||||||
"<button type='button' data-plyr='captions'>",
|
</div>
|
||||||
"<svg class='icon--captions-on'><use xlink:href='#plyr-captions-on'></use></svg>",
|
`;
|
||||||
"<svg><use xlink:href='#plyr-captions-off'></use></svg>",
|
|
||||||
"<span class='plyr__sr-only'>Toggle Captions</span>",
|
|
||||||
"</button>",
|
|
||||||
"<button type='button' data-plyr='fullscreen'>",
|
|
||||||
"<svg class='icon--exit-fullscreen'><use xlink:href='#plyr-exit-fullscreen'></use></svg>",
|
|
||||||
"<svg><use xlink:href='#plyr-enter-fullscreen'></use></svg>",
|
|
||||||
"<span class='plyr__sr-only'>Toggle Fullscreen</span>",
|
|
||||||
"</button>",
|
|
||||||
"</div>"].join("");
|
|
||||||
|
|
||||||
// Setup the player
|
// Setup the player
|
||||||
plyr.setup('.js-player', {
|
const player = new Plyr('#player', { controls });
|
||||||
html: controls
|
|
||||||
});
|
|
||||||
```
|
```
|
||||||
|
2
demo/dist/demo.css
vendored
4390
demo/dist/demo.js
vendored
1
demo/dist/demo.js.map
vendored
Normal file
2
demo/dist/demo.min.js
vendored
Normal file
1
demo/dist/demo.min.js.map
vendored
Normal file
1
demo/dist/demo.svg
vendored
@ -1 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg"><symbol id="icon-github" viewBox="0 0 16 16"><path fill-rule="evenodd" clip-rule="evenodd" d="M8 .2c-4.4 0-8 3.6-8 8 0 3.5 2.3 6.5 5.5 7.6.4.1.5-.2.5-.4V14c-2.2.5-2.7-1-2.7-1-.4-.9-.9-1.2-.9-1.2-.7-.5.1-.5.1-.5.8.1 1.2.8 1.2.8.7 1.3 1.9.9 2.3.7.1-.5.3-.9.5-1.1-1.8-.2-3.6-.9-3.6-4 0-.9.3-1.6.8-2.1-.1-.2-.4-1 .1-2.1 0 0 .7-.2 2.2.8.6-.2 1.3-.3 2-.3s1.4.1 2 .3c1.5-1 2.2-.8 2.2-.8.4 1.1.2 1.9.1 2.1.5.6.8 1.3.8 2.1 0 3.1-1.9 3.7-3.7 3.9.3.4.6.9.6 1.6v2.2c0 .2.1.5.6.4 3.2-1.1 5.5-4.1 5.5-7.6-.1-4.4-3.7-8-8.1-8z"/></symbol><symbol id="icon-twitter" viewBox="0 0 16 16"><title>Twitter</title><path d="M16 3c-.6.3-1.2.4-1.9.5.7-.4 1.2-1 1.4-1.8-.6.4-1.3.6-2.1.8-.6-.6-1.5-1-2.4-1-1.7 0-3.2 1.5-3.2 3.3 0 .3 0 .5.1.7-2.7-.1-5.2-1.4-6.8-3.4-.3.5-.4 1-.4 1.7 0 1.1.6 2.1 1.5 2.7-.5 0-1-.2-1.5-.4C.7 7.7 1.8 9 3.3 9.3c-.3.1-.6.1-.9.1-.2 0-.4 0-.6-.1.4 1.3 1.6 2.3 3.1 2.3-1.1.9-2.5 1.4-4.1 1.4H0c1.5.9 3.2 1.5 5 1.5 6 0 9.3-5 9.3-9.3v-.4C15 4.3 15.6 3.7 16 3z"/></symbol><symbol id="icon-vimeo" viewBox="0 0 16 16"><path d="M16 4.3c-.1 1.6-1.2 3.7-3.3 6.4-2.2 2.8-4 4.2-5.5 4.2-.9 0-1.7-.9-2.4-2.6C4 9.9 3.4 5 2 5c-.1 0-.5.3-1.2.8l-.8-1c.8-.7 3.5-3.4 4.7-3.5 1.2-.1 2 .7 2.3 2.5.3 2 .8 6.1 1.8 6.1.9 0 2.5-3.4 2.6-4 .1-.9-.3-1.9-2.3-1.1.8-2.6 2.3-3.8 4.5-3.8 1.7.1 2.5 1.2 2.4 3.3z"/></symbol><symbol id="icon-youtube" viewBox="0 0 16 16"><path d="M15.8 4.8c-.2-1.3-.8-2.2-2.2-2.4C11.4 2 8 2 8 2s-3.4 0-5.6.4C1 2.6.3 3.5.2 4.8 0 6.1 0 8 0 8s0 1.9.2 3.2c.2 1.3.8 2.2 2.2 2.4C4.6 14 8 14 8 14s3.4 0 5.6-.4c1.4-.3 2-1.1 2.2-2.4C16 9.9 16 8 16 8s0-1.9-.2-3.2zM6 11V5l5 3-5 3z"/></symbol></svg>
|
|
Before Width: | Height: | Size: 1.7 KiB |
1
demo/dist/error.css
vendored
Normal file
@ -6,19 +6,25 @@
|
|||||||
<title>Doh. Looks like something went wrong.</title>
|
<title>Doh. Looks like something went wrong.</title>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
|
||||||
|
<!-- Icons -->
|
||||||
|
<link rel="icon" href="https://cdn.plyr.io/static/icons/favicon.ico">
|
||||||
|
<link rel="icon" type="image/png" href="https://cdn.plyr.io/static/icons/32x32.png" sizes="32x32">
|
||||||
|
<link rel="icon" type="image/png" href="https://cdn.plyr.io/static/icons/16x16.png" sizes="16x16">
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="https://cdn.plyr.io/static/icons/180x180.png">
|
||||||
|
|
||||||
<!-- Docs styles -->
|
<!-- Docs styles -->
|
||||||
<link rel="stylesheet" href="dist/demo.css">
|
<link rel="stylesheet" href="dist/error.css?v=2">
|
||||||
|
|
||||||
<!-- Preload -->
|
<!-- Preload -->
|
||||||
<link rel="preload" as="font" crossorigin type="font/woff2" href="https://cdn.plyr.io/static/fonts/avenir-medium.woff2">
|
<link rel="preload" as="font" crossorigin type="font/woff2" href="https://cdn.plyr.io/static/fonts/gordita-medium.woff2">
|
||||||
<link rel="preload" as="font" crossorigin type="font/woff2" href="https://cdn.plyr.io/static/fonts/avenir-bold.woff2">
|
<link rel="preload" as="font" crossorigin type="font/woff2" href="https://cdn.plyr.io/static/fonts/gordita-bold.woff2">
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<main>
|
<main>
|
||||||
<h1>Doh.</h1>
|
<h1>Doh.</h1>
|
||||||
<p>Looks like something went wrong.</p>
|
<p>Looks like something went wrong.</p>
|
||||||
<a href="http://plyr.io" class="btn btn--primary">Back to plyr.io</a>
|
<a href="javascript:history.back()" class="button">Go back</a>
|
||||||
</main>
|
</main>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
|
213
demo/index.html
@ -3,101 +3,188 @@
|
|||||||
|
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<title>Plyr - A simple HTML5 media player</title>
|
<title>Plyr - A simple, customizable HTML5 Video, Audio, YouTube and Vimeo player</title>
|
||||||
<meta name="description" content="A simple HTML5 media player with custom controls and WebVTT captions.">
|
<meta name="description" property="og:description" content="A simple HTML5 media player with custom controls and WebVTT captions.">
|
||||||
<meta name="author" content="Sam Potts">
|
<meta name="author" content="Sam Potts">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
|
||||||
<!-- Styles -->
|
<!-- Icons -->
|
||||||
<link rel="stylesheet" href="../dist/plyr.css">
|
<link rel="icon" href="https://cdn.plyr.io/static/icons/favicon.ico">
|
||||||
|
<link rel="icon" type="image/png" href="https://cdn.plyr.io/static/icons/32x32.png" sizes="32x32">
|
||||||
|
<link rel="icon" type="image/png" href="https://cdn.plyr.io/static/icons/16x16.png" sizes="16x16">
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="https://cdn.plyr.io/static/icons/180x180.png">
|
||||||
|
|
||||||
|
<!-- Opengraph -->
|
||||||
|
<meta property="og:title" content="Plyr - A simple, customizable HTML5 Video, Audio, YouTube and Vimeo player">
|
||||||
|
<meta property="og:site_name" content="Plyr">
|
||||||
|
<meta property="og:url" content="https://plyr.io">
|
||||||
|
<meta property="og:image" content="https://cdn.plyr.io/static/icons/1200x630.png">
|
||||||
|
|
||||||
|
<!-- Twitter -->
|
||||||
|
<meta name="twitter:card" content="summary">
|
||||||
|
<meta name="twitter:site" content="@sam_potts">
|
||||||
|
<meta name="twitter:creator" content="@sam_potts">
|
||||||
|
<meta name="twitter:card" content="summary_large_image">
|
||||||
|
|
||||||
<!-- Docs styles -->
|
<!-- Docs styles -->
|
||||||
<link rel="stylesheet" href="dist/demo.css">
|
<link rel="stylesheet" href="dist/demo.css?v=2">
|
||||||
|
|
||||||
<!-- Preload -->
|
<!-- Preload -->
|
||||||
<link rel="preload" as="font" crossorigin type="font/woff2" href="https://cdn.plyr.io/static/fonts/avenir-medium.woff2">
|
<link rel="preload" as="font" crossorigin type="font/woff2" href="https://cdn.plyr.io/static/fonts/gordita-medium.woff2">
|
||||||
<link rel="preload" as="font" crossorigin type="font/woff2" href="https://cdn.plyr.io/static/fonts/avenir-bold.woff2">
|
<link rel="preload" as="font" crossorigin type="font/woff2" href="https://cdn.plyr.io/static/fonts/gordita-bold.woff2">
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
<div class="grid">
|
||||||
<header>
|
<header>
|
||||||
<h1>Plyr</h1>
|
<h1>Plyr</h1>
|
||||||
<p>A simple, accessible HTML5 media player by <a href="https://twitter.com/sam_potts" target="_blank">@sam_potts</a></p>
|
<p>A simple, accessible and customisable media player for
|
||||||
<nav>
|
<button type="button" class="faux-link" data-source="video">
|
||||||
<ul>
|
|
||||||
<li>
|
|
||||||
<a href="https://github.com/sampotts/plyr" target="_blank" class="btn btn--large btn--primary" data-shr-network="github">
|
|
||||||
<svg class="icon">
|
<svg class="icon">
|
||||||
<use xlink:href="#icon-github" />
|
<title>HTML5</title>
|
||||||
</svg>Download on GitHub
|
<path d="M14.738.326C14.548.118 14.28 0 14 0H2c-.28 0-.55.118-.738.326S.98.81 1.004 1.09l1 11c.03.317.208.603.48.767l5 3c.16.095.338.143.516.143s.356-.048.515-.143l5-3c.273-.164.452-.45.48-.767l1-11c.026-.28-.067-.557-.257-.764zM12 4H6v2h6v5.72l-4 1.334-4-1.333V9h2v1.28l2 .666 2-.667V8H4V2h8v2z"></path>
|
||||||
</a>
|
</svg>Video</button>,
|
||||||
</li>
|
<button type="button" class="faux-link" data-source="audio">
|
||||||
<li>
|
|
||||||
<a href="https://twitter.com/intent/tweet?text=A+simple+HTML5+media+player+with+custom+controls+and+WebVTT+captions.&url=http%3A%2F%2Fplyr.io&via=Sam_Potts"
|
|
||||||
target="_blank" class="btn btn--large btn--twitter" data-shr-network="twitter">
|
|
||||||
<svg class="icon">
|
<svg class="icon">
|
||||||
<use xlink:href="#icon-twitter" />
|
<title>HTML5</title>
|
||||||
</svg>Tweet
|
<path d="M14.738.326C14.548.118 14.28 0 14 0H2c-.28 0-.55.118-.738.326S.98.81 1.004 1.09l1 11c.03.317.208.603.48.767l5 3c.16.095.338.143.516.143s.356-.048.515-.143l5-3c.273-.164.452-.45.48-.767l1-11c.026-.28-.067-.557-.257-.764zM12 4H6v2h6v5.72l-4 1.334-4-1.333V9h2v1.28l2 .666 2-.667V8H4V2h8v2z"></path>
|
||||||
|
</svg>Audio</button>,
|
||||||
|
<button type="button" class="faux-link" data-source="youtube">
|
||||||
|
<svg class="icon" role="presentation">
|
||||||
|
<title>YouTube</title>
|
||||||
|
<path d="M15.8,4.8c-0.2-1.3-0.8-2.2-2.2-2.4C11.4,2,8,2,8,2S4.6,2,2.4,2.4C1,2.6,0.3,3.5,0.2,4.8C0,6.1,0,8,0,8
|
||||||
|
s0,1.9,0.2,3.2c0.2,1.3,0.8,2.2,2.2,2.4C4.6,14,8,14,8,14s3.4,0,5.6-0.4c1.4-0.3,2-1.1,2.2-2.4C16,9.9,16,8,16,8S16,6.1,15.8,4.8z
|
||||||
|
M6,11V5l5,3L6,11z"></path>
|
||||||
|
</svg>YouTube</button> and
|
||||||
|
<button type="button" class="faux-link" data-source="vimeo">
|
||||||
|
<svg class="icon" role="presentation">
|
||||||
|
<title>Vimeo</title>
|
||||||
|
<path d="M16,4.3c-0.1,1.6-1.2,3.7-3.3,6.4c-2.2,2.8-4,4.2-5.5,4.2c-0.9,0-1.7-0.9-2.4-2.6C4,9.9,3.4,5,2,5
|
||||||
|
C1.9,5,1.5,5.3,0.8,5.8L0,4.8c0.8-0.7,3.5-3.4,4.7-3.5C5.9,1.2,6.7,2,7,3.8c0.3,2,0.8,6.1,1.8,6.1c0.9,0,2.5-3.4,2.6-4
|
||||||
|
c0.1-0.9-0.3-1.9-2.3-1.1c0.8-2.6,2.3-3.8,4.5-3.8C15.3,1.1,16.1,2.2,16,4.3z"></path>
|
||||||
|
</svg>Vimeo</button>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>Premium video monitization from
|
||||||
|
<a href="https://vi.ai/publisher-video-monetization/?aid=plyrio" target="_blank" class="no-border">
|
||||||
|
<img src="https://cdn.plyr.io/static/vi-logo-24x24.svg" alt="ai.vi">
|
||||||
|
<span class="sr-only">ai.vi</span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</p>
|
||||||
</ul>
|
|
||||||
</nav>
|
<div class="call-to-action">
|
||||||
|
<span class="button--with-count">
|
||||||
|
<a href="https://github.com/sampotts/plyr" target="_blank" class="button" data-shr-network="github">
|
||||||
|
<svg class="icon" role="presentation">
|
||||||
|
<title>GitHub</title>
|
||||||
|
<path d="M8,0.2c-4.4,0-8,3.6-8,8c0,3.5,2.3,6.5,5.5,7.6
|
||||||
|
C5.9,15.9,6,15.6,6,15.4c0-0.2,0-0.7,0-1.4C3.8,14.5,3.3,13,3.3,13c-0.4-0.9-0.9-1.2-0.9-1.2c-0.7-0.5,0.1-0.5,0.1-0.5
|
||||||
|
c0.8,0.1,1.2,0.8,1.2,0.8C4.4,13.4,5.6,13,6,12.8c0.1-0.5,0.3-0.9,0.5-1.1c-1.8-0.2-3.6-0.9-3.6-4c0-0.9,0.3-1.6,0.8-2.1
|
||||||
|
c-0.1-0.2-0.4-1,0.1-2.1c0,0,0.7-0.2,2.2,0.8c0.6-0.2,1.3-0.3,2-0.3c0.7,0,1.4,0.1,2,0.3c1.5-1,2.2-0.8,2.2-0.8
|
||||||
|
c0.4,1.1,0.2,1.9,0.1,2.1c0.5,0.6,0.8,1.3,0.8,2.1c0,3.1-1.9,3.7-3.7,3.9C9.7,12,10,12.5,10,13.2c0,1.1,0,1.9,0,2.2
|
||||||
|
c0,0.2,0.1,0.5,0.6,0.4c3.2-1.1,5.5-4.1,5.5-7.6C16,3.8,12.4,0.2,8,0.2z"></path>
|
||||||
|
</svg>
|
||||||
|
Download on GitHub
|
||||||
|
</a>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<main role="main" id="main">
|
<main>
|
||||||
<nav class="btn__bar">
|
<video controls crossorigin playsinline poster="https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-HD.jpg" id="player">
|
||||||
<ul>
|
|
||||||
<li class="active">
|
|
||||||
<button type="button" class="btn" data-source="video">Video</button>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<button type="button" class="btn" data-source="audio">Audio</button>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<button type="button" class="btn btn--youtube" data-source="youtube"><svg class="icon"><use xlink:href="#icon-youtube"/></svg>YouTube</button>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<button type="button" class="btn btn--vimeo" data-source="vimeo"><svg class="icon"><use xlink:href="#icon-vimeo"/></svg>Vimeo</button>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</nav>
|
|
||||||
<section>
|
|
||||||
<video poster="https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-HD.jpg?v1" controls crossorigin>
|
|
||||||
<!-- Video files -->
|
<!-- Video files -->
|
||||||
<source src="https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-HD.mp4" type="video/mp4">
|
<source src="https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-576p.mp4" type="video/mp4" size="576">
|
||||||
<source src="https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-HD.webm" type="video/webm">
|
<source src="https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-720p.mp4" type="video/mp4" size="720">
|
||||||
|
<source src="https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-1080p.mp4" type="video/mp4" size="1080">
|
||||||
|
<source src="https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-1440p.mp4" type="video/mp4" size="1440">
|
||||||
|
|
||||||
<!-- Text track file -->
|
<!-- Caption files -->
|
||||||
<track kind="captions" label="English" srclang="en" src="https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-HD.en.vtt"
|
<track kind="captions" label="English" srclang="en" src="https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-HD.en.vtt"
|
||||||
default>
|
default>
|
||||||
|
<track kind="captions" label="Français" srclang="fr" src="https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-HD.fr.vtt">
|
||||||
|
|
||||||
<!-- Fallback for browsers that don't support the <video> element -->
|
<!-- Fallback for browsers that don't support the <video> element -->
|
||||||
<a href="https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-HD.mp4" download>Download</a>
|
<a href="https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-576p.mp4" download>Download</a>
|
||||||
</video>
|
</video>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li class="plyr__cite plyr__cite--video"><small><a href="http://viewfromabluemoon.com/" target="_blank">View From A Blue Moon</a> © Brainfarm</small></li>
|
<li class="plyr__cite plyr__cite--video" hidden>
|
||||||
<li class="plyr__cite plyr__cite--audio"><small><a href="http://www.kishibashi.com/" target="_blank">Kishi Bashi – “It All Began With A Burst”</a> © Kishi Bashi</small></li>
|
<small>
|
||||||
<li class="plyr__cite plyr__cite--youtube"><small><a href="https://www.youtube.com/watch?v=bTqVqk7FSmY" target="_blank">View From A Blue Moon</a> on <span class="color--youtube"><svg class="icon"><use xlink:href="#icon-youtube"/></svg>YouTube</span></small></li>
|
<svg class="icon">
|
||||||
<li class="plyr__cite plyr__cite--vimeo"><small><a href="https://vimeo.com/ondemand/viewfromabluemoon4k" target="_blank">View From A Blue Moon</a> on <span class="color--vimeo"><svg class="icon"><use xlink:href="#icon-vimeo"/></svg>Vimeo</span></small></li>
|
<title>HTML5</title>
|
||||||
|
<path d="M14.738.326C14.548.118 14.28 0 14 0H2c-.28 0-.55.118-.738.326S.98.81 1.004 1.09l1 11c.03.317.208.603.48.767l5 3c.16.095.338.143.516.143s.356-.048.515-.143l5-3c.273-.164.452-.45.48-.767l1-11c.026-.28-.067-.557-.257-.764zM12 4H6v2h6v5.72l-4 1.334-4-1.333V9h2v1.28l2 .666 2-.667V8H4V2h8v2z"></path>
|
||||||
|
</svg>
|
||||||
|
<a href="https://itunes.apple.com/au/movie/view-from-a-blue-moon/id1041586323" target="_blank">View From A Blue Moon</a> © Brainfarm
|
||||||
|
</small>
|
||||||
|
</li>
|
||||||
|
<li class="plyr__cite plyr__cite--audio" hidden>
|
||||||
|
<small>
|
||||||
|
<svg class="icon" title="HTML5">
|
||||||
|
<title>HTML5</title>
|
||||||
|
<path d="M14.738.326C14.548.118 14.28 0 14 0H2c-.28 0-.55.118-.738.326S.98.81 1.004 1.09l1 11c.03.317.208.603.48.767l5 3c.16.095.338.143.516.143s.356-.048.515-.143l5-3c.273-.164.452-.45.48-.767l1-11c.026-.28-.067-.557-.257-.764zM12 4H6v2h6v5.72l-4 1.334-4-1.333V9h2v1.28l2 .666 2-.667V8H4V2h8v2z"></path>
|
||||||
|
</svg>
|
||||||
|
<a href="http://www.kishibashi.com/" target="_blank">Kishi Bashi – “It All Began With A Burst”</a> © Kishi Bashi
|
||||||
|
</small>
|
||||||
|
</li>
|
||||||
|
<li class="plyr__cite plyr__cite--youtube" hidden>
|
||||||
|
<small>
|
||||||
|
<a href="https://www.youtube.com/watch?v=bTqVqk7FSmY" target="_blank">View From A Blue Moon</a> on
|
||||||
|
<span class="color--youtube">
|
||||||
|
<svg class="icon" role="presentation">
|
||||||
|
<title>YouTube</title>
|
||||||
|
<path d="M15.8,4.8c-0.2-1.3-0.8-2.2-2.2-2.4C11.4,2,8,2,8,2S4.6,2,2.4,2.4C1,2.6,0.3,3.5,0.2,4.8C0,6.1,0,8,0,8
|
||||||
|
s0,1.9,0.2,3.2c0.2,1.3,0.8,2.2,2.2,2.4C4.6,14,8,14,8,14s3.4,0,5.6-0.4c1.4-0.3,2-1.1,2.2-2.4C16,9.9,16,8,16,8S16,6.1,15.8,4.8z
|
||||||
|
M6,11V5l5,3L6,11z"></path>
|
||||||
|
</svg>YouTube
|
||||||
|
</span>
|
||||||
|
</small>
|
||||||
|
</li>
|
||||||
|
<li class="plyr__cite plyr__cite--vimeo" hidden>
|
||||||
|
<small>
|
||||||
|
<a href="https://vimeo.com/76979871" target="_blank">The New Vimeo Player</a> on
|
||||||
|
<span class="color--vimeo">
|
||||||
|
<svg class="icon" role="presentation">
|
||||||
|
<title>Vimeo</title>
|
||||||
|
<path d="M16,4.3c-0.1,1.6-1.2,3.7-3.3,6.4c-2.2,2.8-4,4.2-5.5,4.2c-0.9,0-1.7-0.9-2.4-2.6C4,9.9,3.4,5,2,5
|
||||||
|
C1.9,5,1.5,5.3,0.8,5.8L0,4.8c0.8-0.7,3.5-3.4,4.7-3.5C5.9,1.2,6.7,2,7,3.8c0.3,2,0.8,6.1,1.8,6.1c0.9,0,2.5-3.4,2.6-4
|
||||||
|
c0.1-0.9-0.3-1.9-2.3-1.1c0.8-2.6,2.3-3.8,4.5-3.8C15.3,1.1,16.1,2.2,16,4.3z"></path>
|
||||||
|
</svg>Vimeo
|
||||||
|
</span>
|
||||||
|
</small>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</section>
|
|
||||||
</main>
|
</main>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<aside>
|
||||||
|
<svg class="icon">
|
||||||
|
<title>Twitter</title>
|
||||||
|
<path d="M16,3c-0.6,0.3-1.2,0.4-1.9,0.5c0.7-0.4,1.2-1,1.4-1.8c-0.6,0.4-1.3,0.6-2.1,0.8c-0.6-0.6-1.5-1-2.4-1
|
||||||
|
C9.3,1.5,7.8,3,7.8,4.8c0,0.3,0,0.5,0.1,0.7C5.2,5.4,2.7,4.1,1.1,2.1c-0.3,0.5-0.4,1-0.4,1.7c0,1.1,0.6,2.1,1.5,2.7
|
||||||
|
c-0.5,0-1-0.2-1.5-0.4c0,0,0,0,0,0c0,1.6,1.1,2.9,2.6,3.2C3,9.4,2.7,9.4,2.4,9.4c-0.2,0-0.4,0-0.6-0.1c0.4,1.3,1.6,2.3,3.1,2.3
|
||||||
|
c-1.1,0.9-2.5,1.4-4.1,1.4c-0.3,0-0.5,0-0.8,0c1.5,0.9,3.2,1.5,5,1.5c6,0,9.3-5,9.3-9.3c0-0.1,0-0.3,0-0.4C15,4.3,15.6,3.7,16,3z"></path>
|
||||||
|
</svg>
|
||||||
|
<p>If you think Plyr's good,
|
||||||
|
<a href="https://twitter.com/intent/tweet?text=A+simple+HTML5+media+player+with+custom+controls+and+WebVTT+captions.&url=http%3A%2F%2Fplyr.io&via=Sam_Potts"
|
||||||
|
target="_blank" data-shr-network="twitter">tweet it</a>
|
||||||
|
</p>
|
||||||
|
</aside>
|
||||||
|
|
||||||
|
<!-- Polyfills -->
|
||||||
|
<script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=es6,Array.prototype.includes,CustomEvent,Object.entries,Object.values,URL"
|
||||||
|
crossorigin="anonymous"></script>
|
||||||
|
|
||||||
<!-- Plyr core script -->
|
<!-- Plyr core script -->
|
||||||
<script src="../dist/plyr.js"></script>
|
<script src="../dist/plyr.js" crossorigin="anonymous"></script>
|
||||||
|
|
||||||
<!-- Docs script -->
|
|
||||||
<script src="dist/demo.js"></script>
|
|
||||||
|
|
||||||
<!-- Rangetouch to fix <input type="range"> on touch devices (see https://rangetouch.com) -->
|
|
||||||
<script src="https://cdn.rangetouch.com/1.0.1/rangetouch.js" async></script>
|
|
||||||
|
|
||||||
<!-- Sharing libary (https://shr.one) -->
|
<!-- Sharing libary (https://shr.one) -->
|
||||||
<script src="https://cdn.shr.one/1.0.1/shr.js"></script>
|
<script src="https://cdn.shr.one/1.0.1/shr.js" crossorigin="anonymous"></script>
|
||||||
<script>
|
|
||||||
if (window.shr) { window.shr.setup({ count: { classname: 'btn__count' } }); }
|
<!-- Rangetouch to fix <input type="range"> on touch devices (see https://rangetouch.com) -->
|
||||||
</script>
|
<script src="https://cdn.rangetouch.com/1.0.1/rangetouch.js" async crossorigin="anonymous"></script>
|
||||||
|
|
||||||
|
<!-- Docs script -->
|
||||||
|
<script src="dist/demo.js" crossorigin="anonymous"></script>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
29
demo/media/View_From_A_Blue_Moon_Trailer-HD.en.vtt
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
WEBVTT FILE
|
||||||
|
|
||||||
|
1
|
||||||
|
00:00:09.500 --> 00:00:12.000
|
||||||
|
The ocean floor rises 5 miles to the shores
|
||||||
|
|
||||||
|
2
|
||||||
|
00:00:12.001 --> 00:00:16.500
|
||||||
|
of what people call, the seven mile miracle
|
||||||
|
|
||||||
|
3
|
||||||
|
00:00:25.500 --> 00:00:28.000
|
||||||
|
What would it be like to be born on this island?
|
||||||
|
|
||||||
|
4
|
||||||
|
00:00:32.500 --> 00:00:34.500
|
||||||
|
To grow up on these shores
|
||||||
|
|
||||||
|
5
|
||||||
|
00:00:37.500 --> 00:00:40.000
|
||||||
|
To witness this water, every day
|
||||||
|
|
||||||
|
6
|
||||||
|
00:00:43.500 --> 00:00:46.000
|
||||||
|
You're about to meet someone, who did
|
||||||
|
|
||||||
|
7
|
||||||
|
00:02:45.500 --> 00:02:49.000
|
||||||
|
This is a film about John John Florence
|
29
demo/media/View_From_A_Blue_Moon_Trailer-HD.fr.vtt
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
WEBVTT FILE
|
||||||
|
|
||||||
|
1
|
||||||
|
00:00:09.500 --> 00:00:12.000
|
||||||
|
Le fond de l'océan monte 5 miles des rives
|
||||||
|
|
||||||
|
2
|
||||||
|
00:00:12.001 --> 00:00:16.500
|
||||||
|
de ce que les gens appellent le miracle de sept mile
|
||||||
|
|
||||||
|
3
|
||||||
|
00:00:25.500 --> 00:00:28.000
|
||||||
|
Que serait-il d'être né sur cette île?
|
||||||
|
|
||||||
|
4
|
||||||
|
00:00:32.500 --> 00:00:34.500
|
||||||
|
Pour grandir sur ces rivages
|
||||||
|
|
||||||
|
5
|
||||||
|
00:00:37.500 --> 00:00:40.000
|
||||||
|
Pour assister à cette eau, tous les jours
|
||||||
|
|
||||||
|
6
|
||||||
|
00:00:43.500 --> 00:00:46.000
|
||||||
|
Vous êtes sur le point de rencontrer quelqu'un, qui ne
|
||||||
|
|
||||||
|
7
|
||||||
|
00:02:45.500 --> 00:02:49.000
|
||||||
|
Ceci est un film sur John John Florence
|
BIN
demo/media/View_From_A_Blue_Moon_Trailer-HD.jpg
Normal file
After Width: | Height: | Size: 154 KiB |
335
demo/src/js/demo.js
Normal file
@ -0,0 +1,335 @@
|
|||||||
|
// ==========================================================================
|
||||||
|
// Plyr.io demo
|
||||||
|
// This code is purely for the https://plyr.io website
|
||||||
|
// Please see readme.md in the root or github.com/sampotts/plyr
|
||||||
|
// ==========================================================================
|
||||||
|
|
||||||
|
import Raven from 'raven-js';
|
||||||
|
|
||||||
|
(() => {
|
||||||
|
const isLive = window.location.host === 'plyr.io';
|
||||||
|
|
||||||
|
// Raven / Sentry
|
||||||
|
// For demo site (https://plyr.io) only
|
||||||
|
if (isLive) {
|
||||||
|
Raven.config('https://d4ad9866ad834437a4754e23937071e4@sentry.io/305555').install();
|
||||||
|
}
|
||||||
|
|
||||||
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
Raven.context(() => {
|
||||||
|
if (window.shr) {
|
||||||
|
window.shr.setup({
|
||||||
|
count: {
|
||||||
|
classname: 'button__count',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setup tab focus
|
||||||
|
const tabClassName = 'tab-focus';
|
||||||
|
|
||||||
|
// Remove class on blur
|
||||||
|
document.addEventListener('focusout', event => {
|
||||||
|
event.target.classList.remove(tabClassName);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Add classname to tabbed elements
|
||||||
|
document.addEventListener('keydown', event => {
|
||||||
|
if (event.keyCode !== 9) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delay the adding of classname until the focus has changed
|
||||||
|
// This event fires before the focusin event
|
||||||
|
setTimeout(() => {
|
||||||
|
document.activeElement.classList.add(tabClassName);
|
||||||
|
}, 0);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Setup the player
|
||||||
|
const player = new Plyr('#player', {
|
||||||
|
debug: true,
|
||||||
|
title: 'View From A Blue Moon',
|
||||||
|
iconUrl: '../dist/plyr.svg',
|
||||||
|
keyboard: {
|
||||||
|
global: true,
|
||||||
|
},
|
||||||
|
tooltips: {
|
||||||
|
controls: true,
|
||||||
|
},
|
||||||
|
/* controls: [
|
||||||
|
'play-large',
|
||||||
|
'restart',
|
||||||
|
'rewind',
|
||||||
|
'play',
|
||||||
|
'fast-forward',
|
||||||
|
'progress',
|
||||||
|
'current-time',
|
||||||
|
'duration',
|
||||||
|
'mute',
|
||||||
|
'volume',
|
||||||
|
'captions',
|
||||||
|
'settings',
|
||||||
|
'pip',
|
||||||
|
'airplay',
|
||||||
|
'fullscreen',
|
||||||
|
], */
|
||||||
|
/* i18n: {
|
||||||
|
restart: '重新開始',
|
||||||
|
rewind: '快退{seektime}秒',
|
||||||
|
play: '播放',
|
||||||
|
pause: '暫停',
|
||||||
|
fastForward: '快進{seektime}秒',
|
||||||
|
seek: '尋求',
|
||||||
|
played: '發揮',
|
||||||
|
buffered: '緩衝的',
|
||||||
|
currentTime: '當前時間戳',
|
||||||
|
duration: '長短',
|
||||||
|
volume: '音量',
|
||||||
|
mute: '靜音',
|
||||||
|
unmute: '取消靜音',
|
||||||
|
enableCaptions: '開啟字幕',
|
||||||
|
disableCaptions: '關閉字幕',
|
||||||
|
enterFullscreen: '進入全螢幕',
|
||||||
|
exitFullscreen: '退出全螢幕',
|
||||||
|
frameTitle: '球員為{title}',
|
||||||
|
captions: '字幕',
|
||||||
|
settings: '設定',
|
||||||
|
speed: '速度',
|
||||||
|
normal: '正常',
|
||||||
|
quality: '質量',
|
||||||
|
loop: '循環',
|
||||||
|
start: 'Start',
|
||||||
|
end: 'End',
|
||||||
|
all: 'All',
|
||||||
|
reset: '重啟',
|
||||||
|
disabled: '殘',
|
||||||
|
enabled: '啟用',
|
||||||
|
advertisement: '廣告',
|
||||||
|
}, */
|
||||||
|
captions: {
|
||||||
|
active: true,
|
||||||
|
},
|
||||||
|
keys: {
|
||||||
|
google: 'AIzaSyDrNwtN3nLH_8rjCmu5Wq3ZCm4MNAVdc0c',
|
||||||
|
},
|
||||||
|
ads: {
|
||||||
|
enabled: true,
|
||||||
|
publisherId: '918848828995742',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// Expose for tinkering in the console
|
||||||
|
window.player = player;
|
||||||
|
|
||||||
|
// Setup type toggle
|
||||||
|
const buttons = document.querySelectorAll('[data-source]');
|
||||||
|
const types = {
|
||||||
|
video: 'video',
|
||||||
|
audio: 'audio',
|
||||||
|
youtube: 'youtube',
|
||||||
|
vimeo: 'vimeo',
|
||||||
|
};
|
||||||
|
let currentType = window.location.hash.replace('#', '');
|
||||||
|
const historySupport = window.history && window.history.pushState;
|
||||||
|
|
||||||
|
// Toggle class on an element
|
||||||
|
function toggleClass(element, className, state) {
|
||||||
|
if (element) {
|
||||||
|
element.classList[state ? 'add' : 'remove'](className);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set a new source
|
||||||
|
function newSource(type, init) {
|
||||||
|
// Bail if new type isn't known, it's the current type, or current type is empty (video is default) and new type is video
|
||||||
|
if (
|
||||||
|
!(type in types) ||
|
||||||
|
(!init && type === currentType) ||
|
||||||
|
(!currentType.length && type === types.video)
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case types.video:
|
||||||
|
player.source = {
|
||||||
|
type: 'video',
|
||||||
|
title: 'View From A Blue Moon',
|
||||||
|
sources: [
|
||||||
|
{
|
||||||
|
src: 'https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-576p.mp4',
|
||||||
|
type: 'video/mp4',
|
||||||
|
size: 576,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
src: 'https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-720p.mp4',
|
||||||
|
type: 'video/mp4',
|
||||||
|
size: 720,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
src: 'https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-1080p.mp4',
|
||||||
|
type: 'video/mp4',
|
||||||
|
size: 1080,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
src: 'https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-1440p.mp4',
|
||||||
|
type: 'video/mp4',
|
||||||
|
size: 1440,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
poster: 'https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-HD.jpg',
|
||||||
|
tracks: [
|
||||||
|
{
|
||||||
|
kind: 'captions',
|
||||||
|
label: 'English',
|
||||||
|
srclang: 'en',
|
||||||
|
src: 'https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-HD.en.vtt',
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
kind: 'captions',
|
||||||
|
label: 'French',
|
||||||
|
srclang: 'fr',
|
||||||
|
src: 'https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-HD.fr.vtt',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case types.audio:
|
||||||
|
player.source = {
|
||||||
|
type: 'audio',
|
||||||
|
title: 'Kishi Bashi – “It All Began With A Burst”',
|
||||||
|
sources: [
|
||||||
|
{
|
||||||
|
src: 'https://cdn.plyr.io/static/demo/Kishi_Bashi_-_It_All_Began_With_a_Burst.mp3',
|
||||||
|
type: 'audio/mp3',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
src: 'https://cdn.plyr.io/static/demo/Kishi_Bashi_-_It_All_Began_With_a_Burst.ogg',
|
||||||
|
type: 'audio/ogg',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case types.youtube:
|
||||||
|
player.source = {
|
||||||
|
type: 'video',
|
||||||
|
sources: [
|
||||||
|
{
|
||||||
|
src: 'https://youtube.com/watch?v=bTqVqk7FSmY',
|
||||||
|
provider: 'youtube',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case types.vimeo:
|
||||||
|
player.source = {
|
||||||
|
type: 'video',
|
||||||
|
sources: [
|
||||||
|
{
|
||||||
|
src: 'https://vimeo.com/76979871',
|
||||||
|
provider: 'vimeo',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the current type for next time
|
||||||
|
currentType = type;
|
||||||
|
|
||||||
|
// Remove active classes
|
||||||
|
Array.from(buttons).forEach(button => toggleClass(button.parentElement, 'active', false));
|
||||||
|
|
||||||
|
// Set active on parent
|
||||||
|
toggleClass(document.querySelector(`[data-source="${type}"]`), 'active', true);
|
||||||
|
|
||||||
|
// Show cite
|
||||||
|
Array.from(document.querySelectorAll('.plyr__cite')).forEach(cite => {
|
||||||
|
cite.setAttribute('hidden', '');
|
||||||
|
});
|
||||||
|
document.querySelector(`.plyr__cite--${type}`).removeAttribute('hidden');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bind to each button
|
||||||
|
Array.from(buttons).forEach(button => {
|
||||||
|
button.addEventListener('click', () => {
|
||||||
|
const type = button.getAttribute('data-source');
|
||||||
|
|
||||||
|
newSource(type);
|
||||||
|
|
||||||
|
if (historySupport) {
|
||||||
|
window.history.pushState({ type }, '', `#${type}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// List for backwards/forwards
|
||||||
|
window.addEventListener('popstate', event => {
|
||||||
|
if (event.state && 'type' in event.state) {
|
||||||
|
newSource(event.state.type);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// On load
|
||||||
|
if (historySupport) {
|
||||||
|
const video = !currentType.length;
|
||||||
|
|
||||||
|
// If there's no current type set, assume video
|
||||||
|
if (video) {
|
||||||
|
currentType = types.video;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Replace current history state
|
||||||
|
if (currentType in types) {
|
||||||
|
window.history.replaceState(
|
||||||
|
{
|
||||||
|
type: currentType,
|
||||||
|
},
|
||||||
|
'',
|
||||||
|
video ? '' : `#${currentType}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If it's not video, load the source
|
||||||
|
if (currentType !== types.video) {
|
||||||
|
newSource(currentType, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Google analytics
|
||||||
|
// For demo site (https://plyr.io) only
|
||||||
|
/* eslint-disable */
|
||||||
|
if (isLive) {
|
||||||
|
(function(i, s, o, g, r, a, m) {
|
||||||
|
i.GoogleAnalyticsObject = r;
|
||||||
|
i[r] =
|
||||||
|
i[r] ||
|
||||||
|
function() {
|
||||||
|
(i[r].q = i[r].q || []).push(arguments);
|
||||||
|
};
|
||||||
|
i[r].l = 1 * new Date();
|
||||||
|
a = s.createElement(o);
|
||||||
|
m = s.getElementsByTagName(o)[0];
|
||||||
|
a.async = 1;
|
||||||
|
a.src = g;
|
||||||
|
m.parentNode.insertBefore(a, m);
|
||||||
|
})(window, document, 'script', 'https://www.google-analytics.com/analytics.js', 'ga');
|
||||||
|
window.ga('create', 'UA-40881672-11', 'auto');
|
||||||
|
window.ga('send', 'pageview');
|
||||||
|
}
|
||||||
|
/* eslint-enable */
|
||||||
|
})();
|
@ -1,237 +0,0 @@
|
|||||||
/*
|
|
||||||
* classList.js: Cross-browser full element.classList implementation.
|
|
||||||
* 1.1.20150312
|
|
||||||
*
|
|
||||||
* By Eli Grey, http://eligrey.com
|
|
||||||
* License: Dedicated to the public domain.
|
|
||||||
* See https://github.com/eligrey/classList.js/blob/master/LICENSE.md
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*global self, document, DOMException */
|
|
||||||
|
|
||||||
/*! @source http://purl.eligrey.com/github/classList.js/blob/master/classList.js */
|
|
||||||
|
|
||||||
if ("document" in self) {
|
|
||||||
|
|
||||||
// Full polyfill for browsers with no classList support
|
|
||||||
if (!("classList" in document.createElement("_"))) {
|
|
||||||
|
|
||||||
(function (view) {
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
if (!('Element' in view)) return;
|
|
||||||
|
|
||||||
var
|
|
||||||
classListProp = "classList"
|
|
||||||
, protoProp = "prototype"
|
|
||||||
, elemCtrProto = view.Element[protoProp]
|
|
||||||
, objCtr = Object
|
|
||||||
, strTrim = String[protoProp].trim || function () {
|
|
||||||
return this.replace(/^\s+|\s+$/g, "");
|
|
||||||
}
|
|
||||||
, arrIndexOf = Array[protoProp].indexOf || function (item) {
|
|
||||||
var
|
|
||||||
i = 0
|
|
||||||
, len = this.length
|
|
||||||
;
|
|
||||||
for (; i < len; i++) {
|
|
||||||
if (i in this && this[i] === item) {
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
// Vendors: please allow content code to instantiate DOMExceptions
|
|
||||||
, DOMEx = function (type, message) {
|
|
||||||
this.name = type;
|
|
||||||
this.code = DOMException[type];
|
|
||||||
this.message = message;
|
|
||||||
}
|
|
||||||
, checkTokenAndGetIndex = function (classList, token) {
|
|
||||||
if (token === "") {
|
|
||||||
throw new DOMEx(
|
|
||||||
"SYNTAX_ERR"
|
|
||||||
, "An invalid or illegal string was specified"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (/\s/.test(token)) {
|
|
||||||
throw new DOMEx(
|
|
||||||
"INVALID_CHARACTER_ERR"
|
|
||||||
, "String contains an invalid character"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return arrIndexOf.call(classList, token);
|
|
||||||
}
|
|
||||||
, ClassList = function (elem) {
|
|
||||||
var
|
|
||||||
trimmedClasses = strTrim.call(elem.getAttribute("class") || "")
|
|
||||||
, classes = trimmedClasses ? trimmedClasses.split(/\s+/) : []
|
|
||||||
, i = 0
|
|
||||||
, len = classes.length
|
|
||||||
;
|
|
||||||
for (; i < len; i++) {
|
|
||||||
this.push(classes[i]);
|
|
||||||
}
|
|
||||||
this._updateClassName = function () {
|
|
||||||
elem.setAttribute("class", this.toString());
|
|
||||||
};
|
|
||||||
}
|
|
||||||
, classListProto = ClassList[protoProp] = []
|
|
||||||
, classListGetter = function () {
|
|
||||||
return new ClassList(this);
|
|
||||||
}
|
|
||||||
;
|
|
||||||
// Most DOMException implementations don't allow calling DOMException's toString()
|
|
||||||
// on non-DOMExceptions. Error's toString() is sufficient here.
|
|
||||||
DOMEx[protoProp] = Error[protoProp];
|
|
||||||
classListProto.item = function (i) {
|
|
||||||
return this[i] || null;
|
|
||||||
};
|
|
||||||
classListProto.contains = function (token) {
|
|
||||||
token += "";
|
|
||||||
return checkTokenAndGetIndex(this, token) !== -1;
|
|
||||||
};
|
|
||||||
classListProto.add = function () {
|
|
||||||
var
|
|
||||||
tokens = arguments
|
|
||||||
, i = 0
|
|
||||||
, l = tokens.length
|
|
||||||
, token
|
|
||||||
, updated = false
|
|
||||||
;
|
|
||||||
do {
|
|
||||||
token = tokens[i] + "";
|
|
||||||
if (checkTokenAndGetIndex(this, token) === -1) {
|
|
||||||
this.push(token);
|
|
||||||
updated = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while (++i < l);
|
|
||||||
|
|
||||||
if (updated) {
|
|
||||||
this._updateClassName();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
classListProto.remove = function () {
|
|
||||||
var
|
|
||||||
tokens = arguments
|
|
||||||
, i = 0
|
|
||||||
, l = tokens.length
|
|
||||||
, token
|
|
||||||
, updated = false
|
|
||||||
, index
|
|
||||||
;
|
|
||||||
do {
|
|
||||||
token = tokens[i] + "";
|
|
||||||
index = checkTokenAndGetIndex(this, token);
|
|
||||||
while (index !== -1) {
|
|
||||||
this.splice(index, 1);
|
|
||||||
updated = true;
|
|
||||||
index = checkTokenAndGetIndex(this, token);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while (++i < l);
|
|
||||||
|
|
||||||
if (updated) {
|
|
||||||
this._updateClassName();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
classListProto.toggle = function (token, force) {
|
|
||||||
token += "";
|
|
||||||
|
|
||||||
var
|
|
||||||
result = this.contains(token)
|
|
||||||
, method = result ?
|
|
||||||
force !== true && "remove"
|
|
||||||
:
|
|
||||||
force !== false && "add"
|
|
||||||
;
|
|
||||||
|
|
||||||
if (method) {
|
|
||||||
this[method](token);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (force === true || force === false) {
|
|
||||||
return force;
|
|
||||||
} else {
|
|
||||||
return !result;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
classListProto.toString = function () {
|
|
||||||
return this.join(" ");
|
|
||||||
};
|
|
||||||
|
|
||||||
if (objCtr.defineProperty) {
|
|
||||||
var classListPropDesc = {
|
|
||||||
get: classListGetter
|
|
||||||
, enumerable: true
|
|
||||||
, configurable: true
|
|
||||||
};
|
|
||||||
try {
|
|
||||||
objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc);
|
|
||||||
} catch (ex) { // IE 8 doesn't support enumerable:true
|
|
||||||
if (ex.number === -0x7FF5EC54) {
|
|
||||||
classListPropDesc.enumerable = false;
|
|
||||||
objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (objCtr[protoProp].__defineGetter__) {
|
|
||||||
elemCtrProto.__defineGetter__(classListProp, classListGetter);
|
|
||||||
}
|
|
||||||
|
|
||||||
}(self));
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// There is full or partial native classList support, so just check if we need
|
|
||||||
// to normalize the add/remove and toggle APIs.
|
|
||||||
|
|
||||||
(function () {
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
var testElement = document.createElement("_");
|
|
||||||
|
|
||||||
testElement.classList.add("c1", "c2");
|
|
||||||
|
|
||||||
// Polyfill for IE 10/11 and Firefox <26, where classList.add and
|
|
||||||
// classList.remove exist but support only one argument at a time.
|
|
||||||
if (!testElement.classList.contains("c2")) {
|
|
||||||
var createMethod = function(method) {
|
|
||||||
var original = DOMTokenList.prototype[method];
|
|
||||||
|
|
||||||
DOMTokenList.prototype[method] = function(token) {
|
|
||||||
var i, len = arguments.length;
|
|
||||||
|
|
||||||
for (i = 0; i < len; i++) {
|
|
||||||
token = arguments[i];
|
|
||||||
original.call(this, token);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
createMethod('add');
|
|
||||||
createMethod('remove');
|
|
||||||
}
|
|
||||||
|
|
||||||
testElement.classList.toggle("c3", false);
|
|
||||||
|
|
||||||
// Polyfill for IE 10 and Firefox <24, where classList.toggle does not
|
|
||||||
// support the second argument.
|
|
||||||
if (testElement.classList.contains("c3")) {
|
|
||||||
var _toggle = DOMTokenList.prototype.toggle;
|
|
||||||
|
|
||||||
DOMTokenList.prototype.toggle = function(token, force) {
|
|
||||||
if (1 in arguments && !this.contains(token) === !force) {
|
|
||||||
return force;
|
|
||||||
} else {
|
|
||||||
return _toggle.call(this, token);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
testElement = null;
|
|
||||||
}());
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,203 +0,0 @@
|
|||||||
// ==========================================================================
|
|
||||||
// Plyr.io demo
|
|
||||||
// This code is purely for the plyr.io website
|
|
||||||
// Please see readme.md in the root or github.com/selz/plyr
|
|
||||||
// ==========================================================================
|
|
||||||
|
|
||||||
/*global plyr*/
|
|
||||||
|
|
||||||
// General functions
|
|
||||||
(function() {
|
|
||||||
//document.body.addEventListener('ready', function(event) { console.log(event); });
|
|
||||||
|
|
||||||
// Setup the player
|
|
||||||
var instances = plyr.setup({
|
|
||||||
debug: true,
|
|
||||||
title: "Video demo",
|
|
||||||
iconUrl: "../dist/plyr.svg",
|
|
||||||
tooltips: {
|
|
||||||
controls: true
|
|
||||||
},
|
|
||||||
captions: {
|
|
||||||
defaultActive: true
|
|
||||||
}
|
|
||||||
});
|
|
||||||
plyr.loadSprite("dist/demo.svg");
|
|
||||||
|
|
||||||
// Plyr returns an array regardless
|
|
||||||
var player = instances[0];
|
|
||||||
|
|
||||||
// Setup type toggle
|
|
||||||
var buttons = document.querySelectorAll("[data-source]"),
|
|
||||||
types = {
|
|
||||||
video: "video",
|
|
||||||
audio: "audio",
|
|
||||||
youtube: "youtube",
|
|
||||||
vimeo: "vimeo"
|
|
||||||
},
|
|
||||||
currentType = window.location.hash.replace("#", ""),
|
|
||||||
historySupport = window.history && window.history.pushState;
|
|
||||||
|
|
||||||
// Bind to each button
|
|
||||||
for (var i = buttons.length - 1; i >= 0; i--) {
|
|
||||||
buttons[i].addEventListener("click", function() {
|
|
||||||
var type = this.getAttribute("data-source");
|
|
||||||
|
|
||||||
newSource(type);
|
|
||||||
|
|
||||||
if (historySupport) {
|
|
||||||
history.pushState({ type: type }, "", "#" + type);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// List for backwards/forwards
|
|
||||||
window.addEventListener("popstate", function(event) {
|
|
||||||
if (event.state && "type" in event.state) {
|
|
||||||
newSource(event.state.type);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// On load
|
|
||||||
if (historySupport) {
|
|
||||||
var video = !currentType.length;
|
|
||||||
|
|
||||||
// If there's no current type set, assume video
|
|
||||||
if (video) {
|
|
||||||
currentType = types.video;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Replace current history state
|
|
||||||
if (currentType in types) {
|
|
||||||
history.replaceState({ type: currentType }, "", video ? "" : "#" + currentType);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If it's not video, load the source
|
|
||||||
if (currentType !== types.video) {
|
|
||||||
newSource(currentType, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Toggle class on an element
|
|
||||||
function toggleClass(element, className, state) {
|
|
||||||
if (element) {
|
|
||||||
if (element.classList) {
|
|
||||||
element.classList[state ? "add" : "remove"](className);
|
|
||||||
} else {
|
|
||||||
var name = (" " + element.className + " ").replace(/\s+/g, " ").replace(" " + className + " ", "");
|
|
||||||
element.className = name + (state ? " " + className : "");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set a new source
|
|
||||||
function newSource(type, init) {
|
|
||||||
// Bail if new type isn't known, it's the current type, or current type is empty (video is default) and new type is video
|
|
||||||
if (!(type in types) || (!init && type === currentType) || (!currentType.length && type === types.video)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (type) {
|
|
||||||
case types.video:
|
|
||||||
player.source({
|
|
||||||
type: "video",
|
|
||||||
title: "View From A Blue Moon",
|
|
||||||
sources: [
|
|
||||||
{
|
|
||||||
src: "https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-HD.mp4",
|
|
||||||
type: "video/mp4"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
src: "https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-HD.webm",
|
|
||||||
type: "video/webm"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
poster: "https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-HD.jpg",
|
|
||||||
tracks: [
|
|
||||||
{
|
|
||||||
kind: "captions",
|
|
||||||
label: "English",
|
|
||||||
srclang: "en",
|
|
||||||
src: "https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-HD.en.vtt",
|
|
||||||
default: true
|
|
||||||
}
|
|
||||||
]
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
|
|
||||||
case types.audio:
|
|
||||||
player.source({
|
|
||||||
type: "audio",
|
|
||||||
title: "Kishi Bashi – “It All Began With A Burst”",
|
|
||||||
sources: [
|
|
||||||
{
|
|
||||||
src: "https://cdn.plyr.io/static/demo/Kishi_Bashi_-_It_All_Began_With_a_Burst.mp3",
|
|
||||||
type: "audio/mp3"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
src: "https://cdn.plyr.io/static/demo/Kishi_Bashi_-_It_All_Began_With_a_Burst.ogg",
|
|
||||||
type: "audio/ogg"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
|
|
||||||
case types.youtube:
|
|
||||||
player.source({
|
|
||||||
type: "video",
|
|
||||||
title: "View From A Blue Moon",
|
|
||||||
sources: [
|
|
||||||
{
|
|
||||||
src: "bTqVqk7FSmY",
|
|
||||||
type: "youtube"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
|
|
||||||
case types.vimeo:
|
|
||||||
player.source({
|
|
||||||
type: "video",
|
|
||||||
title: "View From A Blue Moon",
|
|
||||||
sources: [
|
|
||||||
{
|
|
||||||
src: "147865858",
|
|
||||||
type: "vimeo"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the current type for next time
|
|
||||||
currentType = type;
|
|
||||||
|
|
||||||
// Remove active classes
|
|
||||||
for (var x = buttons.length - 1; x >= 0; x--) {
|
|
||||||
toggleClass(buttons[x].parentElement, "active", false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set active on parent
|
|
||||||
toggleClass(document.querySelector('[data-source="' + type + '"]').parentElement, "active", true);
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
|
|
||||||
// Google analytics
|
|
||||||
// For demo site (http://[www.]plyr.io) only
|
|
||||||
if (document.domain.indexOf("plyr.io") > -1) {
|
|
||||||
(function(i, s, o, g, r, a, m) {
|
|
||||||
i.GoogleAnalyticsObject = r;
|
|
||||||
(i[r] =
|
|
||||||
i[r] ||
|
|
||||||
function() {
|
|
||||||
(i[r].q = i[r].q || []).push(arguments);
|
|
||||||
}),
|
|
||||||
(i[r].l = 1 * new Date());
|
|
||||||
(a = s.createElement(o)), (m = s.getElementsByTagName(o)[0]);
|
|
||||||
a.async = 1;
|
|
||||||
a.src = g;
|
|
||||||
m.parentNode.insertBefore(a, m);
|
|
||||||
})(window, document, "script", "//www.google-analytics.com/analytics.js", "ga");
|
|
||||||
ga("create", "UA-40881672-11", "auto");
|
|
||||||
ga("send", "pageview");
|
|
||||||
}
|
|
@ -1,48 +0,0 @@
|
|||||||
// ==========================================================================
|
|
||||||
// Base layout
|
|
||||||
// ==========================================================================
|
|
||||||
|
|
||||||
// BORDER-BOX ALL THE THINGS!
|
|
||||||
// http://paulirish.com/2012/box-sizing-border-box-ftw/
|
|
||||||
*, *::after, *::before {
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hidden
|
|
||||||
[hidden] {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Base
|
|
||||||
html {
|
|
||||||
height: 100%;
|
|
||||||
background: @body-background fixed;
|
|
||||||
}
|
|
||||||
body {
|
|
||||||
margin: 0;
|
|
||||||
padding: (@padding-base / 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Header
|
|
||||||
header {
|
|
||||||
padding: @padding-base;
|
|
||||||
margin-bottom: @padding-base;
|
|
||||||
|
|
||||||
p {
|
|
||||||
.font-size(18);
|
|
||||||
}
|
|
||||||
@media (min-width: @screen-sm) {
|
|
||||||
padding-top: (@padding-base * 3);
|
|
||||||
padding-bottom: (@padding-base * 3);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sections
|
|
||||||
section {
|
|
||||||
max-width: @example-width-video;
|
|
||||||
margin: 0 auto @padding-base;
|
|
||||||
|
|
||||||
@media (min-width: @screen-sm) {
|
|
||||||
margin-bottom: (@padding-base * 2);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,172 +0,0 @@
|
|||||||
// ==========================================================================
|
|
||||||
// Buttons
|
|
||||||
// ==========================================================================
|
|
||||||
|
|
||||||
nav {
|
|
||||||
ul {
|
|
||||||
list-style: none;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
font-size: 0;
|
|
||||||
}
|
|
||||||
li {
|
|
||||||
display: inline-block;
|
|
||||||
margin-top: (@padding-base / 2);
|
|
||||||
.font-size();
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
li + li {
|
|
||||||
margin-left: @padding-base;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Tabs
|
|
||||||
.btn__bar {
|
|
||||||
position: relative;
|
|
||||||
margin: 0 auto @padding-base;
|
|
||||||
max-width: @example-width-video;
|
|
||||||
white-space: nowrap;
|
|
||||||
|
|
||||||
&::before {
|
|
||||||
content: "";
|
|
||||||
position: absolute;
|
|
||||||
top: 50%;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
height: 1px;
|
|
||||||
background: @gray-lighter;
|
|
||||||
}
|
|
||||||
|
|
||||||
ul {
|
|
||||||
position: relative;
|
|
||||||
z-index: 1;
|
|
||||||
display: inline-block;
|
|
||||||
user-select: none;
|
|
||||||
}
|
|
||||||
li {
|
|
||||||
margin: 0;
|
|
||||||
|
|
||||||
&:first-child .btn {
|
|
||||||
border-radius: 4px 0 0 4px;
|
|
||||||
}
|
|
||||||
&:last-child .btn {
|
|
||||||
border-radius: 0 4px 4px 0;
|
|
||||||
}
|
|
||||||
& + li .btn {
|
|
||||||
margin-left: -1px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.active .btn {
|
|
||||||
&:extend(.btn--primary);
|
|
||||||
box-shadow: inset 0 1px 1px rgba(0,0,0, .2);
|
|
||||||
position: relative;
|
|
||||||
z-index: 1;
|
|
||||||
|
|
||||||
.icon {
|
|
||||||
color: inherit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
&.active + li .btn:hover {
|
|
||||||
z-index: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.btn {
|
|
||||||
position: relative;
|
|
||||||
display: block;
|
|
||||||
border-radius: 0;
|
|
||||||
|
|
||||||
&:hover,
|
|
||||||
&:focus {
|
|
||||||
z-index: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: 560px) {
|
|
||||||
margin-bottom: (@padding-base * 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Shared
|
|
||||||
.btn,
|
|
||||||
.btn__count {
|
|
||||||
display: inline-block;
|
|
||||||
vertical-align: middle;
|
|
||||||
border-radius: @border-radius-base;
|
|
||||||
user-select: none;
|
|
||||||
font-weight: @font-weight-bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Buttons
|
|
||||||
.btn {
|
|
||||||
padding: (@padding-base / 2) ((@padding-base / 2) + 2);
|
|
||||||
background: linear-gradient(lighten(@off-white, 2%), darken(@off-white, 3%));
|
|
||||||
border: 1px solid @gray-light;
|
|
||||||
box-shadow: 0 1px 1px rgba(0,0,0, .05);
|
|
||||||
text-shadow: 0 1px 1px #fff;
|
|
||||||
color: @gray;
|
|
||||||
transition: background .1s ease, color .1s ease;
|
|
||||||
.font-size(@font-size-small);
|
|
||||||
|
|
||||||
&:hover,
|
|
||||||
&:focus {
|
|
||||||
border-color: darken(@gray-light, 8%);
|
|
||||||
color: @gray;
|
|
||||||
outline: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sizes
|
|
||||||
.btn--large {
|
|
||||||
padding: (@padding-base / 2) @padding-base;
|
|
||||||
.font-size();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Styles
|
|
||||||
.btn--primary {
|
|
||||||
background-image: linear-gradient(@link-color, darken(@link-color, 5%));
|
|
||||||
background-color: @link-color;
|
|
||||||
border-color: darken(@link-color, 10%);
|
|
||||||
box-shadow: 0 1px 1px rgba(0,0,0, .15);
|
|
||||||
text-shadow: 0 1px 1px rgba(0,0,0, .1);
|
|
||||||
color: #fff;
|
|
||||||
|
|
||||||
&:hover,
|
|
||||||
&:focus {
|
|
||||||
color: #fff;
|
|
||||||
border-color: darken(@link-color, 20%);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.btn--youtube .icon {
|
|
||||||
color: @color-youtube;
|
|
||||||
}
|
|
||||||
.btn--vimeo .icon {
|
|
||||||
color: @color-vimeo;
|
|
||||||
}
|
|
||||||
.btn--twitter .icon {
|
|
||||||
color: @color-twitter;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Count bubble
|
|
||||||
.btn__count {
|
|
||||||
position: relative;
|
|
||||||
margin-left: (@padding-base / 2);
|
|
||||||
padding: (@padding-base / 2) (@padding-base * .75);
|
|
||||||
background: #fff;
|
|
||||||
border: 1px solid @gray-light;
|
|
||||||
|
|
||||||
&::before {
|
|
||||||
content: "";
|
|
||||||
position: absolute;
|
|
||||||
display: block;
|
|
||||||
width: @arrow-size;
|
|
||||||
height: @arrow-size;
|
|
||||||
left: 1px;
|
|
||||||
top: 50%;
|
|
||||||
margin-top: -(@arrow-size / 2);
|
|
||||||
|
|
||||||
background: inherit;
|
|
||||||
border: inherit;
|
|
||||||
border-width: 1px 0 0 1px;
|
|
||||||
transform: rotate(-45deg) translate(-50%, -50%);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,75 +0,0 @@
|
|||||||
// ==========================================================================
|
|
||||||
// Typography
|
|
||||||
// ==========================================================================
|
|
||||||
|
|
||||||
// Base
|
|
||||||
html {
|
|
||||||
font-size: 100%;
|
|
||||||
}
|
|
||||||
body {
|
|
||||||
font-family: "Avenir", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
|
||||||
line-height: 1.5;
|
|
||||||
text-align: center;
|
|
||||||
color: @gray;
|
|
||||||
font-weight: @font-weight-base;
|
|
||||||
.font-smoothing();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Headings
|
|
||||||
h1,
|
|
||||||
h2 {
|
|
||||||
letter-spacing: -.025em;
|
|
||||||
color: @brand-primary;
|
|
||||||
margin: 0 0 (@padding-base / 2);
|
|
||||||
line-height: 1.2;
|
|
||||||
font-weight: @font-weight-bold;
|
|
||||||
}
|
|
||||||
h1 {
|
|
||||||
.font-size(@font-size-h1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Paragraph and small
|
|
||||||
p,
|
|
||||||
small {
|
|
||||||
margin: 0 0 @padding-base;
|
|
||||||
}
|
|
||||||
small {
|
|
||||||
display: block;
|
|
||||||
padding: 0 (@padding-base / 2);
|
|
||||||
.font-size(@font-size-small);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Lists
|
|
||||||
ul,
|
|
||||||
li {
|
|
||||||
list-style: none;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Links
|
|
||||||
a {
|
|
||||||
text-decoration: none;
|
|
||||||
color: @link-color;
|
|
||||||
border-bottom: 1px dotted currentColor;
|
|
||||||
transition: background .3s ease, color .3s ease, border .3s ease;
|
|
||||||
|
|
||||||
&:hover,
|
|
||||||
&:focus {
|
|
||||||
color: @gray-dark;
|
|
||||||
border-bottom-color: rgba(0,0,0,0);
|
|
||||||
}
|
|
||||||
&:focus {
|
|
||||||
.tab-focus();
|
|
||||||
}
|
|
||||||
&.logo {
|
|
||||||
border: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.color--vimeo {
|
|
||||||
color: @color-vimeo;
|
|
||||||
}
|
|
||||||
.color--youtube {
|
|
||||||
color: @color-youtube;
|
|
||||||
}
|
|
@ -1,26 +0,0 @@
|
|||||||
// ==========================================================================
|
|
||||||
// Plyr.io Demo Page
|
|
||||||
// ==========================================================================
|
|
||||||
|
|
||||||
// CSS Reset
|
|
||||||
@import "lib/normalize.less";
|
|
||||||
|
|
||||||
// Mixins
|
|
||||||
@import "lib/mixins.less";
|
|
||||||
|
|
||||||
// Variables
|
|
||||||
@import "variables.less";
|
|
||||||
|
|
||||||
// Animation
|
|
||||||
@import "lib/animation.less";
|
|
||||||
|
|
||||||
// Type
|
|
||||||
@import "lib/fontface.less";
|
|
||||||
@import "components/type.less";
|
|
||||||
|
|
||||||
// Components
|
|
||||||
@import "components/base.less";
|
|
||||||
@import "components/icons.less";
|
|
||||||
@import "components/buttons.less";
|
|
||||||
@import "components/error.less";
|
|
||||||
@import "components/examples.less";
|
|
@ -1,18 +0,0 @@
|
|||||||
// ==========================================================================
|
|
||||||
// Fonts
|
|
||||||
// ==========================================================================
|
|
||||||
|
|
||||||
@font-face {
|
|
||||||
font-family: 'Avenir';
|
|
||||||
src: url('https://cdn.plyr.io/static/fonts/avenir-medium.woff2') format('woff2'), url('https://cdn.plyr.io/static/fonts/avenir-medium.woff') format('woff');
|
|
||||||
font-style: normal;
|
|
||||||
font-weight: @font-weight-base;
|
|
||||||
font-display: swap;
|
|
||||||
}
|
|
||||||
@font-face {
|
|
||||||
font-family: 'Avenir';
|
|
||||||
src: url('https://cdn.plyr.io/static/fonts/avenir-bold.woff2') format('woff2'), url('https://cdn.plyr.io/static/fonts/avenir-bold.woff') format('woff');
|
|
||||||
font-style: normal;
|
|
||||||
font-weight: @font-weight-bold;
|
|
||||||
font-display: swap;
|
|
||||||
}
|
|
@ -1,41 +0,0 @@
|
|||||||
// ==========================================================================
|
|
||||||
// Mixins
|
|
||||||
// ==========================================================================
|
|
||||||
|
|
||||||
// Contain floats: nicolasgallagher.com/micro-clearfix-hack/
|
|
||||||
// ---------------------------------------
|
|
||||||
.clearfix() {
|
|
||||||
zoom: 1;
|
|
||||||
&:before,
|
|
||||||
&:after { content: ""; display: table; }
|
|
||||||
&:after { clear: both; }
|
|
||||||
}
|
|
||||||
|
|
||||||
// Webkit-style focus
|
|
||||||
// ---------------------------------------
|
|
||||||
.tab-focus() {
|
|
||||||
// Default
|
|
||||||
outline: thin dotted @gray-dark;
|
|
||||||
// Webkit
|
|
||||||
outline-offset: 1px;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Use rems for font sizing
|
|
||||||
// Leave <body> at 100%/16px
|
|
||||||
// ---------------------------------------
|
|
||||||
.font-size(@font-size: 16){
|
|
||||||
@rem: round((@font-size / 16), 3);
|
|
||||||
font-size: (@font-size * 1px);
|
|
||||||
font-size: ~"@{rem}rem";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Font smoothing
|
|
||||||
// ---------------------------------------
|
|
||||||
.font-smoothing(@mode: on) when (@mode = on) {
|
|
||||||
-moz-osx-font-smoothing: grayscale;
|
|
||||||
-webkit-font-smoothing: antialiased;
|
|
||||||
}
|
|
||||||
.font-smoothing(@mode: on) when (@mode = off) {
|
|
||||||
-moz-osx-font-smoothing: auto;
|
|
||||||
-webkit-font-smoothing: subpixel-antialiased;
|
|
||||||
}
|
|
406
demo/src/less/lib/normalize.less
vendored
@ -1,406 +0,0 @@
|
|||||||
/*! normalize.css v2.1.3 | MIT License | git.io/normalize */
|
|
||||||
|
|
||||||
/* ==========================================================================
|
|
||||||
HTML5 display definitions
|
|
||||||
========================================================================== */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Correct `block` display not defined in IE 8/9.
|
|
||||||
*/
|
|
||||||
|
|
||||||
article,
|
|
||||||
aside,
|
|
||||||
details,
|
|
||||||
figcaption,
|
|
||||||
figure,
|
|
||||||
footer,
|
|
||||||
header,
|
|
||||||
hgroup,
|
|
||||||
main,
|
|
||||||
nav,
|
|
||||||
section,
|
|
||||||
summary {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Correct `inline-block` display not defined in IE 8/9.
|
|
||||||
*/
|
|
||||||
|
|
||||||
audio,
|
|
||||||
canvas,
|
|
||||||
video {
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Prevent modern browsers from displaying `audio` without controls.
|
|
||||||
* Remove excess height in iOS 5 devices.
|
|
||||||
*/
|
|
||||||
|
|
||||||
audio:not([controls]) {
|
|
||||||
display: none;
|
|
||||||
height: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Address `[hidden]` styling not present in IE 8/9.
|
|
||||||
* Hide the `template` element in IE, Safari, and Firefox < 22.
|
|
||||||
*/
|
|
||||||
|
|
||||||
[hidden],
|
|
||||||
template {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ==========================================================================
|
|
||||||
Base
|
|
||||||
========================================================================== */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 1. Set default font family to sans-serif.
|
|
||||||
* 2. Prevent iOS text size adjust after orientation change, without disabling
|
|
||||||
* user zoom.
|
|
||||||
*/
|
|
||||||
|
|
||||||
html {
|
|
||||||
font-family: sans-serif; /* 1 */
|
|
||||||
-ms-text-size-adjust: 100%; /* 2 */
|
|
||||||
-webkit-text-size-adjust: 100%; /* 2 */
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove default margin.
|
|
||||||
*/
|
|
||||||
|
|
||||||
body {
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ==========================================================================
|
|
||||||
Links
|
|
||||||
========================================================================== */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove the gray background color from active links in IE 10.
|
|
||||||
*/
|
|
||||||
|
|
||||||
a {
|
|
||||||
background: transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Address `outline` inconsistency between Chrome and other browsers.
|
|
||||||
*/
|
|
||||||
|
|
||||||
a:focus {
|
|
||||||
outline: thin dotted;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Improve readability when focused and also mouse hovered in all browsers.
|
|
||||||
*/
|
|
||||||
|
|
||||||
a:active,
|
|
||||||
a:hover {
|
|
||||||
outline: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ==========================================================================
|
|
||||||
Typography
|
|
||||||
========================================================================== */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Address variable `h1` font-size and margin within `section` and `article`
|
|
||||||
* contexts in Firefox 4+, Safari 5, and Chrome.
|
|
||||||
*/
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
font-size: 2em;
|
|
||||||
margin: 0.67em 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Address styling not present in IE 8/9, Safari 5, and Chrome.
|
|
||||||
*/
|
|
||||||
|
|
||||||
abbr[title] {
|
|
||||||
border-bottom: 1px dotted;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Address style set to `bolder` in Firefox 4+, Safari 5, and Chrome.
|
|
||||||
*/
|
|
||||||
|
|
||||||
b,
|
|
||||||
strong {
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Address styling not present in Safari 5 and Chrome.
|
|
||||||
*/
|
|
||||||
|
|
||||||
dfn {
|
|
||||||
font-style: italic;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Address differences between Firefox and other browsers.
|
|
||||||
*/
|
|
||||||
|
|
||||||
hr {
|
|
||||||
-moz-box-sizing: content-box;
|
|
||||||
box-sizing: content-box;
|
|
||||||
height: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Address styling not present in IE 8/9.
|
|
||||||
*/
|
|
||||||
|
|
||||||
mark {
|
|
||||||
background: #ff0;
|
|
||||||
color: #000;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Correct font family set oddly in Safari 5 and Chrome.
|
|
||||||
*/
|
|
||||||
|
|
||||||
code,
|
|
||||||
kbd,
|
|
||||||
pre,
|
|
||||||
samp {
|
|
||||||
font-family: monospace, serif;
|
|
||||||
font-size: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Improve readability of pre-formatted text in all browsers.
|
|
||||||
*/
|
|
||||||
|
|
||||||
pre {
|
|
||||||
white-space: pre-wrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set consistent quote types.
|
|
||||||
*/
|
|
||||||
|
|
||||||
q {
|
|
||||||
quotes: "\201C" "\201D" "\2018" "\2019";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Address inconsistent and variable font size in all browsers.
|
|
||||||
*/
|
|
||||||
|
|
||||||
small {
|
|
||||||
font-size: 80%;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Prevent `sub` and `sup` affecting `line-height` in all browsers.
|
|
||||||
*/
|
|
||||||
|
|
||||||
sub,
|
|
||||||
sup {
|
|
||||||
font-size: 75%;
|
|
||||||
line-height: 0;
|
|
||||||
position: relative;
|
|
||||||
vertical-align: baseline;
|
|
||||||
}
|
|
||||||
|
|
||||||
sup {
|
|
||||||
top: -0.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
sub {
|
|
||||||
bottom: -0.25em;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ==========================================================================
|
|
||||||
Embedded content
|
|
||||||
========================================================================== */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove border when inside `a` element in IE 8/9.
|
|
||||||
*/
|
|
||||||
|
|
||||||
img {
|
|
||||||
border: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Correct overflow displayed oddly in IE 9.
|
|
||||||
*/
|
|
||||||
|
|
||||||
svg:not(:root) {
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ==========================================================================
|
|
||||||
Figures
|
|
||||||
========================================================================== */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Address margin not present in IE 8/9 and Safari 5.
|
|
||||||
*/
|
|
||||||
|
|
||||||
figure {
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ==========================================================================
|
|
||||||
Forms
|
|
||||||
========================================================================== */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Define consistent border, margin, and padding.
|
|
||||||
*/
|
|
||||||
|
|
||||||
fieldset {
|
|
||||||
border: 1px solid #c0c0c0;
|
|
||||||
margin: 0 2px;
|
|
||||||
padding: 0.35em 0.625em 0.75em;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 1. Correct `color` not being inherited in IE 8/9.
|
|
||||||
* 2. Remove padding so people aren't caught out if they zero out fieldsets.
|
|
||||||
*/
|
|
||||||
|
|
||||||
legend {
|
|
||||||
border: 0; /* 1 */
|
|
||||||
padding: 0; /* 2 */
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 1. Correct font family not being inherited in all browsers.
|
|
||||||
* 2. Correct font size not being inherited in all browsers.
|
|
||||||
* 3. Address margins set differently in Firefox 4+, Safari 5, and Chrome.
|
|
||||||
*/
|
|
||||||
|
|
||||||
button,
|
|
||||||
input,
|
|
||||||
select,
|
|
||||||
textarea {
|
|
||||||
font-family: inherit; /* 1 */
|
|
||||||
font-size: 100%; /* 2 */
|
|
||||||
margin: 0; /* 3 */
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Address Firefox 4+ setting `line-height` on `input` using `!important` in
|
|
||||||
* the UA stylesheet.
|
|
||||||
*/
|
|
||||||
|
|
||||||
button,
|
|
||||||
input {
|
|
||||||
line-height: normal;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Address inconsistent `text-transform` inheritance for `button` and `select`.
|
|
||||||
* All other form control elements do not inherit `text-transform` values.
|
|
||||||
* Correct `button` style inheritance in Chrome, Safari 5+, and IE 8+.
|
|
||||||
* Correct `select` style inheritance in Firefox 4+ and Opera.
|
|
||||||
*/
|
|
||||||
|
|
||||||
button,
|
|
||||||
select {
|
|
||||||
text-transform: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`
|
|
||||||
* and `video` controls.
|
|
||||||
* 2. Correct inability to style clickable `input` types in iOS.
|
|
||||||
* 3. Improve usability and consistency of cursor style between image-type
|
|
||||||
* `input` and others.
|
|
||||||
*/
|
|
||||||
|
|
||||||
button,
|
|
||||||
html input[type="button"], /* 1 */
|
|
||||||
input[type="reset"],
|
|
||||||
input[type="submit"] {
|
|
||||||
-webkit-appearance: button; /* 2 */
|
|
||||||
cursor: pointer; /* 3 */
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Re-set default cursor for disabled elements.
|
|
||||||
*/
|
|
||||||
|
|
||||||
button[disabled],
|
|
||||||
html input[disabled] {
|
|
||||||
cursor: default;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 1. Address box sizing set to `content-box` in IE 8/9/10.
|
|
||||||
* 2. Remove excess padding in IE 8/9/10.
|
|
||||||
*/
|
|
||||||
|
|
||||||
input[type="checkbox"],
|
|
||||||
input[type="radio"] {
|
|
||||||
box-sizing: border-box; /* 1 */
|
|
||||||
padding: 0; /* 2 */
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 1. Address `appearance` set to `searchfield` in Safari 5 and Chrome.
|
|
||||||
* 2. Address `box-sizing` set to `border-box` in Safari 5 and Chrome
|
|
||||||
* (include `-moz` to future-proof).
|
|
||||||
*/
|
|
||||||
|
|
||||||
input[type="search"] {
|
|
||||||
-webkit-appearance: textfield; /* 1 */
|
|
||||||
-moz-box-sizing: content-box;
|
|
||||||
-webkit-box-sizing: content-box; /* 2 */
|
|
||||||
box-sizing: content-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove inner padding and search cancel button in Safari 5 and Chrome
|
|
||||||
* on OS X.
|
|
||||||
*/
|
|
||||||
|
|
||||||
input[type="search"]::-webkit-search-cancel-button,
|
|
||||||
input[type="search"]::-webkit-search-decoration {
|
|
||||||
-webkit-appearance: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove inner padding and border in Firefox 4+.
|
|
||||||
*/
|
|
||||||
|
|
||||||
button::-moz-focus-inner,
|
|
||||||
input::-moz-focus-inner {
|
|
||||||
border: 0;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 1. Remove default vertical scrollbar in IE 8/9.
|
|
||||||
* 2. Improve readability and alignment in all browsers.
|
|
||||||
*/
|
|
||||||
|
|
||||||
textarea {
|
|
||||||
overflow: auto; /* 1 */
|
|
||||||
vertical-align: top; /* 2 */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ==========================================================================
|
|
||||||
Tables
|
|
||||||
========================================================================== */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove most spacing between table cells.
|
|
||||||
*/
|
|
||||||
|
|
||||||
table {
|
|
||||||
border-collapse: collapse;
|
|
||||||
border-spacing: 0;
|
|
||||||
}
|
|
@ -1,48 +0,0 @@
|
|||||||
// ==========================================================================
|
|
||||||
// Variables
|
|
||||||
// ==========================================================================
|
|
||||||
|
|
||||||
// Colors
|
|
||||||
@gray-dark: #343f4a;
|
|
||||||
@gray: #55646b;
|
|
||||||
@gray-light: #cbd0d3;
|
|
||||||
@gray-lighter: #dbe3e8;
|
|
||||||
@off-white: #f2f5f7;
|
|
||||||
|
|
||||||
@brand-primary: #3498db;
|
|
||||||
@brand-secondary: #02BD9B;
|
|
||||||
|
|
||||||
// Brands
|
|
||||||
@color-twitter: #4BAAF4;
|
|
||||||
@color-youtube: #cc181e;
|
|
||||||
@color-vimeo: #19b7ed;
|
|
||||||
|
|
||||||
// Base
|
|
||||||
@body-background: @off-white; //linear-gradient(to left top, @brand-secondary, @brand-primary);
|
|
||||||
|
|
||||||
// Type
|
|
||||||
@font-size-base: 16;
|
|
||||||
@font-size-small: 14;
|
|
||||||
@font-size-h1: 64;
|
|
||||||
@font-weight-base: 500;
|
|
||||||
@font-weight-bold: 700;
|
|
||||||
|
|
||||||
// Elements
|
|
||||||
@link-color: @brand-primary;
|
|
||||||
@padding-base: 20px;
|
|
||||||
@arrow-size: 8px;
|
|
||||||
|
|
||||||
// Icons
|
|
||||||
@icon-size: 18px;
|
|
||||||
|
|
||||||
// Breakpoints
|
|
||||||
@screen-sm: 480px;
|
|
||||||
@screen-md: 768px;
|
|
||||||
|
|
||||||
// Radii
|
|
||||||
@border-radius-base: 4px;
|
|
||||||
@border-radius-large: 6px;
|
|
||||||
|
|
||||||
// Examples
|
|
||||||
@example-width-audio: 520px;
|
|
||||||
@example-width-video: 1200px;
|
|
46
demo/src/sass/bundles/demo.scss
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
// ==========================================================================
|
||||||
|
// Plyr.io Demo Page
|
||||||
|
// ==========================================================================
|
||||||
|
@charset 'UTF-8';
|
||||||
|
|
||||||
|
// Settings
|
||||||
|
@import '../settings/breakpoints';
|
||||||
|
@import '../settings/colors';
|
||||||
|
@import '../settings/cosmetic';
|
||||||
|
@import '../settings/icons';
|
||||||
|
@import '../settings/layout';
|
||||||
|
@import '../settings/plyr';
|
||||||
|
@import '../settings/spacing';
|
||||||
|
@import '../settings/type';
|
||||||
|
|
||||||
|
// Libs
|
||||||
|
@import '../lib/fontface';
|
||||||
|
@import '../lib/animation';
|
||||||
|
@import '../lib/mixins';
|
||||||
|
@import '../lib/normalize';
|
||||||
|
@import '../lib/reset';
|
||||||
|
|
||||||
|
// Layout
|
||||||
|
@import '../layout/core';
|
||||||
|
@import '../layout/grid';
|
||||||
|
|
||||||
|
// Type
|
||||||
|
@import '../type/base';
|
||||||
|
@import '../type/headings';
|
||||||
|
|
||||||
|
// Components
|
||||||
|
@import '../components/buttons';
|
||||||
|
@import '../components/header';
|
||||||
|
@import '../components/icons';
|
||||||
|
@import '../components/links';
|
||||||
|
@import '../components/lists';
|
||||||
|
@import '../components/media';
|
||||||
|
@import '../components/navigation';
|
||||||
|
@import '../components/players';
|
||||||
|
|
||||||
|
// Plyr
|
||||||
|
@import '../../../../src/sass/plyr';
|
||||||
|
|
||||||
|
// Utils
|
||||||
|
@import '../utilities/cosmetic';
|
||||||
|
@import '../utilities/hidden';
|
29
demo/src/sass/bundles/error.scss
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
// ==========================================================================
|
||||||
|
// Plyr.io Error Page
|
||||||
|
// ==========================================================================
|
||||||
|
@charset 'UTF-8';
|
||||||
|
|
||||||
|
// Settings
|
||||||
|
@import '../settings/colors';
|
||||||
|
@import '../settings/cosmetic';
|
||||||
|
@import '../settings/icons';
|
||||||
|
@import '../settings/layout';
|
||||||
|
@import '../settings/spacing';
|
||||||
|
@import '../settings/type';
|
||||||
|
|
||||||
|
// Libs
|
||||||
|
@import '../lib/fontface';
|
||||||
|
@import '../lib/mixins';
|
||||||
|
@import '../lib/normalize';
|
||||||
|
@import '../lib/reset';
|
||||||
|
|
||||||
|
// Layout
|
||||||
|
@import '../layout/error';
|
||||||
|
|
||||||
|
// Type
|
||||||
|
@import '../type/base';
|
||||||
|
@import '../type/headings';
|
||||||
|
|
||||||
|
// Components
|
||||||
|
@import '../components/buttons';
|
||||||
|
@import '../components/links';
|
83
demo/src/sass/components/buttons.scss
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
// ==========================================================================
|
||||||
|
// Buttons
|
||||||
|
// ==========================================================================
|
||||||
|
|
||||||
|
// Shared
|
||||||
|
.button,
|
||||||
|
.button__count {
|
||||||
|
align-items: center;
|
||||||
|
background: $color-button-background;
|
||||||
|
border: 0;
|
||||||
|
border-radius: $border-radius-base;
|
||||||
|
box-shadow: 0 1px 1px rgba(#000, 0.1);
|
||||||
|
color: $color-button-text;
|
||||||
|
display: inline-flex;
|
||||||
|
padding: ($spacing-base * 0.75);
|
||||||
|
position: relative;
|
||||||
|
text-shadow: none;
|
||||||
|
user-select: none;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Buttons
|
||||||
|
.button {
|
||||||
|
font-weight: $font-weight-bold;
|
||||||
|
padding-left: $spacing-base;
|
||||||
|
padding-right: $spacing-base;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&:focus {
|
||||||
|
color: $gray-dark;
|
||||||
|
|
||||||
|
// Remove the underline/border
|
||||||
|
&::after {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
box-shadow: 0 2px 2px rgba(#000, 0.1);
|
||||||
|
transform: translateY(-1px);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:focus {
|
||||||
|
outline: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.tab-focus {
|
||||||
|
@include tab-focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
transform: translateY(1px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Button group
|
||||||
|
.button--with-count {
|
||||||
|
display: inline-flex;
|
||||||
|
|
||||||
|
.button .icon {
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Count bubble
|
||||||
|
.button__count {
|
||||||
|
animation: fadein 0.2s ease;
|
||||||
|
margin-left: ($spacing-base / 2);
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
border: $arrow-size solid transparent;
|
||||||
|
border-left-width: 0;
|
||||||
|
border-right-color: $color-button-background;
|
||||||
|
content: '';
|
||||||
|
height: 0;
|
||||||
|
position: absolute;
|
||||||
|
right: 100%;
|
||||||
|
top: 50%;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
width: 0;
|
||||||
|
}
|
||||||
|
}
|
19
demo/src/sass/components/header.scss
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
// ==========================================================================
|
||||||
|
// Header
|
||||||
|
// ==========================================================================
|
||||||
|
|
||||||
|
header {
|
||||||
|
padding-bottom: $spacing-base;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
.call-to-action {
|
||||||
|
margin-top: ($spacing-base * 1.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (min-width: $screen-md) {
|
||||||
|
margin-right: ($spacing-base * 3);
|
||||||
|
max-width: 360px;
|
||||||
|
padding-bottom: ($spacing-base * 2);
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
}
|
@ -5,9 +5,9 @@
|
|||||||
// Base size icon styles
|
// Base size icon styles
|
||||||
.icon {
|
.icon {
|
||||||
fill: currentColor;
|
fill: currentColor;
|
||||||
width: @icon-size;
|
height: $icon-size;
|
||||||
height: @icon-size;
|
|
||||||
vertical-align: -3px;
|
vertical-align: -3px;
|
||||||
|
width: $icon-size;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Within elements
|
// Within elements
|
||||||
@ -16,11 +16,8 @@ button svg,
|
|||||||
label svg {
|
label svg {
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
a .icon,
|
a .icon,
|
||||||
.btn .icon {
|
.btn .icon {
|
||||||
margin-right: (@padding-base / 2);
|
margin-right: floor($spacing-base / 3);
|
||||||
}
|
|
||||||
.btn:not(.btn-large) .icon {
|
|
||||||
width: (@icon-size - 2);
|
|
||||||
height: (@icon-size - 2);
|
|
||||||
}
|
}
|
49
demo/src/sass/components/links.scss
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
// ==========================================================================
|
||||||
|
// Links
|
||||||
|
// ==========================================================================
|
||||||
|
|
||||||
|
// Make a <button> look like an <a>
|
||||||
|
button.faux-link {
|
||||||
|
@extend a; // stylelint-disable-line
|
||||||
|
@include cancel-button-styles();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Links
|
||||||
|
a {
|
||||||
|
border-bottom: 1px dotted currentColor;
|
||||||
|
color: $color-link;
|
||||||
|
font-weight: $font-weight-bold;
|
||||||
|
position: relative;
|
||||||
|
text-decoration: none;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
background: currentColor;
|
||||||
|
content: '';
|
||||||
|
height: 1px;
|
||||||
|
left: 50%;
|
||||||
|
position: absolute;
|
||||||
|
top: 100%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
transition: width 0.2s ease;
|
||||||
|
width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&:focus {
|
||||||
|
border-bottom-color: transparent;
|
||||||
|
outline: 0;
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.tab-focus {
|
||||||
|
@include tab-focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
&.no-border::after {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
11
demo/src/sass/components/lists.scss
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
// ==========================================================================
|
||||||
|
// Lists
|
||||||
|
// ==========================================================================
|
||||||
|
|
||||||
|
// Lists
|
||||||
|
ul,
|
||||||
|
li {
|
||||||
|
list-style: none;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
10
demo/src/sass/components/media.scss
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
// ==========================================================================
|
||||||
|
// Basic media
|
||||||
|
// ==========================================================================
|
||||||
|
|
||||||
|
img,
|
||||||
|
video,
|
||||||
|
audio {
|
||||||
|
max-width: 100%;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
9
demo/src/sass/components/navigation.scss
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
// ==========================================================================
|
||||||
|
// Navigation
|
||||||
|
// ==========================================================================
|
||||||
|
|
||||||
|
nav {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
margin-bottom: $spacing-base;
|
||||||
|
}
|
@ -10,31 +10,35 @@ video {
|
|||||||
|
|
||||||
// Example players
|
// Example players
|
||||||
.plyr {
|
.plyr {
|
||||||
margin: 0 auto;
|
border-radius: $border-radius-base;
|
||||||
border-radius: @border-radius-large;
|
box-shadow: 0 2px 5px rgba(#000, 0.2);
|
||||||
}
|
margin: $spacing-base auto;
|
||||||
.plyr--audio {
|
|
||||||
max-width: @example-width-audio;
|
&.plyr--audio {
|
||||||
|
max-width: 480px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.plyr__video-wrapper::after {
|
.plyr__video-wrapper::after {
|
||||||
content: "";
|
border: 1px solid rgba(#000, 0.15);
|
||||||
|
border-radius: inherit;
|
||||||
|
bottom: 0;
|
||||||
|
content: '';
|
||||||
|
left: 0;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
right: 0;
|
||||||
border: 1px solid fade(#000, 15%);
|
top: 0;
|
||||||
border-radius: inherit;
|
z-index: 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Style full supported player
|
// Style full supported player
|
||||||
.plyr__cite {
|
.plyr__cite {
|
||||||
display: none;
|
display: none;
|
||||||
margin-top: @padding-base;
|
margin-top: $spacing-base;
|
||||||
|
|
||||||
.icon {
|
.icon {
|
||||||
margin-right: (@padding-base / 4);
|
margin-right: ceil($spacing-base / 6);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
64
demo/src/sass/layout/core.scss
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
// ==========================================================================
|
||||||
|
// Core
|
||||||
|
// ==========================================================================
|
||||||
|
|
||||||
|
html,
|
||||||
|
body {
|
||||||
|
display: flex;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
html {
|
||||||
|
background: $page-background;
|
||||||
|
background-attachment: fixed;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
align-items: center;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
min-height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grid {
|
||||||
|
flex: 1;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
main {
|
||||||
|
margin: auto;
|
||||||
|
padding-bottom: 1px; // Collapsing margins
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
aside {
|
||||||
|
align-items: center;
|
||||||
|
background: #fff;
|
||||||
|
color: $gray;
|
||||||
|
display: flex;
|
||||||
|
flex-shrink: 0;
|
||||||
|
justify-content: center;
|
||||||
|
padding: ($spacing-base * 0.75);
|
||||||
|
position: relative;
|
||||||
|
text-align: center;
|
||||||
|
text-shadow: none;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
fill: $color-twitter;
|
||||||
|
margin-right: ($spacing-base / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: $color-twitter;
|
||||||
|
|
||||||
|
&.tab-focus {
|
||||||
|
@include tab-focus($color-twitter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -7,13 +7,24 @@ html.error,
|
|||||||
.error body {
|
.error body {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
html.error {
|
||||||
|
background: $page-background;
|
||||||
|
background-attachment: fixed;
|
||||||
|
}
|
||||||
|
|
||||||
.error body {
|
.error body {
|
||||||
|
align-items: center;
|
||||||
|
display: flex;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
display: table;
|
|
||||||
table-layout: fixed;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.error main {
|
.error main {
|
||||||
display: table-cell;
|
padding: $spacing-base;
|
||||||
|
text-align: center;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
vertical-align: middle;
|
|
||||||
|
p {
|
||||||
|
@include font-size($font-size-large);
|
||||||
|
}
|
||||||
}
|
}
|
19
demo/src/sass/layout/grid.scss
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
// ==========================================================================
|
||||||
|
// Super basic grid
|
||||||
|
// ==========================================================================
|
||||||
|
|
||||||
|
.grid {
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: $spacing-base;
|
||||||
|
|
||||||
|
@media only screen and (min-width: $screen-md) {
|
||||||
|
align-items: center;
|
||||||
|
display: flex;
|
||||||
|
max-width: $container-max-width;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
> * {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -3,7 +3,11 @@
|
|||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
|
|
||||||
// Fade
|
// Fade
|
||||||
@keyframes fade-in {
|
@keyframes fadein {
|
||||||
0% { opacity: 0 }
|
0% {
|
||||||
100% { opacity: 1 }
|
opacity: 0;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
}
|
}
|
45
demo/src/sass/lib/fontface.scss
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
// ==========================================================================
|
||||||
|
// Fonts
|
||||||
|
// ==========================================================================
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-display: swap;
|
||||||
|
font-family: 'Gordita';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: $font-weight-light;
|
||||||
|
src: url('https://cdn.plyr.io/static/fonts/gordita-light.woff2') format('woff2'), url('https://cdn.plyr.io/static/fonts/gordita-light.woff') format('woff');
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-display: swap;
|
||||||
|
font-family: 'Gordita';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: $font-weight-regular;
|
||||||
|
src: url('https://cdn.plyr.io/static/fonts/gordita-regular.woff2') format('woff2'),
|
||||||
|
url('https://cdn.plyr.io/static/fonts/gordita-regular.woff') format('woff');
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-display: swap;
|
||||||
|
font-family: 'Gordita';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: $font-weight-medium;
|
||||||
|
src: url('https://cdn.plyr.io/static/fonts/gordita-medium.woff2') format('woff2'),
|
||||||
|
url('https://cdn.plyr.io/static/fonts/gordita-medium.woff') format('woff');
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-display: swap;
|
||||||
|
font-family: 'Gordita';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: $font-weight-bold;
|
||||||
|
src: url('https://cdn.plyr.io/static/fonts/gordita-bold.woff2') format('woff2'), url('https://cdn.plyr.io/static/fonts/gordita-bold.woff') format('woff');
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-display: swap;
|
||||||
|
font-family: 'Gordita';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: $font-weight-black;
|
||||||
|
src: url('https://cdn.plyr.io/static/fonts/gordita-black.woff2') format('woff2'), url('https://cdn.plyr.io/static/fonts/gordita-black.woff') format('woff');
|
||||||
|
}
|
54
demo/src/sass/lib/mixins.scss
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
// ==========================================================================
|
||||||
|
// Mixins
|
||||||
|
// ==========================================================================
|
||||||
|
|
||||||
|
// Convert a <button> into an <a>
|
||||||
|
// ---------------------------------------
|
||||||
|
@mixin cancel-button-styles() {
|
||||||
|
background: transparent;
|
||||||
|
border: 0;
|
||||||
|
border-radius: 0;
|
||||||
|
cursor: pointer;
|
||||||
|
font: inherit;
|
||||||
|
line-height: $line-height-base;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
position: relative;
|
||||||
|
text-align: inherit;
|
||||||
|
text-shadow: inherit;
|
||||||
|
-moz-user-select: text; // stylelint-disable-line
|
||||||
|
vertical-align: baseline;
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Nicer focus styles
|
||||||
|
// ---------------------------------------
|
||||||
|
@mixin tab-focus($color: $tab-focus-default-color) {
|
||||||
|
box-shadow: 0 0 0 3px rgba($color, 0.35);
|
||||||
|
outline: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use rems for font sizing
|
||||||
|
// Leave <body> at 100%/16px
|
||||||
|
// ---------------------------------------
|
||||||
|
@function calculate-rem($size) {
|
||||||
|
$rem: $size / 16;
|
||||||
|
@return #{$rem}rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin font-size($size: 16) {
|
||||||
|
font-size: $size * 1px; // Fallback in px
|
||||||
|
font-size: calculate-rem($size);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Font smoothing
|
||||||
|
// ---------------------------------------
|
||||||
|
@mixin font-smoothing($enabled: true) {
|
||||||
|
@if $enabled {
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
} @else {
|
||||||
|
-moz-osx-font-smoothing: auto;
|
||||||
|
-webkit-font-smoothing: subpixel-antialiased;
|
||||||
|
}
|
||||||
|
}
|
450
demo/src/sass/lib/normalize.scss
vendored
Normal file
@ -0,0 +1,450 @@
|
|||||||
|
/*! normalize.css v7.0.0 | MIT License | github.com/necolas/normalize.css */
|
||||||
|
|
||||||
|
/* Document
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1. Correct the line height in all browsers.
|
||||||
|
* 2. Prevent adjustments of font size after orientation changes in
|
||||||
|
* IE on Windows Phone and in iOS.
|
||||||
|
*/
|
||||||
|
|
||||||
|
html {
|
||||||
|
line-height: 1.15; /* 1 */
|
||||||
|
-ms-text-size-adjust: 100%; /* 2 */
|
||||||
|
-webkit-text-size-adjust: 100%; /* 2 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Sections
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the margin in all browsers (opinionated).
|
||||||
|
*/
|
||||||
|
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the correct display in IE 9-.
|
||||||
|
*/
|
||||||
|
|
||||||
|
article,
|
||||||
|
aside,
|
||||||
|
footer,
|
||||||
|
header,
|
||||||
|
nav,
|
||||||
|
section {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Correct the font size and margin on `h1` elements within `section` and
|
||||||
|
* `article` contexts in Chrome, Firefox, and Safari.
|
||||||
|
*/
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 2em;
|
||||||
|
margin: 0.67em 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Grouping content
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the correct display in IE 9-.
|
||||||
|
* 1. Add the correct display in IE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
figcaption,
|
||||||
|
figure,
|
||||||
|
main {
|
||||||
|
/* 1 */
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the correct margin in IE 8.
|
||||||
|
*/
|
||||||
|
|
||||||
|
figure {
|
||||||
|
margin: 1em 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1. Add the correct box sizing in Firefox.
|
||||||
|
* 2. Show the overflow in Edge and IE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
hr {
|
||||||
|
box-sizing: content-box; /* 1 */
|
||||||
|
height: 0; /* 1 */
|
||||||
|
overflow: visible; /* 2 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1. Correct the inheritance and scaling of font size in all browsers.
|
||||||
|
* 2. Correct the odd `em` font sizing in all browsers.
|
||||||
|
*/
|
||||||
|
|
||||||
|
pre {
|
||||||
|
font-family: monospace, monospace; /* 1 */
|
||||||
|
font-size: 1em; /* 2 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Text-level semantics
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1. Remove the gray background on active links in IE 10.
|
||||||
|
* 2. Remove gaps in links underline in iOS 8+ and Safari 8+.
|
||||||
|
*/
|
||||||
|
|
||||||
|
a {
|
||||||
|
background-color: transparent; /* 1 */
|
||||||
|
-webkit-text-decoration-skip: objects; /* 2 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1. Remove the bottom border in Chrome 57- and Firefox 39-.
|
||||||
|
* 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
|
||||||
|
*/
|
||||||
|
|
||||||
|
abbr[title] {
|
||||||
|
border-bottom: none; /* 1 */
|
||||||
|
text-decoration: underline; /* 2 */
|
||||||
|
text-decoration: underline dotted; /* 2 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prevent the duplicate application of `bolder` by the next rule in Safari 6.
|
||||||
|
*/
|
||||||
|
|
||||||
|
b,
|
||||||
|
strong {
|
||||||
|
font-weight: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the correct font weight in Chrome, Edge, and Safari.
|
||||||
|
*/
|
||||||
|
|
||||||
|
b,
|
||||||
|
strong {
|
||||||
|
font-weight: bolder;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1. Correct the inheritance and scaling of font size in all browsers.
|
||||||
|
* 2. Correct the odd `em` font sizing in all browsers.
|
||||||
|
*/
|
||||||
|
|
||||||
|
code,
|
||||||
|
kbd,
|
||||||
|
samp {
|
||||||
|
font-family: monospace, monospace; /* 1 */
|
||||||
|
font-size: 1em; /* 2 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the correct font style in Android 4.3-.
|
||||||
|
*/
|
||||||
|
|
||||||
|
dfn {
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the correct background and color in IE 9-.
|
||||||
|
*/
|
||||||
|
|
||||||
|
mark {
|
||||||
|
background-color: #ff0;
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the correct font size in all browsers.
|
||||||
|
*/
|
||||||
|
|
||||||
|
small {
|
||||||
|
font-size: 80%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prevent `sub` and `sup` elements from affecting the line height in
|
||||||
|
* all browsers.
|
||||||
|
*/
|
||||||
|
|
||||||
|
sub,
|
||||||
|
sup {
|
||||||
|
font-size: 75%;
|
||||||
|
line-height: 0;
|
||||||
|
position: relative;
|
||||||
|
vertical-align: baseline;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub {
|
||||||
|
bottom: -0.25em;
|
||||||
|
}
|
||||||
|
|
||||||
|
sup {
|
||||||
|
top: -0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Embedded content
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the correct display in IE 9-.
|
||||||
|
*/
|
||||||
|
|
||||||
|
audio,
|
||||||
|
video {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the correct display in iOS 4-7.
|
||||||
|
*/
|
||||||
|
|
||||||
|
audio:not([controls]) {
|
||||||
|
display: none;
|
||||||
|
height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the border on images inside links in IE 10-.
|
||||||
|
*/
|
||||||
|
|
||||||
|
img {
|
||||||
|
border-style: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hide the overflow in IE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
svg:not(:root) {
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Forms
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1. Change the font styles in all browsers (opinionated).
|
||||||
|
* 2. Remove the margin in Firefox and Safari.
|
||||||
|
*/
|
||||||
|
|
||||||
|
button,
|
||||||
|
input,
|
||||||
|
optgroup,
|
||||||
|
select,
|
||||||
|
textarea {
|
||||||
|
font-family: sans-serif; /* 1 */
|
||||||
|
font-size: 100%; /* 1 */
|
||||||
|
line-height: 1.15; /* 1 */
|
||||||
|
margin: 0; /* 2 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the overflow in IE.
|
||||||
|
* 1. Show the overflow in Edge.
|
||||||
|
*/
|
||||||
|
|
||||||
|
button,
|
||||||
|
input {
|
||||||
|
/* 1 */
|
||||||
|
overflow: visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the inheritance of text transform in Edge, Firefox, and IE.
|
||||||
|
* 1. Remove the inheritance of text transform in Firefox.
|
||||||
|
*/
|
||||||
|
|
||||||
|
button,
|
||||||
|
select {
|
||||||
|
/* 1 */
|
||||||
|
text-transform: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1. Prevent a WebKit bug where (2) destroys native `audio` and `video`
|
||||||
|
* controls in Android 4.
|
||||||
|
* 2. Correct the inability to style clickable types in iOS and Safari.
|
||||||
|
*/
|
||||||
|
|
||||||
|
button,
|
||||||
|
html [type='button'],
|
||||||
|
[type='reset'],
|
||||||
|
[type='submit'] {
|
||||||
|
-webkit-appearance: button; /* 2 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the inner border and padding in Firefox.
|
||||||
|
*/
|
||||||
|
|
||||||
|
button::-moz-focus-inner,
|
||||||
|
[type='button']::-moz-focus-inner,
|
||||||
|
[type='reset']::-moz-focus-inner,
|
||||||
|
[type='submit']::-moz-focus-inner {
|
||||||
|
border-style: none;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restore the focus styles unset by the previous rule.
|
||||||
|
*/
|
||||||
|
|
||||||
|
button:-moz-focusring,
|
||||||
|
[type='button']:-moz-focusring,
|
||||||
|
[type='reset']:-moz-focusring,
|
||||||
|
[type='submit']:-moz-focusring {
|
||||||
|
outline: 1px dotted ButtonText;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Correct the padding in Firefox.
|
||||||
|
*/
|
||||||
|
|
||||||
|
fieldset {
|
||||||
|
padding: 0.35em 0.75em 0.625em;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1. Correct the text wrapping in Edge and IE.
|
||||||
|
* 2. Correct the color inheritance from `fieldset` elements in IE.
|
||||||
|
* 3. Remove the padding so developers are not caught out when they zero out
|
||||||
|
* `fieldset` elements in all browsers.
|
||||||
|
*/
|
||||||
|
|
||||||
|
legend {
|
||||||
|
box-sizing: border-box; /* 1 */
|
||||||
|
color: inherit; /* 2 */
|
||||||
|
display: table; /* 1 */
|
||||||
|
max-width: 100%; /* 1 */
|
||||||
|
padding: 0; /* 3 */
|
||||||
|
white-space: normal; /* 1 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1. Add the correct display in IE 9-.
|
||||||
|
* 2. Add the correct vertical alignment in Chrome, Firefox, and Opera.
|
||||||
|
*/
|
||||||
|
|
||||||
|
progress {
|
||||||
|
display: inline-block; /* 1 */
|
||||||
|
vertical-align: baseline; /* 2 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the default vertical scrollbar in IE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
textarea {
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1. Add the correct box sizing in IE 10-.
|
||||||
|
* 2. Remove the padding in IE 10-.
|
||||||
|
*/
|
||||||
|
|
||||||
|
[type='checkbox'],
|
||||||
|
[type='radio'] {
|
||||||
|
box-sizing: border-box; /* 1 */
|
||||||
|
padding: 0; /* 2 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Correct the cursor style of increment and decrement buttons in Chrome.
|
||||||
|
*/
|
||||||
|
|
||||||
|
[type='number']::-webkit-inner-spin-button,
|
||||||
|
[type='number']::-webkit-outer-spin-button {
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1. Correct the odd appearance in Chrome and Safari.
|
||||||
|
* 2. Correct the outline style in Safari.
|
||||||
|
*/
|
||||||
|
|
||||||
|
[type='search'] {
|
||||||
|
-webkit-appearance: textfield; /* 1 */
|
||||||
|
outline-offset: -2px; /* 2 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the inner padding and cancel buttons in Chrome and Safari on macOS.
|
||||||
|
*/
|
||||||
|
|
||||||
|
[type='search']::-webkit-search-cancel-button,
|
||||||
|
[type='search']::-webkit-search-decoration {
|
||||||
|
-webkit-appearance: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1. Correct the inability to style clickable types in iOS and Safari.
|
||||||
|
* 2. Change font properties to `inherit` in Safari.
|
||||||
|
*/
|
||||||
|
|
||||||
|
::-webkit-file-upload-button {
|
||||||
|
-webkit-appearance: button; /* 1 */
|
||||||
|
font: inherit; /* 2 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Interactive
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add the correct display in IE 9-.
|
||||||
|
* 1. Add the correct display in Edge, IE, and Firefox.
|
||||||
|
*/
|
||||||
|
|
||||||
|
details,
|
||||||
|
menu {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add the correct display in all browsers.
|
||||||
|
*/
|
||||||
|
|
||||||
|
summary {
|
||||||
|
display: list-item;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Scripting
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the correct display in IE 9-.
|
||||||
|
*/
|
||||||
|
|
||||||
|
canvas {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the correct display in IE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
template {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Hidden
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the correct display in IE 10-.
|
||||||
|
*/
|
||||||
|
|
||||||
|
[hidden] {
|
||||||
|
display: none;
|
||||||
|
}
|
11
demo/src/sass/lib/reset.scss
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
// ==========================================================================
|
||||||
|
// Resets
|
||||||
|
// ==========================================================================
|
||||||
|
|
||||||
|
// BORDER-BOX ALL THE THINGS!
|
||||||
|
// http://paulirish.com/2012/box-sizing-border-box-ftw/
|
||||||
|
*,
|
||||||
|
*::after,
|
||||||
|
*::before {
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
6
demo/src/sass/settings/breakpoints.scss
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
// ==========================================================================
|
||||||
|
// Breakpoints
|
||||||
|
// ==========================================================================
|
||||||
|
|
||||||
|
$screen-sm: 480px;
|
||||||
|
$screen-md: 768px;
|
32
demo/src/sass/settings/colors.scss
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
// ==========================================================================
|
||||||
|
// Colors
|
||||||
|
// ==========================================================================
|
||||||
|
|
||||||
|
// Greyscale
|
||||||
|
$gray-dark: #343f4a;
|
||||||
|
$gray: #55646b;
|
||||||
|
$gray-light: #cbd0d3;
|
||||||
|
$gray-lighter: #dbe3e8;
|
||||||
|
$off-white: #f2f5f7;
|
||||||
|
|
||||||
|
// Text
|
||||||
|
$color-text: #fff;
|
||||||
|
|
||||||
|
// Plyr
|
||||||
|
$color-brand-primary: #1aafff;
|
||||||
|
|
||||||
|
// Brands
|
||||||
|
$color-twitter: #4baaf4;
|
||||||
|
$color-youtube: #cc181e;
|
||||||
|
$color-vimeo: #19b7ed;
|
||||||
|
|
||||||
|
// Elements
|
||||||
|
$color-link: #fff;
|
||||||
|
$color-background: $color-brand-primary;
|
||||||
|
|
||||||
|
// Buttons
|
||||||
|
$color-button-background: #fff;
|
||||||
|
$color-button-text: $gray;
|
||||||
|
|
||||||
|
// Focus
|
||||||
|
$tab-focus-default-color: #fff;
|
12
demo/src/sass/settings/cosmetic.scss
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
// ==========================================================================
|
||||||
|
// Misc cosmetic
|
||||||
|
// ==========================================================================
|
||||||
|
|
||||||
|
// Button count arrow size
|
||||||
|
$arrow-size: 5px;
|
||||||
|
|
||||||
|
// Radii
|
||||||
|
$border-radius-base: 4px;
|
||||||
|
|
||||||
|
// Background
|
||||||
|
$page-background: linear-gradient(to left top, lighten($color-background, 10%), darken($color-background, 20%));
|
5
demo/src/sass/settings/icons.scss
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
// ==========================================================================
|
||||||
|
// Icons
|
||||||
|
// ==========================================================================
|
||||||
|
|
||||||
|
$icon-size: 16px;
|
5
demo/src/sass/settings/layout.scss
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
// ==========================================================================
|
||||||
|
// Layout
|
||||||
|
// ==========================================================================
|
||||||
|
|
||||||
|
$container-max-width: 1260px;
|
19
demo/src/sass/settings/plyr.scss
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
// ==========================================================================
|
||||||
|
// Plyr Settings
|
||||||
|
// ==========================================================================
|
||||||
|
|
||||||
|
// Font
|
||||||
|
$plyr-font-family: inherit;
|
||||||
|
|
||||||
|
// Sizes
|
||||||
|
$plyr-font-size-base: 13px;
|
||||||
|
$plyr-font-size-small: 12px;
|
||||||
|
$plyr-font-size-time: 11px;
|
||||||
|
$plyr-font-size-badges: 9px;
|
||||||
|
|
||||||
|
// Captions
|
||||||
|
$plyr-font-size-captions-base: $plyr-font-size-base;
|
||||||
|
$plyr-font-size-captions-small: $plyr-font-size-small;
|
||||||
|
$plyr-font-size-captions-medium: 18px;
|
||||||
|
$plyr-font-size-captions-large: 21px;
|
||||||
|
$plyr-font-size-menu: $plyr-font-size-base;
|
5
demo/src/sass/settings/spacing.scss
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
// ==========================================================================
|
||||||
|
// Colors
|
||||||
|
// ==========================================================================
|
||||||
|
|
||||||
|
$spacing-base: 20px;
|
20
demo/src/sass/settings/type.scss
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
// ==========================================================================
|
||||||
|
// Typography
|
||||||
|
// ==========================================================================
|
||||||
|
|
||||||
|
$font-sans-serif: 'Gordita', 'Avenir', 'Helvetica Neue', sans-serif;
|
||||||
|
|
||||||
|
$font-size-base: 15;
|
||||||
|
$font-size-small: 13;
|
||||||
|
$font-size-large: 18;
|
||||||
|
$font-size-h1: 64;
|
||||||
|
|
||||||
|
$font-weight-light: 300;
|
||||||
|
$font-weight-regular: 400;
|
||||||
|
$font-weight-medium: 500;
|
||||||
|
$font-weight-bold: 600;
|
||||||
|
$font-weight-black: 900;
|
||||||
|
|
||||||
|
$line-height-base: 1.75;
|
||||||
|
|
||||||
|
$letter-spacing-headings: -0.025em;
|
35
demo/src/sass/type/base.scss
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
// ==========================================================================
|
||||||
|
// Base
|
||||||
|
// ==========================================================================
|
||||||
|
|
||||||
|
// Set to 100% for rem sizing
|
||||||
|
html {
|
||||||
|
font-size: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
@include font-smoothing();
|
||||||
|
@include font-size($font-size-base);
|
||||||
|
color: $color-text;
|
||||||
|
font-family: $font-sans-serif;
|
||||||
|
font-weight: $font-weight-medium;
|
||||||
|
line-height: $line-height-base;
|
||||||
|
text-shadow: 0 1px 1px rgba(#000, 0.15);
|
||||||
|
}
|
||||||
|
|
||||||
|
button,
|
||||||
|
input,
|
||||||
|
select,
|
||||||
|
textarea {
|
||||||
|
font: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
p,
|
||||||
|
small {
|
||||||
|
margin: 0 0 $spacing-base;
|
||||||
|
}
|
||||||
|
|
||||||
|
small {
|
||||||
|
@include font-size($font-size-small);
|
||||||
|
display: block;
|
||||||
|
}
|
11
demo/src/sass/type/headings.scss
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
// ==========================================================================
|
||||||
|
// Headings
|
||||||
|
// ==========================================================================
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
@include font-size($font-size-h1);
|
||||||
|
font-weight: $font-weight-bold;
|
||||||
|
letter-spacing: $letter-spacing-headings;
|
||||||
|
line-height: 1.2;
|
||||||
|
margin: 0 0 $spacing-base;
|
||||||
|
}
|
7
demo/src/sass/utilities/cosmetic.scss
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
// ==========================================================================
|
||||||
|
// Misc cosmetic
|
||||||
|
// ==========================================================================
|
||||||
|
|
||||||
|
.no-border {
|
||||||
|
border: 0;
|
||||||
|
}
|
20
demo/src/sass/utilities/hidden.scss
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
// ==========================================================================
|
||||||
|
// Hidden
|
||||||
|
// ==========================================================================
|
||||||
|
|
||||||
|
[hidden] {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hide only visually, but have it available for screen readers: h5bp.com/v
|
||||||
|
.sr-only {
|
||||||
|
border: 0;
|
||||||
|
clip: rect(0 0 0 0);
|
||||||
|
height: 1px;
|
||||||
|
margin: -1px;
|
||||||
|
opacity: 0.001;
|
||||||
|
overflow: hidden;
|
||||||
|
padding: 0;
|
||||||
|
position: absolute;
|
||||||
|
width: 1px;
|
||||||
|
}
|
@ -1,12 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!-- Generator: Adobe Illustrator 19.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
|
||||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
|
||||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
|
||||||
width="16px" height="16px" viewBox="0 0 16 16" enable-background="new 0 0 16 16" xml:space="preserve">
|
|
||||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M8,0.2c-4.4,0-8,3.6-8,8c0,3.5,2.3,6.5,5.5,7.6
|
|
||||||
C5.9,15.9,6,15.6,6,15.4c0-0.2,0-0.7,0-1.4C3.8,14.5,3.3,13,3.3,13c-0.4-0.9-0.9-1.2-0.9-1.2c-0.7-0.5,0.1-0.5,0.1-0.5
|
|
||||||
c0.8,0.1,1.2,0.8,1.2,0.8C4.4,13.4,5.6,13,6,12.8c0.1-0.5,0.3-0.9,0.5-1.1c-1.8-0.2-3.6-0.9-3.6-4c0-0.9,0.3-1.6,0.8-2.1
|
|
||||||
c-0.1-0.2-0.4-1,0.1-2.1c0,0,0.7-0.2,2.2,0.8c0.6-0.2,1.3-0.3,2-0.3c0.7,0,1.4,0.1,2,0.3c1.5-1,2.2-0.8,2.2-0.8
|
|
||||||
c0.4,1.1,0.2,1.9,0.1,2.1c0.5,0.6,0.8,1.3,0.8,2.1c0,3.1-1.9,3.7-3.7,3.9C9.7,12,10,12.5,10,13.2c0,1.1,0,1.9,0,2.2
|
|
||||||
c0,0.2,0.1,0.5,0.6,0.4c3.2-1.1,5.5-4.1,5.5-7.6C16,3.8,12.4,0.2,8,0.2z"/>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 1.1 KiB |
@ -1,11 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!-- Generator: Adobe Illustrator 19.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
|
||||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
|
||||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
|
||||||
width="16px" height="16px" viewBox="0 0 16 16" enable-background="new 0 0 16 16" xml:space="preserve">
|
|
||||||
<title>Twitter</title>
|
|
||||||
<path d="M16,3c-0.6,0.3-1.2,0.4-1.9,0.5c0.7-0.4,1.2-1,1.4-1.8c-0.6,0.4-1.3,0.6-2.1,0.8c-0.6-0.6-1.5-1-2.4-1
|
|
||||||
C9.3,1.5,7.8,3,7.8,4.8c0,0.3,0,0.5,0.1,0.7C5.2,5.4,2.7,4.1,1.1,2.1c-0.3,0.5-0.4,1-0.4,1.7c0,1.1,0.6,2.1,1.5,2.7
|
|
||||||
c-0.5,0-1-0.2-1.5-0.4c0,0,0,0,0,0c0,1.6,1.1,2.9,2.6,3.2C3,9.4,2.7,9.4,2.4,9.4c-0.2,0-0.4,0-0.6-0.1c0.4,1.3,1.6,2.3,3.1,2.3
|
|
||||||
c-1.1,0.9-2.5,1.4-4.1,1.4c-0.3,0-0.5,0-0.8,0c1.5,0.9,3.2,1.5,5,1.5c6,0,9.3-5,9.3-9.3c0-0.1,0-0.3,0-0.4C15,4.3,15.6,3.7,16,3z"/>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 981 B |
@ -1,9 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!-- Generator: Adobe Illustrator 19.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
|
||||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
|
||||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
|
||||||
width="16px" height="16px" viewBox="0 0 16 16" enable-background="new 0 0 16 16" xml:space="preserve">
|
|
||||||
<path d="M16,4.3c-0.1,1.6-1.2,3.7-3.3,6.4c-2.2,2.8-4,4.2-5.5,4.2c-0.9,0-1.7-0.9-2.4-2.6C4,9.9,3.4,5,2,5
|
|
||||||
C1.9,5,1.5,5.3,0.8,5.8L0,4.8c0.8-0.7,3.5-3.4,4.7-3.5C5.9,1.2,6.7,2,7,3.8c0.3,2,0.8,6.1,1.8,6.1c0.9,0,2.5-3.4,2.6-4
|
|
||||||
c0.1-0.9-0.3-1.9-2.3-1.1c0.8-2.6,2.3-3.8,4.5-3.8C15.3,1.1,16.1,2.2,16,4.3z"/>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 779 B |
@ -1,9 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!-- Generator: Adobe Illustrator 19.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
|
||||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
|
||||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
|
||||||
width="16px" height="16px" viewBox="0 0 16 16" enable-background="new 0 0 16 16" xml:space="preserve">
|
|
||||||
<path d="M15.8,4.8c-0.2-1.3-0.8-2.2-2.2-2.4C11.4,2,8,2,8,2S4.6,2,2.4,2.4C1,2.6,0.3,3.5,0.2,4.8C0,6.1,0,8,0,8
|
|
||||||
s0,1.9,0.2,3.2c0.2,1.3,0.8,2.2,2.2,2.4C4.6,14,8,14,8,14s3.4,0,5.6-0.4c1.4-0.3,2-1.1,2.2-2.4C16,9.9,16,8,16,8S16,6.1,15.8,4.8z
|
|
||||||
M6,11V5l5,3L6,11z"/>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 739 B |
BIN
dist/blank.mp4
vendored
Normal file
2
dist/plyr.css
vendored
8148
dist/plyr.js
vendored
1
dist/plyr.js.map
vendored
Normal file
2
dist/plyr.min.js
vendored
Normal file
1
dist/plyr.min.js.map
vendored
Normal file
13529
dist/plyr.polyfilled.js
vendored
Normal file
1
dist/plyr.polyfilled.js.map
vendored
Normal file
2
dist/plyr.polyfilled.min.js
vendored
Normal file
1
dist/plyr.polyfilled.min.js.map
vendored
Normal file
2
dist/plyr.svg
vendored
@ -1 +1 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg"><symbol id="plyr-captions-off" viewBox="0 0 18 18"><path d="M1 1c-.6 0-1 .4-1 1v11c0 .6.4 1 1 1h4.6l2.7 2.7c.2.2.4.3.7.3.3 0 .5-.1.7-.3l2.7-2.7H17c.6 0 1-.4 1-1V2c0-.6-.4-1-1-1H1zm4.52 10.15c1.99 0 3.01-1.32 3.28-2.41l-1.29-.39c-.19.66-.78 1.45-1.99 1.45-1.14 0-2.2-.83-2.2-2.34 0-1.61 1.12-2.37 2.18-2.37 1.23 0 1.78.75 1.95 1.43l1.3-.41C8.47 4.96 7.46 3.76 5.5 3.76c-1.9 0-3.61 1.44-3.61 3.7 0 2.26 1.65 3.69 3.63 3.69zm7.57 0c1.99 0 3.01-1.32 3.28-2.41l-1.29-.39c-.19.66-.78 1.45-1.99 1.45-1.14 0-2.2-.83-2.2-2.34 0-1.61 1.12-2.37 2.18-2.37 1.23 0 1.78.75 1.95 1.43l1.3-.41c-.28-1.15-1.29-2.35-3.25-2.35-1.9 0-3.61 1.44-3.61 3.7 0 2.26 1.65 3.69 3.63 3.69z" fill-rule="evenodd" fill-opacity=".5"/></symbol><symbol id="plyr-captions-on" viewBox="0 0 18 18"><path d="M1 1c-.6 0-1 .4-1 1v11c0 .6.4 1 1 1h4.6l2.7 2.7c.2.2.4.3.7.3.3 0 .5-.1.7-.3l2.7-2.7H17c.6 0 1-.4 1-1V2c0-.6-.4-1-1-1H1zm4.52 10.15c1.99 0 3.01-1.32 3.28-2.41l-1.29-.39c-.19.66-.78 1.45-1.99 1.45-1.14 0-2.2-.83-2.2-2.34 0-1.61 1.12-2.37 2.18-2.37 1.23 0 1.78.75 1.95 1.43l1.3-.41C8.47 4.96 7.46 3.76 5.5 3.76c-1.9 0-3.61 1.44-3.61 3.7 0 2.26 1.65 3.69 3.63 3.69zm7.57 0c1.99 0 3.01-1.32 3.28-2.41l-1.29-.39c-.19.66-.78 1.45-1.99 1.45-1.14 0-2.2-.83-2.2-2.34 0-1.61 1.12-2.37 2.18-2.37 1.23 0 1.78.75 1.95 1.43l1.3-.41c-.28-1.15-1.29-2.35-3.25-2.35-1.9 0-3.61 1.44-3.61 3.7 0 2.26 1.65 3.69 3.63 3.69z" fill-rule="evenodd"/></symbol><symbol id="plyr-enter-fullscreen" viewBox="0 0 18 18"><path d="M10 3h3.6l-4 4L11 8.4l4-4V8h2V1h-7zM7 9.6l-4 4V10H1v7h7v-2H4.4l4-4z"/></symbol><symbol id="plyr-exit-fullscreen" viewBox="0 0 18 18"><path d="M1 12h3.6l-4 4L2 17.4l4-4V17h2v-7H1zM16 .6l-4 4V1h-2v7h7V6h-3.6l4-4z"/></symbol><symbol id="plyr-fast-forward" viewBox="0 0 18 18"><path d="M7.875 7.171L0 1v16l7.875-6.171V17L18 9 7.875 1z"/></symbol><symbol id="plyr-muted" viewBox="0 0 18 18"><path d="M12.4 12.5l2.1-2.1 2.1 2.1 1.4-1.4L15.9 9 18 6.9l-1.4-1.4-2.1 2.1-2.1-2.1L11 6.9 13.1 9 11 11.1zM3.786 6.008H.714C.286 6.008 0 6.31 0 6.76v4.512c0 .452.286.752.714.752h3.072l4.071 3.858c.5.3 1.143 0 1.143-.602V2.752c0-.601-.643-.977-1.143-.601L3.786 6.008z"/></symbol><symbol id="plyr-pause" viewBox="0 0 18 18"><path d="M6 1H3c-.6 0-1 .4-1 1v14c0 .6.4 1 1 1h3c.6 0 1-.4 1-1V2c0-.6-.4-1-1-1zM12 1c-.6 0-1 .4-1 1v14c0 .6.4 1 1 1h3c.6 0 1-.4 1-1V2c0-.6-.4-1-1-1h-3z"/></symbol><symbol id="plyr-play" viewBox="0 0 18 18"><path d="M15.562 8.1L3.87.225C3.052-.337 2 .225 2 1.125v15.75c0 .9 1.052 1.462 1.87.9L15.563 9.9c.584-.45.584-1.35 0-1.8z"/></symbol><symbol id="plyr-restart" viewBox="0 0 18 18"><path d="M9.7 1.2l.7 6.4 2.1-2.1c1.9 1.9 1.9 5.1 0 7-.9 1-2.2 1.5-3.5 1.5-1.3 0-2.6-.5-3.5-1.5-1.9-1.9-1.9-5.1 0-7 .6-.6 1.4-1.1 2.3-1.3l-.6-1.9C6 2.6 4.9 3.2 4 4.1 1.3 6.8 1.3 11.2 4 14c1.3 1.3 3.1 2 4.9 2 1.9 0 3.6-.7 4.9-2 2.7-2.7 2.7-7.1 0-9.9L16 1.9l-6.3-.7z"/></symbol><symbol id="plyr-rewind" viewBox="0 0 18 18"><path d="M10.125 1L0 9l10.125 8v-6.171L18 17V1l-7.875 6.171z"/></symbol><symbol id="plyr-volume" viewBox="0 0 18 18"><path d="M15.6 3.3c-.4-.4-1-.4-1.4 0-.4.4-.4 1 0 1.4C15.4 5.9 16 7.4 16 9c0 1.6-.6 3.1-1.8 4.3-.4.4-.4 1 0 1.4.2.2.5.3.7.3.3 0 .5-.1.7-.3C17.1 13.2 18 11.2 18 9s-.9-4.2-2.4-5.7z"/><path d="M11.282 5.282a.909.909 0 0 0 0 1.316c.735.735.995 1.458.995 2.402 0 .936-.425 1.917-.995 2.487a.909.909 0 0 0 0 1.316c.145.145.636.262 1.018.156a.725.725 0 0 0 .298-.156C13.773 11.733 14.13 10.16 14.13 9c0-.17-.002-.34-.011-.51-.053-.992-.319-2.005-1.522-3.208a.909.909 0 0 0-1.316 0zM3.786 6.008H.714C.286 6.008 0 6.31 0 6.76v4.512c0 .452.286.752.714.752h3.072l4.071 3.858c.5.3 1.143 0 1.143-.602V2.752c0-.601-.643-.977-1.143-.601L3.786 6.008z"/></symbol></svg>
|
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg"><symbol id="plyr-airplay" viewBox="0 0 18 18"><path d="M16 1H2a1 1 0 0 0-1 1v10a1 1 0 0 0 1 1h3v-2H3V3h12v8h-2v2h3a1 1 0 0 0 1-1V2a1 1 0 0 0-1-1z"/><path d="M4 17h10l-5-6z"/></symbol><symbol id="plyr-captions-off" viewBox="0 0 18 18"><path d="M1 1c-.6 0-1 .4-1 1v11c0 .6.4 1 1 1h4.6l2.7 2.7c.2.2.4.3.7.3.3 0 .5-.1.7-.3l2.7-2.7H17c.6 0 1-.4 1-1V2c0-.6-.4-1-1-1H1zm4.52 10.15c1.99 0 3.01-1.32 3.28-2.41l-1.29-.39c-.19.66-.78 1.45-1.99 1.45-1.14 0-2.2-.83-2.2-2.34 0-1.61 1.12-2.37 2.18-2.37 1.23 0 1.78.75 1.95 1.43l1.3-.41C8.47 4.96 7.46 3.76 5.5 3.76c-1.9 0-3.61 1.44-3.61 3.7 0 2.26 1.65 3.69 3.63 3.69zm7.57 0c1.99 0 3.01-1.32 3.28-2.41l-1.29-.39c-.19.66-.78 1.45-1.99 1.45-1.14 0-2.2-.83-2.2-2.34 0-1.61 1.12-2.37 2.18-2.37 1.23 0 1.78.75 1.95 1.43l1.3-.41c-.28-1.15-1.29-2.35-3.25-2.35-1.9 0-3.61 1.44-3.61 3.7 0 2.26 1.65 3.69 3.63 3.69z" fill-rule="evenodd" fill-opacity=".5"/></symbol><symbol id="plyr-captions-on" viewBox="0 0 18 18"><path d="M1 1c-.6 0-1 .4-1 1v11c0 .6.4 1 1 1h4.6l2.7 2.7c.2.2.4.3.7.3.3 0 .5-.1.7-.3l2.7-2.7H17c.6 0 1-.4 1-1V2c0-.6-.4-1-1-1H1zm4.52 10.15c1.99 0 3.01-1.32 3.28-2.41l-1.29-.39c-.19.66-.78 1.45-1.99 1.45-1.14 0-2.2-.83-2.2-2.34 0-1.61 1.12-2.37 2.18-2.37 1.23 0 1.78.75 1.95 1.43l1.3-.41C8.47 4.96 7.46 3.76 5.5 3.76c-1.9 0-3.61 1.44-3.61 3.7 0 2.26 1.65 3.69 3.63 3.69zm7.57 0c1.99 0 3.01-1.32 3.28-2.41l-1.29-.39c-.19.66-.78 1.45-1.99 1.45-1.14 0-2.2-.83-2.2-2.34 0-1.61 1.12-2.37 2.18-2.37 1.23 0 1.78.75 1.95 1.43l1.3-.41c-.28-1.15-1.29-2.35-3.25-2.35-1.9 0-3.61 1.44-3.61 3.7 0 2.26 1.65 3.69 3.63 3.69z" fill-rule="evenodd"/></symbol><symbol id="plyr-enter-fullscreen" viewBox="0 0 18 18"><path d="M10 3h3.6l-4 4L11 8.4l4-4V8h2V1h-7zM7 9.6l-4 4V10H1v7h7v-2H4.4l4-4z"/></symbol><symbol id="plyr-exit-fullscreen" viewBox="0 0 18 18"><path d="M1 12h3.6l-4 4L2 17.4l4-4V17h2v-7H1zM16 .6l-4 4V1h-2v7h7V6h-3.6l4-4z"/></symbol><symbol id="plyr-fast-forward" viewBox="0 0 18 18"><path d="M7.875 7.171L0 1v16l7.875-6.171V17L18 9 7.875 1z"/></symbol><symbol id="plyr-muted" viewBox="0 0 18 18"><path d="M12.4 12.5l2.1-2.1 2.1 2.1 1.4-1.4L15.9 9 18 6.9l-1.4-1.4-2.1 2.1-2.1-2.1L11 6.9 13.1 9 11 11.1zM3.786 6.008H.714C.286 6.008 0 6.31 0 6.76v4.512c0 .452.286.752.714.752h3.072l4.071 3.858c.5.3 1.143 0 1.143-.602V2.752c0-.601-.643-.977-1.143-.601L3.786 6.008z"/></symbol><symbol id="plyr-pause" viewBox="0 0 18 18"><path d="M6 1H3c-.6 0-1 .4-1 1v14c0 .6.4 1 1 1h3c.6 0 1-.4 1-1V2c0-.6-.4-1-1-1zM12 1c-.6 0-1 .4-1 1v14c0 .6.4 1 1 1h3c.6 0 1-.4 1-1V2c0-.6-.4-1-1-1h-3z"/></symbol><symbol id="plyr-pip" viewBox="0 0 18 18"><path d="M13.293 3.293L7.022 9.564l1.414 1.414 6.271-6.271L17 7V1h-6z"/><path d="M13 15H3V5h5V3H2a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-6h-2v5z"/></symbol><symbol id="plyr-play" viewBox="0 0 18 18"><path d="M15.562 8.1L3.87.225C3.052-.337 2 .225 2 1.125v15.75c0 .9 1.052 1.462 1.87.9L15.563 9.9c.584-.45.584-1.35 0-1.8z"/></symbol><symbol id="plyr-restart" viewBox="0 0 18 18"><path d="M9.7 1.2l.7 6.4 2.1-2.1c1.9 1.9 1.9 5.1 0 7-.9 1-2.2 1.5-3.5 1.5-1.3 0-2.6-.5-3.5-1.5-1.9-1.9-1.9-5.1 0-7 .6-.6 1.4-1.1 2.3-1.3l-.6-1.9C6 2.6 4.9 3.2 4 4.1 1.3 6.8 1.3 11.2 4 14c1.3 1.3 3.1 2 4.9 2 1.9 0 3.6-.7 4.9-2 2.7-2.7 2.7-7.1 0-9.9L16 1.9l-6.3-.7z"/></symbol><symbol id="plyr-rewind" viewBox="0 0 18 18"><path d="M10.125 1L0 9l10.125 8v-6.171L18 17V1l-7.875 6.171z"/></symbol><symbol id="plyr-settings" viewBox="0 0 18 18"><path d="M16.135 7.784a2 2 0 0 1-1.23-2.969c.322-.536.225-.998-.094-1.316l-.31-.31c-.318-.318-.78-.415-1.316-.094a2 2 0 0 1-2.969-1.23C10.065 1.258 9.669 1 9.219 1h-.438c-.45 0-.845.258-.997.865a2 2 0 0 1-2.969 1.23c-.536-.322-.999-.225-1.317.093l-.31.31c-.318.318-.415.781-.093 1.317a2 2 0 0 1-1.23 2.969C1.26 7.935 1 8.33 1 8.781v.438c0 .45.258.845.865.997a2 2 0 0 1 1.23 2.969c-.322.536-.225.998.094 1.316l.31.31c.319.319.782.415 1.316.094a2 2 0 0 1 2.969 1.23c.151.607.547.865.997.865h.438c.45 0 .845-.258.997-.865a2 2 0 0 1 2.969-1.23c.535.321.997.225 1.316-.094l.31-.31c.318-.318.415-.781.094-1.316a2 2 0 0 1 1.23-2.969c.607-.151.865-.547.865-.997v-.438c0-.451-.26-.846-.865-.997zM9 12a3 3 0 1 1 0-6 3 3 0 0 1 0 6z"/></symbol><symbol id="plyr-volume" viewBox="0 0 18 18"><path d="M15.6 3.3c-.4-.4-1-.4-1.4 0-.4.4-.4 1 0 1.4C15.4 5.9 16 7.4 16 9c0 1.6-.6 3.1-1.8 4.3-.4.4-.4 1 0 1.4.2.2.5.3.7.3.3 0 .5-.1.7-.3C17.1 13.2 18 11.2 18 9s-.9-4.2-2.4-5.7z"/><path d="M11.282 5.282a.909.909 0 0 0 0 1.316c.735.735.995 1.458.995 2.402 0 .936-.425 1.917-.995 2.487a.909.909 0 0 0 0 1.316c.145.145.636.262 1.018.156a.725.725 0 0 0 .298-.156C13.773 11.733 14.13 10.16 14.13 9c0-.17-.002-.34-.011-.51-.053-.992-.319-2.005-1.522-3.208a.909.909 0 0 0-1.316 0zM3.786 6.008H.714C.286 6.008 0 6.31 0 6.76v4.512c0 .452.286.752.714.752h3.072l4.071 3.858c.5.3 1.143 0 1.143-.602V2.752c0-.601-.643-.977-1.143-.601L3.786 6.008z"/></symbol></svg>
|
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 4.9 KiB |
479
gulpfile.js
@ -1,353 +1,420 @@
|
|||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
// Gulp build script
|
// Gulp build script
|
||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
/*global require, __dirname,Buffer*/
|
/* global require, __dirname */
|
||||||
/*jshint -W079 */
|
/* eslint no-console: "off" */
|
||||||
|
|
||||||
var fs = require('fs'),
|
const del = require('del');
|
||||||
path = require('path'),
|
const path = require('path');
|
||||||
gulp = require('gulp'),
|
const gulp = require('gulp');
|
||||||
gutil = require('gulp-util'),
|
const gutil = require('gulp-util');
|
||||||
concat = require('gulp-concat'),
|
const concat = require('gulp-concat');
|
||||||
uglify = require('gulp-uglify'),
|
const filter = require('gulp-filter');
|
||||||
less = require('gulp-less'),
|
const sass = require('gulp-sass');
|
||||||
sass = require('gulp-sass'),
|
const cleancss = require('gulp-clean-css');
|
||||||
cleanCSS = require('gulp-clean-css'),
|
const run = require('run-sequence');
|
||||||
run = require('run-sequence'),
|
const header = require('gulp-header');
|
||||||
prefix = require('gulp-autoprefixer'),
|
const prefix = require('gulp-autoprefixer');
|
||||||
svgstore = require('gulp-svgstore'),
|
const gitbranch = require('git-branch');
|
||||||
svgmin = require('gulp-svgmin'),
|
const svgstore = require('gulp-svgstore');
|
||||||
rename = require('gulp-rename'),
|
const svgmin = require('gulp-svgmin');
|
||||||
s3 = require('gulp-s3'),
|
const rename = require('gulp-rename');
|
||||||
replace = require('gulp-replace'),
|
const s3 = require('gulp-s3');
|
||||||
open = require('gulp-open'),
|
const replace = require('gulp-replace');
|
||||||
size = require('gulp-size'),
|
const open = require('gulp-open');
|
||||||
through = require('through2');
|
const size = require('gulp-size');
|
||||||
|
const rollup = require('gulp-better-rollup');
|
||||||
|
const babel = require('rollup-plugin-babel');
|
||||||
|
const sourcemaps = require('gulp-sourcemaps');
|
||||||
|
const uglify = require('gulp-uglify-es').default;
|
||||||
|
const commonjs = require('rollup-plugin-commonjs');
|
||||||
|
const resolve = require('rollup-plugin-node-resolve');
|
||||||
|
|
||||||
var root = __dirname,
|
const bundles = require('./bundles.json');
|
||||||
paths = {
|
const pkg = require('./package.json');
|
||||||
|
|
||||||
|
// Get AWS config
|
||||||
|
let aws = {};
|
||||||
|
try {
|
||||||
|
aws = require('./aws.json'); //eslint-disable-line
|
||||||
|
} catch (e) {
|
||||||
|
// Do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
const minSuffix = '.min';
|
||||||
|
|
||||||
|
// Paths
|
||||||
|
const root = __dirname;
|
||||||
|
const paths = {
|
||||||
plyr: {
|
plyr: {
|
||||||
// Source paths
|
// Source paths
|
||||||
src: {
|
src: {
|
||||||
less: path.join(root, 'src/less/**/*'),
|
sass: path.join(root, 'src/sass/**/*.scss'),
|
||||||
scss: path.join(root, 'src/scss/**/*'),
|
|
||||||
js: path.join(root, 'src/js/**/*'),
|
js: path.join(root, 'src/js/**/*'),
|
||||||
sprite: path.join(root, 'src/sprite/*.svg'),
|
sprite: path.join(root, 'src/sprite/*.svg'),
|
||||||
},
|
},
|
||||||
|
|
||||||
// Output paths
|
// Output paths
|
||||||
output: path.join(root, 'dist/'),
|
output: path.join(root, 'dist/'),
|
||||||
},
|
},
|
||||||
demo: {
|
demo: {
|
||||||
// Source paths
|
// Source paths
|
||||||
src: {
|
src: {
|
||||||
less: path.join(root, 'demo/src/less/**/*'),
|
sass: path.join(root, 'demo/src/sass/**/*.scss'),
|
||||||
js: path.join(root, 'demo/src/js/**/*'),
|
js: path.join(root, 'demo/src/js/**/*'),
|
||||||
sprite: path.join(root, 'demo/src/sprite/**/*'),
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// Output paths
|
// Output paths
|
||||||
output: path.join(root, 'demo/dist/'),
|
output: path.join(root, 'demo/dist/'),
|
||||||
|
|
||||||
// Demo
|
// Demo
|
||||||
root: path.join(root, 'demo/'),
|
root: path.join(root, 'demo/'),
|
||||||
},
|
},
|
||||||
upload: [path.join(root, 'dist/**'), path.join(root, 'demo/dist/**')],
|
upload: [
|
||||||
},
|
path.join(root, `dist/*${minSuffix}.*`),
|
||||||
// Task arrays
|
path.join(root, 'dist/*.css'),
|
||||||
tasks = {
|
path.join(root, 'dist/*.svg'),
|
||||||
less: [],
|
path.join(root, `demo/dist/*${minSuffix}.*`),
|
||||||
scss: [],
|
path.join(root, 'demo/dist/*.css'),
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
// Task arrays
|
||||||
|
const tasks = {
|
||||||
|
sass: [],
|
||||||
js: [],
|
js: [],
|
||||||
sprite: [],
|
sprite: [],
|
||||||
|
clean: ['clean'],
|
||||||
|
};
|
||||||
|
|
||||||
|
// Size plugin
|
||||||
|
const sizeOptions = { showFiles: true, gzip: true };
|
||||||
|
|
||||||
|
// Browserlist
|
||||||
|
const browsers = ['> 1%'];
|
||||||
|
|
||||||
|
// Babel config
|
||||||
|
const babelrc = {
|
||||||
|
presets: [[
|
||||||
|
'env',
|
||||||
|
{
|
||||||
|
targets: {
|
||||||
|
browsers,
|
||||||
},
|
},
|
||||||
// Fetch bundles from JSON
|
useBuiltIns: true,
|
||||||
bundles = loadJSON(path.join(root, 'bundles.json')),
|
modules: false,
|
||||||
package = loadJSON(path.join(root, 'package.json'));
|
|
||||||
|
|
||||||
// Load json
|
|
||||||
function loadJSON(path) {
|
|
||||||
try {
|
|
||||||
return JSON.parse(fs.readFileSync(path));
|
|
||||||
} catch (err) {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create a file from a string
|
|
||||||
// http://stackoverflow.com/questions/23230569/how-do-you-create-a-file-from-a-string-in-gulp
|
|
||||||
function createFile(filename, string) {
|
|
||||||
var src = require('stream').Readable({
|
|
||||||
objectMode: true,
|
|
||||||
});
|
|
||||||
src._read = function() {
|
|
||||||
this.push(
|
|
||||||
new gutil.File({
|
|
||||||
cwd: '',
|
|
||||||
base: '',
|
|
||||||
path: filename,
|
|
||||||
contents: new Buffer(string),
|
|
||||||
// stats also required for some functions
|
|
||||||
// https://nodejs.org/api/fs.html#fs_class_fs_stats
|
|
||||||
stat: {
|
|
||||||
size: string.length,
|
|
||||||
},
|
},
|
||||||
}),
|
]],
|
||||||
);
|
plugins: ['external-helpers'],
|
||||||
this.push(null);
|
babelrc: false,
|
||||||
};
|
exclude: 'node_modules/**',
|
||||||
return src;
|
};
|
||||||
}
|
|
||||||
|
|
||||||
var build = {
|
// Clean out /dist
|
||||||
js: function(files, bundle) {
|
gulp.task('clean', () => {
|
||||||
for (var key in files) {
|
const dirs = [
|
||||||
(function(key) {
|
paths.plyr.output,
|
||||||
var name = 'js-' + key;
|
paths.demo.output,
|
||||||
|
].map(dir => path.join(dir, '**/*'));
|
||||||
|
|
||||||
|
// Don't delete the mp4
|
||||||
|
dirs.push(`!${path.join(paths.plyr.output, '**/*.mp4')}`);
|
||||||
|
|
||||||
|
del(dirs);
|
||||||
|
});
|
||||||
|
|
||||||
|
const build = {
|
||||||
|
js(files, bundle, options) {
|
||||||
|
Object.keys(files).forEach(key => {
|
||||||
|
const name = `js:${key}`;
|
||||||
tasks.js.push(name);
|
tasks.js.push(name);
|
||||||
|
const { output } = paths[bundle];
|
||||||
|
|
||||||
gulp.task(name, function() {
|
return gulp.task(name, () =>
|
||||||
return gulp
|
gulp
|
||||||
.src(bundles[bundle].js[key])
|
.src(bundles[bundle].js[key])
|
||||||
|
.pipe(sourcemaps.init())
|
||||||
.pipe(concat(key))
|
.pipe(concat(key))
|
||||||
.pipe(uglify().on('error', gutil.log))
|
.pipe(
|
||||||
.pipe(gulp.dest(paths[bundle].output));
|
rollup(
|
||||||
});
|
{
|
||||||
})(key);
|
plugins: [
|
||||||
}
|
resolve(),
|
||||||
|
commonjs(),
|
||||||
|
babel(babelrc),
|
||||||
|
],
|
||||||
},
|
},
|
||||||
less: function(files, bundle) {
|
options,
|
||||||
for (var key in files) {
|
),
|
||||||
(function(key) {
|
)
|
||||||
var name = 'less-' + key;
|
.pipe(header('typeof navigator === "object" && ')) // "Support" SSR (#935)
|
||||||
tasks.less.push(name);
|
.pipe(sourcemaps.write(''))
|
||||||
|
.pipe(gulp.dest(output))
|
||||||
gulp.task(name, function() {
|
.pipe(filter('**/*.js'))
|
||||||
return gulp
|
.pipe(uglify())
|
||||||
.src(bundles[bundle].less[key])
|
.pipe(size(sizeOptions))
|
||||||
.pipe(less())
|
.pipe(rename({ suffix: minSuffix }))
|
||||||
.on('error', gutil.log)
|
.pipe(sourcemaps.write(''))
|
||||||
.pipe(concat(key))
|
.pipe(gulp.dest(output)),
|
||||||
.pipe(prefix(['last 2 versions'], { cascade: true }))
|
);
|
||||||
.pipe(cleanCSS())
|
|
||||||
.pipe(gulp.dest(paths[bundle].output));
|
|
||||||
});
|
});
|
||||||
})(key);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
scss: function(files, bundle) {
|
sass(files, bundle) {
|
||||||
for (var key in files) {
|
Object.keys(files).forEach(key => {
|
||||||
(function(key) {
|
const name = `sass:${key}`;
|
||||||
var name = 'scss-' + key;
|
tasks.sass.push(name);
|
||||||
tasks.scss.push(name);
|
|
||||||
|
|
||||||
gulp.task(name, function() {
|
return gulp.task(name, () =>
|
||||||
return gulp
|
gulp
|
||||||
.src(bundles[bundle].scss[key])
|
.src(bundles[bundle].sass[key])
|
||||||
.pipe(sass())
|
.pipe(sass())
|
||||||
.on('error', gutil.log)
|
.on('error', gutil.log)
|
||||||
.pipe(concat(key))
|
.pipe(concat(key))
|
||||||
.pipe(prefix(['last 2 versions'], { cascade: true }))
|
.pipe(prefix(browsers, { cascade: false }))
|
||||||
.pipe(cleanCSS())
|
.pipe(cleancss())
|
||||||
.pipe(gulp.dest(paths[bundle].output));
|
.pipe(size(sizeOptions))
|
||||||
|
.pipe(gulp.dest(paths[bundle].output)),
|
||||||
|
);
|
||||||
});
|
});
|
||||||
})(key);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
sprite: function(bundle) {
|
sprite(bundle) {
|
||||||
var name = 'sprite-' + bundle;
|
const name = `svg:sprite:${bundle}`;
|
||||||
tasks.sprite.push(name);
|
tasks.sprite.push(name);
|
||||||
|
|
||||||
// Process Icons
|
// Process Icons
|
||||||
gulp.task(name, function() {
|
return gulp.task(name, () =>
|
||||||
return gulp
|
gulp
|
||||||
.src(paths[bundle].src.sprite)
|
.src(paths[bundle].src.sprite)
|
||||||
.pipe(
|
.pipe(
|
||||||
svgmin({
|
svgmin({
|
||||||
plugins: [
|
plugins: [{
|
||||||
{
|
|
||||||
removeDesc: true,
|
removeDesc: true,
|
||||||
},
|
}],
|
||||||
],
|
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.pipe(svgstore())
|
.pipe(svgstore())
|
||||||
.pipe(rename({ basename: bundle }))
|
.pipe(rename({ basename: bundle }))
|
||||||
.pipe(gulp.dest(paths[bundle].output));
|
.pipe(size(sizeOptions))
|
||||||
});
|
.pipe(gulp.dest(paths[bundle].output)),
|
||||||
|
);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
// Plyr core files
|
// Plyr core files
|
||||||
build.js(bundles.plyr.js, 'plyr');
|
build.js(bundles.plyr.js, 'plyr', { name: 'Plyr', format: 'umd' });
|
||||||
build.less(bundles.plyr.less, 'plyr');
|
build.sass(bundles.plyr.sass, 'plyr');
|
||||||
build.scss(bundles.plyr.scss, 'plyr');
|
|
||||||
build.sprite('plyr');
|
build.sprite('plyr');
|
||||||
|
|
||||||
// Demo files
|
// Demo files
|
||||||
build.less(bundles.demo.less, 'demo');
|
build.sass(bundles.demo.sass, 'demo');
|
||||||
build.js(bundles.demo.js, 'demo');
|
build.js(bundles.demo.js, 'demo', { format: 'iife' });
|
||||||
build.sprite('demo');
|
|
||||||
|
|
||||||
// Build all JS
|
// Build all JS
|
||||||
gulp.task('js', function() {
|
gulp.task('js', () => {
|
||||||
run(tasks.js);
|
run(tasks.js);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Build SCSS (for testing, default is LESS)
|
|
||||||
gulp.task('scss', function() {
|
|
||||||
run(tasks.scss);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Watch for file changes
|
// Watch for file changes
|
||||||
gulp.task('watch', function() {
|
gulp.task('watch', () => {
|
||||||
// Plyr core
|
// Plyr core
|
||||||
gulp.watch(paths.plyr.src.js, tasks.js);
|
gulp.watch(paths.plyr.src.js, tasks.js);
|
||||||
gulp.watch(paths.plyr.src.less, tasks.less);
|
gulp.watch(paths.plyr.src.sass, tasks.sass);
|
||||||
gulp.watch(paths.plyr.src.sprite, tasks.sprite);
|
gulp.watch(paths.plyr.src.sprite, tasks.sprite);
|
||||||
|
|
||||||
// Demo
|
// Demo
|
||||||
gulp.watch(paths.demo.src.js, tasks.js);
|
gulp.watch(paths.demo.src.js, tasks.js);
|
||||||
gulp.watch(paths.demo.src.less, tasks.less);
|
gulp.watch(paths.demo.src.sass, tasks.sass);
|
||||||
gulp.watch(paths.demo.src.sprite, tasks.sprite);
|
});
|
||||||
|
|
||||||
|
// Build distribution
|
||||||
|
gulp.task('build', () => {
|
||||||
|
run(tasks.clean, tasks.js, tasks.sass, tasks.sprite);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Default gulp task
|
// Default gulp task
|
||||||
gulp.task('default', function() {
|
gulp.task('default', () => {
|
||||||
run(tasks.js, tasks.less, tasks.sprite, 'watch');
|
run('build', 'watch');
|
||||||
});
|
});
|
||||||
|
|
||||||
// Publish a version to CDN and demo
|
// Publish a version to CDN and demo
|
||||||
// --------------------------------------------
|
// --------------------------------------------
|
||||||
|
// If aws is setup
|
||||||
|
if (Object.keys(aws).includes('cdn') && Object.keys(aws).includes('demo')) {
|
||||||
|
const { version } = pkg;
|
||||||
|
|
||||||
// Some options
|
// Get branch info
|
||||||
var aws = loadJSON(path.join(root, 'aws.json')),
|
const branch = {
|
||||||
version = package.version,
|
current: gitbranch.sync(),
|
||||||
maxAge = 31536000, // seconds 1 year
|
master: 'master',
|
||||||
options = {
|
develop: 'develop',
|
||||||
|
};
|
||||||
|
const allowed = [
|
||||||
|
branch.master,
|
||||||
|
branch.develop,
|
||||||
|
];
|
||||||
|
|
||||||
|
const maxAge = 31536000; // 1 year
|
||||||
|
const options = {
|
||||||
cdn: {
|
cdn: {
|
||||||
headers: {
|
headers: {
|
||||||
'Cache-Control': 'max-age=' + maxAge,
|
'Cache-Control': `max-age=${maxAge}`,
|
||||||
Vary: 'Accept-Encoding',
|
Vary: 'Accept-Encoding',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
demo: {
|
demo: {
|
||||||
|
uploadPath: branch.current === branch.develop ? 'beta/' : null,
|
||||||
headers: {
|
headers: {
|
||||||
'Cache-Control': 'no-cache, no-store, must-revalidate, max-age=0',
|
'Cache-Control': 'no-cache, no-store, must-revalidate, max-age=0',
|
||||||
Vary: 'Accept-Encoding',
|
Vary: 'Accept-Encoding',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
symlinks: function(version, filename) {
|
symlinks(ver, filename) {
|
||||||
return {
|
return {
|
||||||
headers: {
|
headers: {
|
||||||
// http://stackoverflow.com/questions/2272835/amazon-s3-object-redirect
|
// http://stackoverflow.com/questions/2272835/amazon-s3-object-redirect
|
||||||
'x-amz-website-redirect-location': '/' + version + '/' + filename,
|
'x-amz-website-redirect-location': `/${ver}/${filename}`,
|
||||||
'Cache-Control': 'no-cache, no-store, must-revalidate, max-age=0',
|
'Cache-Control': 'no-cache, no-store, must-revalidate, max-age=0',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
// If aws is setup
|
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\\-]+)*)?';
|
||||||
if ('cdn' in aws) {
|
const semver = new RegExp(`v${regex}`, 'gi');
|
||||||
var regex = '(?:0|[1-9][0-9]*)\\.(?:0|[1-9][0-9]*).(?:0|[1-9][0-9]*)(?:-[\\da-z\\-]+(?:.[\\da-z\\-]+)*)?(?:\\+[\\da-z\\-]+(?:.[\\da-z\\-]+)*)?',
|
const localPath = new RegExp('(../)?dist', 'gi');
|
||||||
cdnpath = new RegExp(aws.cdn.domain + '/' + regex, 'gi'),
|
const versionPath = `https://${aws.cdn.domain}/${version}`;
|
||||||
semver = new RegExp('v' + regex, 'gi'),
|
const cdnpath = new RegExp(`${aws.cdn.domain}/${regex}/`, 'gi');
|
||||||
localPath = new RegExp('(../)?dist', 'gi'),
|
|
||||||
versionPath = 'https://' + aws.cdn.domain + '/' + version;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Publish version to CDN bucket
|
gulp.task('version', () => {
|
||||||
gulp.task('cdn', function() {
|
console.log(`Updating versions to '${version}'...`);
|
||||||
console.log('Uploading ' + version + ' to ' + aws.cdn.domain + '...');
|
|
||||||
|
// Replace versioned URLs in source
|
||||||
|
const files = [
|
||||||
|
'plyr.js',
|
||||||
|
'plyr.polyfilled.js',
|
||||||
|
'defaults.js',
|
||||||
|
];
|
||||||
|
|
||||||
|
return gulp
|
||||||
|
.src(files.map(file => path.join(root, `src/js/${file}`)))
|
||||||
|
.pipe(replace(semver, `v${version}`))
|
||||||
|
.pipe(replace(cdnpath, `${aws.cdn.domain}/${version}/`))
|
||||||
|
.pipe(gulp.dest(path.join(root, 'src/js/')));
|
||||||
|
});
|
||||||
|
|
||||||
|
// Publish version to CDN bucket
|
||||||
|
gulp.task('cdn', () => {
|
||||||
|
if (!allowed.includes(branch.current)) {
|
||||||
|
console.error(`Must be on ${allowed.join(', ')} to publish! (current: ${branch.current})`);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`Uploading '${version}' to ${aws.cdn.domain}...`);
|
||||||
|
|
||||||
// Upload to CDN
|
// Upload to CDN
|
||||||
return gulp
|
return (
|
||||||
|
gulp
|
||||||
.src(paths.upload)
|
.src(paths.upload)
|
||||||
|
.pipe(
|
||||||
|
rename(p => {
|
||||||
|
p.basename = p.basename.replace(minSuffix, ''); // eslint-disable-line
|
||||||
|
p.dirname = p.dirname.replace('.', version); // eslint-disable-line
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
// Remove min suffix from source map URL
|
||||||
|
.pipe(replace(/sourceMappingURL=([\w-?.]+)/, (match, p1) => `sourceMappingURL=${p1.replace(minSuffix, '')}`))
|
||||||
.pipe(
|
.pipe(
|
||||||
size({
|
size({
|
||||||
showFiles: true,
|
showFiles: true,
|
||||||
gzip: true,
|
gzip: true,
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.pipe(
|
|
||||||
rename(function(path) {
|
|
||||||
path.dirname = path.dirname.replace('.', version);
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
.pipe(replace(localPath, versionPath))
|
.pipe(replace(localPath, versionPath))
|
||||||
.pipe(s3(aws.cdn, options.cdn));
|
.pipe(s3(aws.cdn, options.cdn))
|
||||||
});
|
);
|
||||||
|
});
|
||||||
|
|
||||||
// Publish to demo bucket
|
// Publish to demo bucket
|
||||||
gulp.task('demo', function() {
|
gulp.task('demo', () => {
|
||||||
console.log('Uploading ' + version + ' demo to ' + aws.demo.domain + '...');
|
if (!allowed.includes(branch.current)) {
|
||||||
|
console.error(`Must be on ${allowed.join(', ')} to publish! (current: ${branch.current})`);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`Uploading '${version}' demo to ${aws.demo.domain}...`);
|
||||||
|
|
||||||
// Replace versioned files in readme.md
|
// Replace versioned files in readme.md
|
||||||
gulp
|
gulp
|
||||||
.src([root + '/readme.md'])
|
.src([`${root}/readme.md`])
|
||||||
.pipe(replace(cdnpath, aws.cdn.domain + '/' + version))
|
.pipe(replace(cdnpath, `${aws.cdn.domain}/${version}/`))
|
||||||
.pipe(gulp.dest(root));
|
.pipe(gulp.dest(root));
|
||||||
|
|
||||||
// Replace versioned files in plyr.js
|
|
||||||
gulp
|
|
||||||
.src(path.join(root, 'src/js/plyr.js'))
|
|
||||||
.pipe(replace(semver, 'v' + version))
|
|
||||||
.pipe(replace(cdnpath, aws.cdn.domain + '/' + version))
|
|
||||||
.pipe(gulp.dest(path.join(root, 'src/js/')));
|
|
||||||
|
|
||||||
// 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 error = `${paths.demo.root}error.html`;
|
||||||
|
const pages = [index];
|
||||||
|
|
||||||
|
if (branch.current === branch.master) {
|
||||||
|
pages.push(error);
|
||||||
|
}
|
||||||
|
|
||||||
gulp
|
gulp
|
||||||
.src([paths.demo.root + '*.html'])
|
.src(pages)
|
||||||
.pipe(replace(localPath, versionPath))
|
.pipe(replace(localPath, versionPath))
|
||||||
.pipe(s3(aws.demo, options.demo));
|
.pipe(s3(aws.demo, options.demo));
|
||||||
|
|
||||||
|
// Only update CDN for master (prod)
|
||||||
|
if (branch.current !== branch.master) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
// Upload error.html to cdn (as well as demo site)
|
// Upload error.html to cdn (as well as demo site)
|
||||||
return gulp
|
return gulp
|
||||||
.src([paths.demo.root + 'error.html'])
|
.src([error])
|
||||||
.pipe(replace(localPath, versionPath))
|
.pipe(replace(localPath, versionPath))
|
||||||
.pipe(s3(aws.cdn, options.demo));
|
.pipe(s3(aws.cdn, options.demo));
|
||||||
});
|
});
|
||||||
|
|
||||||
// Open the demo site to check it's sweet
|
// Update symlinks for latest
|
||||||
gulp.task('symlinks', function() {
|
/* gulp.task("symlinks", function () {
|
||||||
console.log('Updating symlinks...');
|
console.log("Updating symlinks...");
|
||||||
|
|
||||||
return gulp.src(paths.upload).pipe(
|
return gulp.src(paths.upload)
|
||||||
through.obj(function(chunk, enc, callback) {
|
.pipe(through.obj(function (chunk, enc, callback) {
|
||||||
if (chunk.stat.isFile()) {
|
if (chunk.stat.isFile()) {
|
||||||
// Get the filename
|
// Get the filename
|
||||||
var filename = chunk.path.split('/').reverse()[0];
|
var filename = chunk.path.split("/").reverse()[0];
|
||||||
|
|
||||||
// Create the 0 byte redirect files to upload
|
// Create the 0 byte redirect files to upload
|
||||||
createFile(filename, '')
|
createFile(filename, "")
|
||||||
.pipe(
|
.pipe(rename(function (path) {
|
||||||
rename(function(path) {
|
path.dirname = path.dirname.replace(".", "latest");
|
||||||
path.dirname = path.dirname.replace('.', 'latest');
|
}))
|
||||||
}),
|
|
||||||
)
|
|
||||||
// Upload to S3 with correct headers
|
// Upload to S3 with correct headers
|
||||||
.pipe(s3(aws.cdn, options.symlinks(version, filename)));
|
.pipe(s3(aws.cdn, options.symlinks(version, filename)));
|
||||||
}
|
}
|
||||||
|
|
||||||
callback(null, chunk);
|
callback(null, chunk);
|
||||||
}),
|
}));
|
||||||
);
|
}); */
|
||||||
});
|
|
||||||
|
|
||||||
// Open the demo site to check it's sweet
|
// Open the demo site to check it's sweet
|
||||||
gulp.task('open', function() {
|
gulp.task('open', () => {
|
||||||
console.log('Opening ' + aws.demo.domain + '...');
|
console.log(`Opening ${aws.demo.domain}...`);
|
||||||
|
|
||||||
// A file must be specified or gulp will skip the task
|
// A file must be specified or gulp will skip the task
|
||||||
// Doesn't matter which file since we set the URL above
|
// Doesn't matter which file since we set the URL above
|
||||||
// Weird, I know...
|
// Weird, I know...
|
||||||
return gulp.src([paths.demo.root + 'index.html']).pipe(
|
return gulp.src([`${paths.demo.root}index.html`]).pipe(
|
||||||
open('', {
|
open('', {
|
||||||
url: 'http://' + aws.demo.domain,
|
url: `http://${aws.demo.domain}`,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Do everything
|
// Do everything
|
||||||
gulp.task('publish', function() {
|
gulp.task('publish', callback => {
|
||||||
run(tasks.js, tasks.less, tasks.sprite, 'cdn', 'demo', 'symlinks');
|
run('version', tasks.clean, tasks.js, tasks.sass, tasks.sprite, 'cdn', 'demo', callback);
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
4604
package-lock.json
generated
81
package.json
@ -1,38 +1,58 @@
|
|||||||
{
|
{
|
||||||
"name": "plyr",
|
"name": "plyr",
|
||||||
"version": "2.0.17",
|
"version": "3.3.14",
|
||||||
"description": "A simple, accessible and customizable HTML5, YouTube and Vimeo media player",
|
"description": "A simple, accessible and customizable HTML5, YouTube and Vimeo media player",
|
||||||
"homepage": "http://plyr.io",
|
"homepage": "https://plyr.io",
|
||||||
"main": "src/js/plyr.js",
|
"main": "./dist/plyr.js",
|
||||||
"dependencies": {},
|
"browser": "./dist/plyr.min.js",
|
||||||
|
"sass": "./src/sass/plyr.scss",
|
||||||
|
"style": "./dist/plyr.css",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"babel-core": "^6.26.3",
|
||||||
|
"babel-eslint": "^8.2.3",
|
||||||
|
"babel-plugin-external-helpers": "^6.22.0",
|
||||||
|
"babel-preset-env": "^1.7.0",
|
||||||
|
"del": "^3.0.0",
|
||||||
|
"eslint": "^4.19.1",
|
||||||
|
"eslint-config-airbnb-base": "^12.1.0",
|
||||||
|
"eslint-config-prettier": "^2.9.0",
|
||||||
|
"eslint-plugin-import": "^2.12.0",
|
||||||
|
"git-branch": "^2.0.1",
|
||||||
"gulp": "^3.9.1",
|
"gulp": "^3.9.1",
|
||||||
"gulp-autoprefixer": "^4.0.0",
|
"gulp-autoprefixer": "^5.0.0",
|
||||||
"gulp-clean-css": "^3.9.0",
|
"gulp-better-rollup": "^3.2.1",
|
||||||
|
"gulp-clean-css": "^3.9.4",
|
||||||
"gulp-concat": "^2.6.1",
|
"gulp-concat": "^2.6.1",
|
||||||
"gulp-less": "^3.3.2",
|
"gulp-filter": "^5.1.0",
|
||||||
"gulp-open": "^2.0.0",
|
"gulp-header": "^2.0.5",
|
||||||
"gulp-rename": "^1.2.2",
|
"gulp-open": "^3.0.1",
|
||||||
"gulp-replace": "^0.6.1",
|
"gulp-postcss": "^7.0.1",
|
||||||
|
"gulp-rename": "^1.3.0",
|
||||||
|
"gulp-replace": "^1.0.0",
|
||||||
"gulp-s3": "^0.11.0",
|
"gulp-s3": "^0.11.0",
|
||||||
"gulp-sass": "^3.1.0",
|
"gulp-sass": "^4.0.1",
|
||||||
"gulp-size": "^2.1.0",
|
"gulp-size": "^3.0.0",
|
||||||
|
"gulp-sourcemaps": "^2.6.4",
|
||||||
"gulp-svgmin": "^1.2.4",
|
"gulp-svgmin": "^1.2.4",
|
||||||
"gulp-svgstore": "^6.1.0",
|
"gulp-svgstore": "^6.1.1",
|
||||||
"gulp-uglify": "^3.0.0",
|
"gulp-uglify-es": "^1.0.4",
|
||||||
"gulp-util": "^3.0.8",
|
"gulp-util": "^3.0.8",
|
||||||
"run-sequence": "^2.2.0",
|
"postcss-custom-properties": "^7.0.0",
|
||||||
"through2": "^2.0.3"
|
"prettier-eslint": "^8.8.1",
|
||||||
|
"prettier-stylelint": "^0.4.2",
|
||||||
|
"rollup-plugin-babel": "^3.0.4",
|
||||||
|
"rollup-plugin-commonjs": "^9.1.3",
|
||||||
|
"rollup-plugin-node-resolve": "^3.3.0",
|
||||||
|
"run-sequence": "^2.2.1",
|
||||||
|
"stylelint": "^9.3.0",
|
||||||
|
"stylelint-config-prettier": "^3.2.0",
|
||||||
|
"stylelint-config-recommended": "^2.1.0",
|
||||||
|
"stylelint-config-sass-guidelines": "^5.0.0",
|
||||||
|
"stylelint-order": "^0.8.1",
|
||||||
|
"stylelint-scss": "^3.1.2",
|
||||||
|
"stylelint-selector-bem-pattern": "^2.0.0"
|
||||||
},
|
},
|
||||||
"keywords": [
|
"keywords": ["HTML5 Video", "HTML5 Audio", "Media Player", "DASH", "Shaka", "WordPress", "HLS"],
|
||||||
"HTML5 Video",
|
|
||||||
"HTML5 Audio",
|
|
||||||
"Media Player",
|
|
||||||
"DASH",
|
|
||||||
"Shaka",
|
|
||||||
"WordPress",
|
|
||||||
"HLS"
|
|
||||||
],
|
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "git://github.com/sampotts/plyr.git"
|
"url": "git://github.com/sampotts/plyr.git"
|
||||||
@ -45,7 +65,16 @@
|
|||||||
"doc": "readme.md"
|
"doc": "readme.md"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
"build": "gulp build",
|
||||||
|
"lint": "eslint src/js",
|
||||||
"test": "echo \"Error: no test specified\" && exit 1"
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
},
|
},
|
||||||
"author": "Sam Potts <sam@potts.es>"
|
"author": "Sam Potts <sam@potts.es>",
|
||||||
|
"dependencies": {
|
||||||
|
"babel-polyfill": "^6.26.0",
|
||||||
|
"custom-event-polyfill": "^0.3.0",
|
||||||
|
"loadjs": "^3.5.4",
|
||||||
|
"raven-js": "^3.26.2",
|
||||||
|
"url-polyfill": "^1.0.13"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
32
plyr.code-workspace
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
{
|
||||||
|
"folders": [
|
||||||
|
{
|
||||||
|
"path": "."
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"settings": {
|
||||||
|
// Exclude from the editor
|
||||||
|
"files.exclude": {
|
||||||
|
"**/node_modules": true
|
||||||
|
},
|
||||||
|
// Exclude from search
|
||||||
|
"search.exclude": {
|
||||||
|
"dist/": true,
|
||||||
|
"demo/dist/": true
|
||||||
|
},
|
||||||
|
// Linting
|
||||||
|
"stylelint.enable": true,
|
||||||
|
"css.validate": false,
|
||||||
|
"scss.validate": false,
|
||||||
|
"javascript.validate.enable": false,
|
||||||
|
// Prettier
|
||||||
|
"prettier.eslintIntegration": true,
|
||||||
|
"prettier.stylelintIntegration": true,
|
||||||
|
// Formatting
|
||||||
|
"editor.tabSize": 4,
|
||||||
|
"editor.insertSpaces": true,
|
||||||
|
"editor.formatOnSave": true,
|
||||||
|
// Trim on save
|
||||||
|
"files.trimTrailingWhitespace": true
|
||||||
|
}
|
||||||
|
}
|
384
src/js/captions.js
Normal file
@ -0,0 +1,384 @@
|
|||||||
|
// ==========================================================================
|
||||||
|
// Plyr Captions
|
||||||
|
// TODO: Create as class
|
||||||
|
// ==========================================================================
|
||||||
|
|
||||||
|
import controls from './controls';
|
||||||
|
import i18n from './i18n';
|
||||||
|
import support from './support';
|
||||||
|
import { dedupe } from './utils/arrays';
|
||||||
|
import browser from './utils/browser';
|
||||||
|
import {
|
||||||
|
createElement,
|
||||||
|
emptyElement,
|
||||||
|
getAttributesFromSelector,
|
||||||
|
insertAfter,
|
||||||
|
removeElement,
|
||||||
|
toggleClass,
|
||||||
|
} from './utils/elements';
|
||||||
|
import { on, triggerEvent } from './utils/events';
|
||||||
|
import fetch from './utils/fetch';
|
||||||
|
import is from './utils/is';
|
||||||
|
import { getHTML } from './utils/strings';
|
||||||
|
import { parseUrl } from './utils/urls';
|
||||||
|
|
||||||
|
const captions = {
|
||||||
|
// Setup captions
|
||||||
|
setup() {
|
||||||
|
// Requires UI support
|
||||||
|
if (!this.supported.ui) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only Vimeo and HTML5 video supported at this point
|
||||||
|
if (!this.isVideo || this.isYouTube || (this.isHTML5 && !support.textTracks)) {
|
||||||
|
// Clear menu and hide
|
||||||
|
if (
|
||||||
|
is.array(this.config.controls) &&
|
||||||
|
this.config.controls.includes('settings') &&
|
||||||
|
this.config.settings.includes('captions')
|
||||||
|
) {
|
||||||
|
controls.setCaptionsMenu.call(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Inject the container
|
||||||
|
if (!is.element(this.elements.captions)) {
|
||||||
|
this.elements.captions = createElement('div', getAttributesFromSelector(this.config.selectors.captions));
|
||||||
|
|
||||||
|
insertAfter(this.elements.captions, this.elements.wrapper);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fix IE captions if CORS is used
|
||||||
|
// Fetch captions and inject as blobs instead (data URIs not supported!)
|
||||||
|
if (browser.isIE && window.URL) {
|
||||||
|
const elements = this.media.querySelectorAll('track');
|
||||||
|
|
||||||
|
Array.from(elements).forEach(track => {
|
||||||
|
const src = track.getAttribute('src');
|
||||||
|
const url = parseUrl(src);
|
||||||
|
|
||||||
|
if (
|
||||||
|
url !== null &&
|
||||||
|
url.hostname !== window.location.href.hostname &&
|
||||||
|
['http:', 'https:'].includes(url.protocol)
|
||||||
|
) {
|
||||||
|
fetch(src, 'blob')
|
||||||
|
.then(blob => {
|
||||||
|
track.setAttribute('src', window.URL.createObjectURL(blob));
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
removeElement(track);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get and set initial data
|
||||||
|
// The "preferred" options are not realized unless / until the wanted language has a match
|
||||||
|
// * languages: Array of user's browser languages.
|
||||||
|
// * language: The language preferred by user settings or config
|
||||||
|
// * active: The state preferred by user settings or config
|
||||||
|
// * toggled: The real captions state
|
||||||
|
|
||||||
|
const languages = dedupe(
|
||||||
|
Array.from(navigator.languages || navigator.userLanguage).map(language => language.split('-')[0]),
|
||||||
|
);
|
||||||
|
|
||||||
|
let language = (this.storage.get('language') || this.config.captions.language || 'auto').toLowerCase();
|
||||||
|
|
||||||
|
// Use first browser language when language is 'auto'
|
||||||
|
if (language === 'auto') {
|
||||||
|
[language] = languages;
|
||||||
|
}
|
||||||
|
|
||||||
|
let active = this.storage.get('captions');
|
||||||
|
if (!is.boolean(active)) {
|
||||||
|
({ active } = this.config.captions);
|
||||||
|
}
|
||||||
|
|
||||||
|
Object.assign(this.captions, {
|
||||||
|
toggled: false,
|
||||||
|
active,
|
||||||
|
language,
|
||||||
|
languages,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Watch changes to textTracks and update captions menu
|
||||||
|
if (this.isHTML5) {
|
||||||
|
const trackEvents = this.config.captions.update ? 'addtrack removetrack' : 'removetrack';
|
||||||
|
on.call(this, this.media.textTracks, trackEvents, captions.update.bind(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update available languages in list next tick (the event must not be triggered before the listeners)
|
||||||
|
setTimeout(captions.update.bind(this), 0);
|
||||||
|
},
|
||||||
|
|
||||||
|
// Update available language options in settings based on tracks
|
||||||
|
update() {
|
||||||
|
const tracks = captions.getTracks.call(this, true);
|
||||||
|
// Get the wanted language
|
||||||
|
const { active, language, meta, currentTrackNode } = this.captions;
|
||||||
|
const languageExists = Boolean(tracks.find(track => track.language === language));
|
||||||
|
|
||||||
|
// Handle tracks (add event listener and "pseudo"-default)
|
||||||
|
if (this.isHTML5 && this.isVideo) {
|
||||||
|
tracks.filter(track => !meta.get(track)).forEach(track => {
|
||||||
|
this.debug.log('Track added', track);
|
||||||
|
// Attempt to store if the original dom element was "default"
|
||||||
|
meta.set(track, {
|
||||||
|
default: track.mode === 'showing',
|
||||||
|
});
|
||||||
|
|
||||||
|
// Turn off native caption rendering to avoid double captions
|
||||||
|
track.mode = 'hidden';
|
||||||
|
|
||||||
|
// Add event listener for cue changes
|
||||||
|
on.call(this, track, 'cuechange', () => captions.updateCues.call(this));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update language first time it matches, or if the previous matching track was removed
|
||||||
|
if ((languageExists && this.language !== language) || !tracks.includes(currentTrackNode)) {
|
||||||
|
captions.setLanguage.call(this, language);
|
||||||
|
captions.toggle.call(this, active && languageExists);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enable or disable captions based on track length
|
||||||
|
toggleClass(this.elements.container, this.config.classNames.captions.enabled, !is.empty(tracks));
|
||||||
|
|
||||||
|
// Update available languages in list
|
||||||
|
if ((this.config.controls || []).includes('settings') && this.config.settings.includes('captions')) {
|
||||||
|
controls.setCaptionsMenu.call(this);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// Toggle captions display
|
||||||
|
// Used internally for the toggleCaptions method, with the passive option forced to false
|
||||||
|
toggle(input, passive = true) {
|
||||||
|
// If there's no full support
|
||||||
|
if (!this.supported.ui) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { toggled } = this.captions; // Current state
|
||||||
|
const activeClass = this.config.classNames.captions.active;
|
||||||
|
|
||||||
|
// Get the next state
|
||||||
|
// If the method is called without parameter, toggle based on current value
|
||||||
|
const active = is.nullOrUndefined(input) ? !toggled : input;
|
||||||
|
|
||||||
|
// Update state and trigger event
|
||||||
|
if (active !== toggled) {
|
||||||
|
// When passive, don't override user preferences
|
||||||
|
if (!passive) {
|
||||||
|
this.captions.active = active;
|
||||||
|
this.storage.set({ captions: active });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Force language if the call isn't passive and there is no matching language to toggle to
|
||||||
|
if (!this.language && active && !passive) {
|
||||||
|
const tracks = captions.getTracks.call(this);
|
||||||
|
const track = captions.findTrack.call(this, [this.captions.language, ...this.captions.languages], true);
|
||||||
|
|
||||||
|
// Override user preferences to avoid switching languages if a matching track is added
|
||||||
|
this.captions.language = track.language;
|
||||||
|
|
||||||
|
// Set caption, but don't store in localStorage as user preference
|
||||||
|
captions.set.call(this, tracks.indexOf(track));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Toggle state
|
||||||
|
this.elements.buttons.captions.pressed = active;
|
||||||
|
|
||||||
|
// Add class hook
|
||||||
|
toggleClass(this.elements.container, activeClass, active);
|
||||||
|
|
||||||
|
this.captions.toggled = active;
|
||||||
|
|
||||||
|
// Update settings menu
|
||||||
|
controls.updateSetting.call(this, 'captions');
|
||||||
|
|
||||||
|
// Trigger event (not used internally)
|
||||||
|
triggerEvent.call(this, this.media, active ? 'captionsenabled' : 'captionsdisabled');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// Set captions by track index
|
||||||
|
// Used internally for the currentTrack setter with the passive option forced to false
|
||||||
|
set(index, passive = true) {
|
||||||
|
const tracks = captions.getTracks.call(this);
|
||||||
|
|
||||||
|
// Disable captions if setting to -1
|
||||||
|
if (index === -1) {
|
||||||
|
captions.toggle.call(this, false, passive);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is.number(index)) {
|
||||||
|
this.debug.warn('Invalid caption argument', index);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(index in tracks)) {
|
||||||
|
this.debug.warn('Track not found', index);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.captions.currentTrack !== index) {
|
||||||
|
this.captions.currentTrack = index;
|
||||||
|
const track = tracks[index];
|
||||||
|
const { language } = track || {};
|
||||||
|
|
||||||
|
// Store reference to node for invalidation on remove
|
||||||
|
this.captions.currentTrackNode = track;
|
||||||
|
|
||||||
|
// Update settings menu
|
||||||
|
controls.updateSetting.call(this, 'captions');
|
||||||
|
|
||||||
|
// When passive, don't override user preferences
|
||||||
|
if (!passive) {
|
||||||
|
this.captions.language = language;
|
||||||
|
this.storage.set({ language });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle Vimeo captions
|
||||||
|
if (this.isVimeo) {
|
||||||
|
this.embed.enableTextTrack(language);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Trigger event
|
||||||
|
triggerEvent.call(this, this.media, 'languagechange');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show captions
|
||||||
|
captions.toggle.call(this, true, passive);
|
||||||
|
|
||||||
|
if (this.isHTML5 && this.isVideo) {
|
||||||
|
// If we change the active track while a cue is already displayed we need to update it
|
||||||
|
captions.updateCues.call(this);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// Set captions by language
|
||||||
|
// Used internally for the language setter with the passive option forced to false
|
||||||
|
setLanguage(input, passive = true) {
|
||||||
|
if (!is.string(input)) {
|
||||||
|
this.debug.warn('Invalid language argument', input);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Normalize
|
||||||
|
const language = input.toLowerCase();
|
||||||
|
this.captions.language = language;
|
||||||
|
|
||||||
|
// Set currentTrack
|
||||||
|
const tracks = captions.getTracks.call(this);
|
||||||
|
const track = captions.findTrack.call(this, [language]);
|
||||||
|
captions.set.call(this, tracks.indexOf(track), passive);
|
||||||
|
},
|
||||||
|
|
||||||
|
// Get current valid caption tracks
|
||||||
|
// If update is false it will also ignore tracks without metadata
|
||||||
|
// This is used to "freeze" the language options when captions.update is false
|
||||||
|
getTracks(update = false) {
|
||||||
|
// Handle media or textTracks missing or null
|
||||||
|
const tracks = Array.from((this.media || {}).textTracks || []);
|
||||||
|
// For HTML5, use cache instead of current tracks when it exists (if captions.update is false)
|
||||||
|
// Filter out removed tracks and tracks that aren't captions/subtitles (for example metadata)
|
||||||
|
return tracks
|
||||||
|
.filter(track => !this.isHTML5 || update || this.captions.meta.has(track))
|
||||||
|
.filter(track => ['captions', 'subtitles'].includes(track.kind));
|
||||||
|
},
|
||||||
|
|
||||||
|
// Match tracks based on languages and get the first
|
||||||
|
findTrack(languages, force = false) {
|
||||||
|
const tracks = captions.getTracks.call(this);
|
||||||
|
const sortIsDefault = track => Number((this.captions.meta.get(track) || {}).default);
|
||||||
|
const sorted = Array.from(tracks).sort((a, b) => sortIsDefault(b) - sortIsDefault(a));
|
||||||
|
let track;
|
||||||
|
languages.every(language => {
|
||||||
|
track = sorted.find(track => track.language === language);
|
||||||
|
return !track; // Break iteration if there is a match
|
||||||
|
});
|
||||||
|
// If no match is found but is required, get first
|
||||||
|
return track || (force ? sorted[0] : undefined);
|
||||||
|
},
|
||||||
|
|
||||||
|
// Get the current track
|
||||||
|
getCurrentTrack() {
|
||||||
|
return captions.getTracks.call(this)[this.currentTrack];
|
||||||
|
},
|
||||||
|
|
||||||
|
// Get UI label for track
|
||||||
|
getLabel(track) {
|
||||||
|
let currentTrack = track;
|
||||||
|
|
||||||
|
if (!is.track(currentTrack) && support.textTracks && this.captions.toggled) {
|
||||||
|
currentTrack = captions.getCurrentTrack.call(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is.track(currentTrack)) {
|
||||||
|
if (!is.empty(currentTrack.label)) {
|
||||||
|
return currentTrack.label;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is.empty(currentTrack.language)) {
|
||||||
|
return track.language.toUpperCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
return i18n.get('enabled', this.config);
|
||||||
|
}
|
||||||
|
|
||||||
|
return i18n.get('disabled', this.config);
|
||||||
|
},
|
||||||
|
|
||||||
|
// Update captions using current track's active cues
|
||||||
|
// Also optional array argument in case there isn't any track (ex: vimeo)
|
||||||
|
updateCues(input) {
|
||||||
|
// Requires UI
|
||||||
|
if (!this.supported.ui) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is.element(this.elements.captions)) {
|
||||||
|
this.debug.warn('No captions element to render to');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only accept array or empty input
|
||||||
|
if (!is.nullOrUndefined(input) && !Array.isArray(input)) {
|
||||||
|
this.debug.warn('updateCues: Invalid input', input);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let cues = input;
|
||||||
|
|
||||||
|
// Get cues from track
|
||||||
|
if (!cues) {
|
||||||
|
const track = captions.getCurrentTrack.call(this);
|
||||||
|
cues = Array.from((track || {}).activeCues || [])
|
||||||
|
.map(cue => cue.getCueAsHTML())
|
||||||
|
.map(getHTML);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set new caption text
|
||||||
|
const content = cues.map(cueText => cueText.trim()).join('\n');
|
||||||
|
const changed = content !== this.elements.captions.innerHTML;
|
||||||
|
|
||||||
|
if (changed) {
|
||||||
|
// Empty the container and create a new child element
|
||||||
|
emptyElement(this.elements.captions);
|
||||||
|
const caption = createElement('span', getAttributesFromSelector(this.config.selectors.caption));
|
||||||
|
caption.innerHTML = content;
|
||||||
|
this.elements.captions.appendChild(caption);
|
||||||
|
|
||||||
|
// Trigger event
|
||||||
|
triggerEvent.call(this, this.media, 'cuechange');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default captions;
|
402
src/js/config/defaults.js
Normal file
@ -0,0 +1,402 @@
|
|||||||
|
// ==========================================================================
|
||||||
|
// Plyr default config
|
||||||
|
// ==========================================================================
|
||||||
|
|
||||||
|
const defaults = {
|
||||||
|
// Disable
|
||||||
|
enabled: true,
|
||||||
|
|
||||||
|
// Custom media title
|
||||||
|
title: '',
|
||||||
|
|
||||||
|
// Logging to console
|
||||||
|
debug: false,
|
||||||
|
|
||||||
|
// Auto play (if supported)
|
||||||
|
autoplay: false,
|
||||||
|
|
||||||
|
// Only allow one media playing at once (vimeo only)
|
||||||
|
autopause: true,
|
||||||
|
|
||||||
|
// Allow inline playback on iOS (this effects YouTube/Vimeo - HTML5 requires the attribute present)
|
||||||
|
// TODO: Remove iosNative fullscreen option in favour of this (logic needs work)
|
||||||
|
playsinline: true,
|
||||||
|
|
||||||
|
// Default time to skip when rewind/fast forward
|
||||||
|
seekTime: 10,
|
||||||
|
|
||||||
|
// Default volume
|
||||||
|
volume: 1,
|
||||||
|
muted: false,
|
||||||
|
|
||||||
|
// Pass a custom duration
|
||||||
|
duration: null,
|
||||||
|
|
||||||
|
// Display the media duration on load in the current time position
|
||||||
|
// If you have opted to display both duration and currentTime, this is ignored
|
||||||
|
displayDuration: true,
|
||||||
|
|
||||||
|
// Invert the current time to be a countdown
|
||||||
|
invertTime: true,
|
||||||
|
|
||||||
|
// Clicking the currentTime inverts it's value to show time left rather than elapsed
|
||||||
|
toggleInvert: true,
|
||||||
|
|
||||||
|
// Aspect ratio (for embeds)
|
||||||
|
ratio: '16:9',
|
||||||
|
|
||||||
|
// Click video container to play/pause
|
||||||
|
clickToPlay: true,
|
||||||
|
|
||||||
|
// Auto hide the controls
|
||||||
|
hideControls: true,
|
||||||
|
|
||||||
|
// Reset to start when playback ended
|
||||||
|
resetOnEnd: false,
|
||||||
|
|
||||||
|
// Disable the standard context menu
|
||||||
|
disableContextMenu: true,
|
||||||
|
|
||||||
|
// Sprite (for icons)
|
||||||
|
loadSprite: true,
|
||||||
|
iconPrefix: 'plyr',
|
||||||
|
iconUrl: 'https://cdn.plyr.io/3.3.12/plyr.svg',
|
||||||
|
|
||||||
|
// Blank video (used to prevent errors on source change)
|
||||||
|
blankVideo: 'https://cdn.plyr.io/static/blank.mp4',
|
||||||
|
|
||||||
|
// Quality default
|
||||||
|
quality: {
|
||||||
|
default: 576,
|
||||||
|
options: [
|
||||||
|
4320,
|
||||||
|
2880,
|
||||||
|
2160,
|
||||||
|
1440,
|
||||||
|
1080,
|
||||||
|
720,
|
||||||
|
576,
|
||||||
|
480,
|
||||||
|
360,
|
||||||
|
240,
|
||||||
|
'default', // YouTube's "auto"
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
// Set loops
|
||||||
|
loop: {
|
||||||
|
active: false,
|
||||||
|
// start: null,
|
||||||
|
// end: null,
|
||||||
|
},
|
||||||
|
|
||||||
|
// Speed default and options to display
|
||||||
|
speed: {
|
||||||
|
selected: 1,
|
||||||
|
options: [0.5, 0.75, 1, 1.25, 1.5, 1.75, 2],
|
||||||
|
},
|
||||||
|
|
||||||
|
// Keyboard shortcut settings
|
||||||
|
keyboard: {
|
||||||
|
focused: true,
|
||||||
|
global: false,
|
||||||
|
},
|
||||||
|
|
||||||
|
// Display tooltips
|
||||||
|
tooltips: {
|
||||||
|
controls: false,
|
||||||
|
seek: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
// Captions settings
|
||||||
|
captions: {
|
||||||
|
active: false,
|
||||||
|
language: 'auto',
|
||||||
|
// Listen to new tracks added after Plyr is initialized.
|
||||||
|
// This is needed for streaming captions, but may result in unselectable options
|
||||||
|
update: false,
|
||||||
|
},
|
||||||
|
|
||||||
|
// Fullscreen settings
|
||||||
|
fullscreen: {
|
||||||
|
enabled: true, // Allow fullscreen?
|
||||||
|
fallback: true, // Fallback for vintage browsers
|
||||||
|
iosNative: false, // Use the native fullscreen in iOS (disables custom controls)
|
||||||
|
},
|
||||||
|
|
||||||
|
// Local storage
|
||||||
|
storage: {
|
||||||
|
enabled: true,
|
||||||
|
key: 'plyr',
|
||||||
|
},
|
||||||
|
|
||||||
|
// Default controls
|
||||||
|
controls: [
|
||||||
|
'play-large',
|
||||||
|
// 'restart',
|
||||||
|
// 'rewind',
|
||||||
|
'play',
|
||||||
|
// 'fast-forward',
|
||||||
|
'progress',
|
||||||
|
'current-time',
|
||||||
|
'mute',
|
||||||
|
'volume',
|
||||||
|
'captions',
|
||||||
|
'settings',
|
||||||
|
'pip',
|
||||||
|
'airplay',
|
||||||
|
'fullscreen',
|
||||||
|
],
|
||||||
|
settings: ['captions', 'quality', 'speed'],
|
||||||
|
|
||||||
|
// Localisation
|
||||||
|
i18n: {
|
||||||
|
restart: 'Restart',
|
||||||
|
rewind: 'Rewind {seektime}s',
|
||||||
|
play: 'Play',
|
||||||
|
pause: 'Pause',
|
||||||
|
fastForward: 'Forward {seektime}s',
|
||||||
|
seek: 'Seek',
|
||||||
|
seekLabel: '{currentTime} of {duration}',
|
||||||
|
played: 'Played',
|
||||||
|
buffered: 'Buffered',
|
||||||
|
currentTime: 'Current time',
|
||||||
|
duration: 'Duration',
|
||||||
|
volume: 'Volume',
|
||||||
|
mute: 'Mute',
|
||||||
|
unmute: 'Unmute',
|
||||||
|
enableCaptions: 'Enable captions',
|
||||||
|
disableCaptions: 'Disable captions',
|
||||||
|
enterFullscreen: 'Enter fullscreen',
|
||||||
|
exitFullscreen: 'Exit fullscreen',
|
||||||
|
frameTitle: 'Player for {title}',
|
||||||
|
captions: 'Captions',
|
||||||
|
settings: 'Settings',
|
||||||
|
menuBack: 'Go back to previous menu',
|
||||||
|
speed: 'Speed',
|
||||||
|
normal: 'Normal',
|
||||||
|
quality: 'Quality',
|
||||||
|
loop: 'Loop',
|
||||||
|
start: 'Start',
|
||||||
|
end: 'End',
|
||||||
|
all: 'All',
|
||||||
|
reset: 'Reset',
|
||||||
|
disabled: 'Disabled',
|
||||||
|
enabled: 'Enabled',
|
||||||
|
advertisement: 'Ad',
|
||||||
|
qualityBadge: {
|
||||||
|
2160: '4K',
|
||||||
|
1440: 'HD',
|
||||||
|
1080: 'HD',
|
||||||
|
720: 'HD',
|
||||||
|
576: 'SD',
|
||||||
|
480: 'SD',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
// URLs
|
||||||
|
urls: {
|
||||||
|
vimeo: {
|
||||||
|
sdk: 'https://player.vimeo.com/api/player.js',
|
||||||
|
iframe: 'https://player.vimeo.com/video/{0}?{1}',
|
||||||
|
api: 'https://vimeo.com/api/v2/video/{0}.json',
|
||||||
|
},
|
||||||
|
youtube: {
|
||||||
|
sdk: 'https://www.youtube.com/iframe_api',
|
||||||
|
api:
|
||||||
|
'https://www.googleapis.com/youtube/v3/videos?id={0}&key={1}&fields=items(snippet(title))&part=snippet',
|
||||||
|
},
|
||||||
|
googleIMA: {
|
||||||
|
sdk: 'https://imasdk.googleapis.com/js/sdkloader/ima3.js',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
// Custom control listeners
|
||||||
|
listeners: {
|
||||||
|
seek: null,
|
||||||
|
play: null,
|
||||||
|
pause: null,
|
||||||
|
restart: null,
|
||||||
|
rewind: null,
|
||||||
|
fastForward: null,
|
||||||
|
mute: null,
|
||||||
|
volume: null,
|
||||||
|
captions: null,
|
||||||
|
fullscreen: null,
|
||||||
|
pip: null,
|
||||||
|
airplay: null,
|
||||||
|
speed: null,
|
||||||
|
quality: null,
|
||||||
|
loop: null,
|
||||||
|
language: null,
|
||||||
|
},
|
||||||
|
|
||||||
|
// Events to watch and bubble
|
||||||
|
events: [
|
||||||
|
// Events to watch on HTML5 media elements and bubble
|
||||||
|
// https://developer.mozilla.org/en/docs/Web/Guide/Events/Media_events
|
||||||
|
'ended',
|
||||||
|
'progress',
|
||||||
|
'stalled',
|
||||||
|
'playing',
|
||||||
|
'waiting',
|
||||||
|
'canplay',
|
||||||
|
'canplaythrough',
|
||||||
|
'loadstart',
|
||||||
|
'loadeddata',
|
||||||
|
'loadedmetadata',
|
||||||
|
'timeupdate',
|
||||||
|
'volumechange',
|
||||||
|
'play',
|
||||||
|
'pause',
|
||||||
|
'error',
|
||||||
|
'seeking',
|
||||||
|
'seeked',
|
||||||
|
'emptied',
|
||||||
|
'ratechange',
|
||||||
|
'cuechange',
|
||||||
|
|
||||||
|
// Custom events
|
||||||
|
'enterfullscreen',
|
||||||
|
'exitfullscreen',
|
||||||
|
'captionsenabled',
|
||||||
|
'captionsdisabled',
|
||||||
|
'languagechange',
|
||||||
|
'controlshidden',
|
||||||
|
'controlsshown',
|
||||||
|
'ready',
|
||||||
|
|
||||||
|
// YouTube
|
||||||
|
'statechange',
|
||||||
|
'qualitychange',
|
||||||
|
'qualityrequested',
|
||||||
|
|
||||||
|
// Ads
|
||||||
|
'adsloaded',
|
||||||
|
'adscontentpause',
|
||||||
|
'adscontentresume',
|
||||||
|
'adstarted',
|
||||||
|
'adsmidpoint',
|
||||||
|
'adscomplete',
|
||||||
|
'adsallcomplete',
|
||||||
|
'adsimpression',
|
||||||
|
'adsclick',
|
||||||
|
],
|
||||||
|
|
||||||
|
// Selectors
|
||||||
|
// Change these to match your template if using custom HTML
|
||||||
|
selectors: {
|
||||||
|
editable: 'input, textarea, select, [contenteditable]',
|
||||||
|
container: '.plyr',
|
||||||
|
controls: {
|
||||||
|
container: null,
|
||||||
|
wrapper: '.plyr__controls',
|
||||||
|
},
|
||||||
|
labels: '[data-plyr]',
|
||||||
|
buttons: {
|
||||||
|
play: '[data-plyr="play"]',
|
||||||
|
pause: '[data-plyr="pause"]',
|
||||||
|
restart: '[data-plyr="restart"]',
|
||||||
|
rewind: '[data-plyr="rewind"]',
|
||||||
|
fastForward: '[data-plyr="fast-forward"]',
|
||||||
|
mute: '[data-plyr="mute"]',
|
||||||
|
captions: '[data-plyr="captions"]',
|
||||||
|
fullscreen: '[data-plyr="fullscreen"]',
|
||||||
|
pip: '[data-plyr="pip"]',
|
||||||
|
airplay: '[data-plyr="airplay"]',
|
||||||
|
settings: '[data-plyr="settings"]',
|
||||||
|
loop: '[data-plyr="loop"]',
|
||||||
|
},
|
||||||
|
inputs: {
|
||||||
|
seek: '[data-plyr="seek"]',
|
||||||
|
volume: '[data-plyr="volume"]',
|
||||||
|
speed: '[data-plyr="speed"]',
|
||||||
|
language: '[data-plyr="language"]',
|
||||||
|
quality: '[data-plyr="quality"]',
|
||||||
|
},
|
||||||
|
display: {
|
||||||
|
currentTime: '.plyr__time--current',
|
||||||
|
duration: '.plyr__time--duration',
|
||||||
|
buffer: '.plyr__progress__buffer',
|
||||||
|
loop: '.plyr__progress__loop', // Used later
|
||||||
|
volume: '.plyr__volume--display',
|
||||||
|
},
|
||||||
|
progress: '.plyr__progress',
|
||||||
|
captions: '.plyr__captions',
|
||||||
|
caption: '.plyr__caption',
|
||||||
|
menu: {
|
||||||
|
quality: '.js-plyr__menu__list--quality',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
// Class hooks added to the player in different states
|
||||||
|
classNames: {
|
||||||
|
type: 'plyr--{0}',
|
||||||
|
provider: 'plyr--{0}',
|
||||||
|
video: 'plyr__video-wrapper',
|
||||||
|
embed: 'plyr__video-embed',
|
||||||
|
embedContainer: 'plyr__video-embed__container',
|
||||||
|
poster: 'plyr__poster',
|
||||||
|
posterEnabled: 'plyr__poster-enabled',
|
||||||
|
ads: 'plyr__ads',
|
||||||
|
control: 'plyr__control',
|
||||||
|
controlPressed: 'plyr__control--pressed',
|
||||||
|
playing: 'plyr--playing',
|
||||||
|
paused: 'plyr--paused',
|
||||||
|
stopped: 'plyr--stopped',
|
||||||
|
loading: 'plyr--loading',
|
||||||
|
hover: 'plyr--hover',
|
||||||
|
tooltip: 'plyr__tooltip',
|
||||||
|
cues: 'plyr__cues',
|
||||||
|
hidden: 'plyr__sr-only',
|
||||||
|
hideControls: 'plyr--hide-controls',
|
||||||
|
isIos: 'plyr--is-ios',
|
||||||
|
isTouch: 'plyr--is-touch',
|
||||||
|
uiSupported: 'plyr--full-ui',
|
||||||
|
noTransition: 'plyr--no-transition',
|
||||||
|
menu: {
|
||||||
|
value: 'plyr__menu__value',
|
||||||
|
badge: 'plyr__badge',
|
||||||
|
open: 'plyr--menu-open',
|
||||||
|
},
|
||||||
|
captions: {
|
||||||
|
enabled: 'plyr--captions-enabled',
|
||||||
|
active: 'plyr--captions-active',
|
||||||
|
},
|
||||||
|
fullscreen: {
|
||||||
|
enabled: 'plyr--fullscreen-enabled',
|
||||||
|
fallback: 'plyr--fullscreen-fallback',
|
||||||
|
},
|
||||||
|
pip: {
|
||||||
|
supported: 'plyr--pip-supported',
|
||||||
|
active: 'plyr--pip-active',
|
||||||
|
},
|
||||||
|
airplay: {
|
||||||
|
supported: 'plyr--airplay-supported',
|
||||||
|
active: 'plyr--airplay-active',
|
||||||
|
},
|
||||||
|
tabFocus: 'plyr__tab-focus',
|
||||||
|
},
|
||||||
|
|
||||||
|
// Embed attributes
|
||||||
|
attributes: {
|
||||||
|
embed: {
|
||||||
|
provider: 'data-plyr-provider',
|
||||||
|
id: 'data-plyr-embed-id',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
// API keys
|
||||||
|
keys: {
|
||||||
|
google: null,
|
||||||
|
},
|
||||||
|
|
||||||
|
// Advertisements plugin
|
||||||
|
// Register for an account here: http://vi.ai/publisher-video-monetization/?aid=plyrio
|
||||||
|
ads: {
|
||||||
|
enabled: false,
|
||||||
|
publisherId: '',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default defaults;
|
34
src/js/config/types.js
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
// ==========================================================================
|
||||||
|
// Plyr supported types and providers
|
||||||
|
// ==========================================================================
|
||||||
|
|
||||||
|
export const providers = {
|
||||||
|
html5: 'html5',
|
||||||
|
youtube: 'youtube',
|
||||||
|
vimeo: 'vimeo',
|
||||||
|
};
|
||||||
|
|
||||||
|
export const types = {
|
||||||
|
audio: 'audio',
|
||||||
|
video: 'video',
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get provider by URL
|
||||||
|
* @param {string} url
|
||||||
|
*/
|
||||||
|
export function getProviderByUrl(url) {
|
||||||
|
// YouTube
|
||||||
|
if (/^(https?:\/\/)?(www\.)?(youtube\.com|youtu\.?be)\/.+$/.test(url)) {
|
||||||
|
return providers.youtube;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Vimeo
|
||||||
|
if (/^https?:\/\/player.vimeo.com\/video\/\d{0,9}(?=\b|\/)/.test(url)) {
|
||||||
|
return providers.vimeo;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default { providers, types };
|
28
src/js/console.js
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
// ==========================================================================
|
||||||
|
// Console wrapper
|
||||||
|
// ==========================================================================
|
||||||
|
|
||||||
|
const noop = () => {};
|
||||||
|
|
||||||
|
export default class Console {
|
||||||
|
constructor(enabled = false) {
|
||||||
|
this.enabled = window.console && enabled;
|
||||||
|
|
||||||
|
if (this.enabled) {
|
||||||
|
this.log('Debugging enabled');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
get log() {
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
return this.enabled ? Function.prototype.bind.call(console.log, console) : noop;
|
||||||
|
}
|
||||||
|
get warn() {
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
return this.enabled ? Function.prototype.bind.call(console.warn, console) : noop;
|
||||||
|
}
|
||||||
|
get error() {
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
return this.enabled ? Function.prototype.bind.call(console.error, console) : noop;
|
||||||
|
}
|
||||||
|
}
|
1479
src/js/controls.js
vendored
Normal file
222
src/js/fullscreen.js
Normal file
@ -0,0 +1,222 @@
|
|||||||
|
// ==========================================================================
|
||||||
|
// Fullscreen wrapper
|
||||||
|
// https://developer.mozilla.org/en-US/docs/Web/API/Fullscreen_API#prefixing
|
||||||
|
// ==========================================================================
|
||||||
|
|
||||||
|
import browser from './utils/browser';
|
||||||
|
import { hasClass, toggleClass, trapFocus } from './utils/elements';
|
||||||
|
import { on, triggerEvent } from './utils/events';
|
||||||
|
import is from './utils/is';
|
||||||
|
|
||||||
|
function onChange() {
|
||||||
|
if (!this.enabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update toggle button
|
||||||
|
const button = this.player.elements.buttons.fullscreen;
|
||||||
|
if (is.element(button)) {
|
||||||
|
button.pressed = this.active;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Trigger an event
|
||||||
|
triggerEvent.call(this.player, this.target, this.active ? 'enterfullscreen' : 'exitfullscreen', true);
|
||||||
|
|
||||||
|
// Trap focus in container
|
||||||
|
if (!browser.isIos) {
|
||||||
|
trapFocus.call(this.player, this.target, this.active);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleFallback(toggle = false) {
|
||||||
|
// Store or restore scroll position
|
||||||
|
if (toggle) {
|
||||||
|
this.scrollPosition = {
|
||||||
|
x: window.scrollX || 0,
|
||||||
|
y: window.scrollY || 0,
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
window.scrollTo(this.scrollPosition.x, this.scrollPosition.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Toggle scroll
|
||||||
|
document.body.style.overflow = toggle ? 'hidden' : '';
|
||||||
|
|
||||||
|
// Toggle class hook
|
||||||
|
toggleClass(this.target, this.player.config.classNames.fullscreen.fallback, toggle);
|
||||||
|
|
||||||
|
// Toggle button and fire events
|
||||||
|
onChange.call(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
class Fullscreen {
|
||||||
|
constructor(player) {
|
||||||
|
// Keep reference to parent
|
||||||
|
this.player = player;
|
||||||
|
|
||||||
|
// Get prefix
|
||||||
|
this.prefix = Fullscreen.prefix;
|
||||||
|
this.property = Fullscreen.property;
|
||||||
|
|
||||||
|
// Scroll position
|
||||||
|
this.scrollPosition = { x: 0, y: 0 };
|
||||||
|
|
||||||
|
// Register event listeners
|
||||||
|
// Handle event (incase user presses escape etc)
|
||||||
|
on.call(
|
||||||
|
this.player,
|
||||||
|
document,
|
||||||
|
this.prefix === 'ms' ? 'MSFullscreenChange' : `${this.prefix}fullscreenchange`,
|
||||||
|
() => {
|
||||||
|
// TODO: Filter for target??
|
||||||
|
onChange.call(this);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
// Fullscreen toggle on double click
|
||||||
|
on.call(this.player, this.player.elements.container, 'dblclick', event => {
|
||||||
|
// Ignore double click in controls
|
||||||
|
if (is.element(this.player.elements.controls) && this.player.elements.controls.contains(event.target)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.toggle();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Update the UI
|
||||||
|
this.update();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determine if native supported
|
||||||
|
static get native() {
|
||||||
|
return !!(
|
||||||
|
document.fullscreenEnabled ||
|
||||||
|
document.webkitFullscreenEnabled ||
|
||||||
|
document.mozFullScreenEnabled ||
|
||||||
|
document.msFullscreenEnabled
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the prefix for handlers
|
||||||
|
static get prefix() {
|
||||||
|
// No prefix
|
||||||
|
if (is.function(document.exitFullscreen)) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for fullscreen support by vendor prefix
|
||||||
|
let value = '';
|
||||||
|
const prefixes = ['webkit', 'moz', 'ms'];
|
||||||
|
|
||||||
|
prefixes.some(pre => {
|
||||||
|
if (is.function(document[`${pre}ExitFullscreen`]) || is.function(document[`${pre}CancelFullScreen`])) {
|
||||||
|
value = pre;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
static get property() {
|
||||||
|
return this.prefix === 'moz' ? 'FullScreen' : 'Fullscreen';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determine if fullscreen is enabled
|
||||||
|
get enabled() {
|
||||||
|
return (
|
||||||
|
(Fullscreen.native || this.player.config.fullscreen.fallback) &&
|
||||||
|
this.player.config.fullscreen.enabled &&
|
||||||
|
this.player.supported.ui &&
|
||||||
|
this.player.isVideo
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get active state
|
||||||
|
get active() {
|
||||||
|
if (!this.enabled) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fallback using classname
|
||||||
|
if (!Fullscreen.native) {
|
||||||
|
return hasClass(this.target, this.player.config.classNames.fullscreen.fallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
const element = !this.prefix ? document.fullscreenElement : document[`${this.prefix}${this.property}Element`];
|
||||||
|
|
||||||
|
return element === this.target;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get target element
|
||||||
|
get target() {
|
||||||
|
return browser.isIos && this.player.config.fullscreen.iosNative
|
||||||
|
? this.player.media
|
||||||
|
: this.player.elements.container;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update UI
|
||||||
|
update() {
|
||||||
|
if (this.enabled) {
|
||||||
|
this.player.debug.log(`${Fullscreen.native ? 'Native' : 'Fallback'} fullscreen enabled`);
|
||||||
|
} else {
|
||||||
|
this.player.debug.log('Fullscreen not supported and fallback disabled');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add styling hook to show button
|
||||||
|
toggleClass(this.player.elements.container, this.player.config.classNames.fullscreen.enabled, this.enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make an element fullscreen
|
||||||
|
enter() {
|
||||||
|
if (!this.enabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// iOS native fullscreen doesn't need the request step
|
||||||
|
if (browser.isIos && this.player.config.fullscreen.iosNative) {
|
||||||
|
if (this.player.playing) {
|
||||||
|
this.target.webkitEnterFullscreen();
|
||||||
|
}
|
||||||
|
} else if (!Fullscreen.native) {
|
||||||
|
toggleFallback.call(this, true);
|
||||||
|
} else if (!this.prefix) {
|
||||||
|
this.target.requestFullscreen();
|
||||||
|
} else if (!is.empty(this.prefix)) {
|
||||||
|
this.target[`${this.prefix}Request${this.property}`]();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bail from fullscreen
|
||||||
|
exit() {
|
||||||
|
if (!this.enabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// iOS native fullscreen
|
||||||
|
if (browser.isIos && this.player.config.fullscreen.iosNative) {
|
||||||
|
this.target.webkitExitFullscreen();
|
||||||
|
this.player.play();
|
||||||
|
} else if (!Fullscreen.native) {
|
||||||
|
toggleFallback.call(this, false);
|
||||||
|
} else if (!this.prefix) {
|
||||||
|
(document.cancelFullScreen || document.exitFullscreen).call(document);
|
||||||
|
} else if (!is.empty(this.prefix)) {
|
||||||
|
const action = this.prefix === 'moz' ? 'Cancel' : 'Exit';
|
||||||
|
document[`${this.prefix}${action}${this.property}`]();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Toggle state
|
||||||
|
toggle() {
|
||||||
|
if (!this.active) {
|
||||||
|
this.enter();
|
||||||
|
} else {
|
||||||
|
this.exit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Fullscreen;
|
112
src/js/html5.js
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
// ==========================================================================
|
||||||
|
// Plyr HTML5 helpers
|
||||||
|
// ==========================================================================
|
||||||
|
|
||||||
|
import support from './support';
|
||||||
|
import { removeElement } from './utils/elements';
|
||||||
|
import { triggerEvent } from './utils/events';
|
||||||
|
|
||||||
|
const html5 = {
|
||||||
|
getSources() {
|
||||||
|
if (!this.isHTML5) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
const sources = Array.from(this.media.querySelectorAll('source'));
|
||||||
|
|
||||||
|
// Filter out unsupported sources
|
||||||
|
return sources.filter(source => support.mime.call(this, source.getAttribute('type')));
|
||||||
|
},
|
||||||
|
|
||||||
|
// Get quality levels
|
||||||
|
getQualityOptions() {
|
||||||
|
// Get sizes from <source> elements
|
||||||
|
return html5.getSources
|
||||||
|
.call(this)
|
||||||
|
.map(source => Number(source.getAttribute('size')))
|
||||||
|
.filter(Boolean);
|
||||||
|
},
|
||||||
|
|
||||||
|
extend() {
|
||||||
|
if (!this.isHTML5) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const player = this;
|
||||||
|
|
||||||
|
// Quality
|
||||||
|
Object.defineProperty(player.media, 'quality', {
|
||||||
|
get() {
|
||||||
|
// Get sources
|
||||||
|
const sources = html5.getSources.call(player);
|
||||||
|
const [source] = sources.filter(source => source.getAttribute('src') === player.source);
|
||||||
|
|
||||||
|
// Return size, if match is found
|
||||||
|
return source && Number(source.getAttribute('size'));
|
||||||
|
},
|
||||||
|
set(input) {
|
||||||
|
// Get sources
|
||||||
|
const sources = html5.getSources.call(player);
|
||||||
|
|
||||||
|
// Get first match for requested size
|
||||||
|
const source = sources.find(source => Number(source.getAttribute('size')) === input);
|
||||||
|
|
||||||
|
// No matching source found
|
||||||
|
if (!source) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get current state
|
||||||
|
const { currentTime, playing } = player;
|
||||||
|
|
||||||
|
// Set new source
|
||||||
|
player.media.src = source.getAttribute('src');
|
||||||
|
|
||||||
|
// Restore time
|
||||||
|
const onLoadedMetaData = () => {
|
||||||
|
player.currentTime = currentTime;
|
||||||
|
};
|
||||||
|
player.once('loadedmetadata', onLoadedMetaData);
|
||||||
|
|
||||||
|
// Load new source
|
||||||
|
player.media.load();
|
||||||
|
|
||||||
|
// Resume playing
|
||||||
|
if (playing) {
|
||||||
|
player.play();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Trigger change event
|
||||||
|
triggerEvent.call(player, player.media, 'qualitychange', false, {
|
||||||
|
quality: input,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
// Cancel current network requests
|
||||||
|
// See https://github.com/sampotts/plyr/issues/174
|
||||||
|
cancelRequests() {
|
||||||
|
if (!this.isHTML5) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove child sources
|
||||||
|
removeElement(html5.getSources.call(this));
|
||||||
|
|
||||||
|
// Set blank video src attribute
|
||||||
|
// This is to prevent a MEDIA_ERR_SRC_NOT_SUPPORTED error
|
||||||
|
// Info: http://stackoverflow.com/questions/32231579/how-to-properly-dispose-of-an-html5-video-and-close-socket-or-connection
|
||||||
|
this.media.setAttribute('src', this.config.blankVideo);
|
||||||
|
|
||||||
|
// Load the new empty source
|
||||||
|
// This will cancel existing requests
|
||||||
|
// See https://github.com/sampotts/plyr/issues/174
|
||||||
|
this.media.load();
|
||||||
|
|
||||||
|
// Debugging
|
||||||
|
this.debug.log('Cancelled network requests');
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default html5;
|
34
src/js/i18n.js
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
// ==========================================================================
|
||||||
|
// Plyr internationalization
|
||||||
|
// ==========================================================================
|
||||||
|
|
||||||
|
import is from './utils/is';
|
||||||
|
import { getDeep } from './utils/objects';
|
||||||
|
import { replaceAll } from './utils/strings';
|
||||||
|
|
||||||
|
const i18n = {
|
||||||
|
get(key = '', config = {}) {
|
||||||
|
if (is.empty(key) || is.empty(config)) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
let string = getDeep(config.i18n, key);
|
||||||
|
|
||||||
|
if (is.empty(string)) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
const replace = {
|
||||||
|
'{seektime}': config.seekTime,
|
||||||
|
'{title}': config.title,
|
||||||
|
};
|
||||||
|
|
||||||
|
Object.entries(replace).forEach(([key, value]) => {
|
||||||
|
string = replaceAll(string, key, value);
|
||||||
|
});
|
||||||
|
|
||||||
|
return string;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default i18n;
|