cloudinary-video-player 1.6.2-edge.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (226) hide show
  1. package/.eslintignore +4 -0
  2. package/.snyk +19 -0
  3. package/.travis.yml +8 -0
  4. package/CHANGELOG.md +329 -0
  5. package/LICENSE +21 -0
  6. package/README.md +87 -0
  7. package/dist/cld-video-player.css +2110 -0
  8. package/dist/cld-video-player.js +5249 -0
  9. package/dist/cld-video-player.light.css +1766 -0
  10. package/dist/cld-video-player.light.js +1399 -0
  11. package/dist/cld-video-player.light.min.css +1 -0
  12. package/dist/cld-video-player.light.min.js +2 -0
  13. package/dist/cld-video-player.light.min.js.LICENSE.txt +23 -0
  14. package/dist/cld-video-player.min.css +1 -0
  15. package/dist/cld-video-player.min.js +2 -0
  16. package/dist/cld-video-player.min.js.LICENSE.txt +26 -0
  17. package/dist/fonts/cloudinary_icon_for_black_bg.svg +69 -0
  18. package/dist/fonts/cloudinary_icon_for_white_bg.svg +69 -0
  19. package/docs/360.html +102 -0
  20. package/docs/_template.html +93 -0
  21. package/docs/adaptive-streaming.html +297 -0
  22. package/docs/analytics.html +140 -0
  23. package/docs/api.html +302 -0
  24. package/docs/audio.html +136 -0
  25. package/docs/autoplay-fallback.html +138 -0
  26. package/docs/autoplay-on-scroll.html +107 -0
  27. package/docs/codec-fallback.html +158 -0
  28. package/docs/colors.html +135 -0
  29. package/docs/components.html +284 -0
  30. package/docs/custom-cld-errors.html +134 -0
  31. package/docs/floating-player.html +98 -0
  32. package/docs/fluid.html +117 -0
  33. package/docs/force-hls-subtitles-ios.html +159 -0
  34. package/docs/index.html +83 -0
  35. package/docs/interaction-area.html +398 -0
  36. package/docs/live-customer.html +128 -0
  37. package/docs/multiple-players.html +125 -0
  38. package/docs/playlist-by-tag-cap.html +182 -0
  39. package/docs/playlist-by-tag.html +133 -0
  40. package/docs/playlist.html +133 -0
  41. package/docs/poster.html +155 -0
  42. package/docs/raw-url.html +104 -0
  43. package/docs/recommendations.html +155 -0
  44. package/docs/scripts.js +156 -0
  45. package/docs/seek-thumbs.html +90 -0
  46. package/docs/shoppable.html +335 -0
  47. package/docs/subtitles-and-captions.html +267 -0
  48. package/docs/transformations.html +171 -0
  49. package/docs/ui-config.html +108 -0
  50. package/docs/vast-vpaid.html +149 -0
  51. package/env.example.js +6 -0
  52. package/env.js +6 -0
  53. package/jest-puppeteer.config.js +14 -0
  54. package/jest.config.js +196 -0
  55. package/package.json +99 -0
  56. package/sandbox.config.json +3 -0
  57. package/setupJest.js +1 -0
  58. package/src/assets/fonts/VideoJS.svg +120 -0
  59. package/src/assets/fonts/VideoJS.ttf +0 -0
  60. package/src/assets/fonts/VideoJS.woff +0 -0
  61. package/src/assets/fonts/icons.json +120 -0
  62. package/src/assets/icons/cloudinary_icon_for_black_bg.svg +69 -0
  63. package/src/assets/icons/cloudinary_icon_for_white_bg.svg +69 -0
  64. package/src/assets/icons/cloudinary_logo_for_dark_bg.svg +188 -0
  65. package/src/assets/icons/cloudinary_logo_for_white_bg.svg +188 -0
  66. package/src/assets/icons/info-circle.svg +17 -0
  67. package/src/assets/styles/ads-label.scss +16 -0
  68. package/src/assets/styles/components/interaction-areas.scss +158 -0
  69. package/src/assets/styles/components/playlist.scss +213 -0
  70. package/src/assets/styles/components/themedButton.scss +48 -0
  71. package/src/assets/styles/components/thumbnail.scss +94 -0
  72. package/src/assets/styles/components/title-bar.scss +67 -0
  73. package/src/assets/styles/components/triangle-volume-bar.scss +52 -0
  74. package/src/assets/styles/icons.scss +257 -0
  75. package/src/assets/styles/main.scss +324 -0
  76. package/src/assets/styles/mixins/aspect-ratio.scss +16 -0
  77. package/src/assets/styles/mixins/disable-transition.scss +3 -0
  78. package/src/assets/styles/mixins/mixins.scss +5 -0
  79. package/src/assets/styles/mixins/skin.scss +64 -0
  80. package/src/assets/styles/variables.scss +2 -0
  81. package/src/assets/styles/videojs-ima.scss +252 -0
  82. package/src/components/component-utils.js +20 -0
  83. package/src/components/index.js +21 -0
  84. package/src/components/interaction-area/interaction-area.const.js +30 -0
  85. package/src/components/interaction-area/interaction-area.service.js +223 -0
  86. package/src/components/interaction-area/interaction-area.utils.js +236 -0
  87. package/src/components/jumpButtons/jump-10-minus.js +21 -0
  88. package/src/components/jumpButtons/jump-10-plus.js +20 -0
  89. package/src/components/logoButton/logo-button.const.js +3 -0
  90. package/src/components/logoButton/logo-button.js +30 -0
  91. package/src/components/logoButton/logo-button.scss +15 -0
  92. package/src/components/playlist/components/playlist-button.js +34 -0
  93. package/src/components/playlist/components/playlist-next-button.js +18 -0
  94. package/src/components/playlist/components/playlist-previous-button.js +18 -0
  95. package/src/components/playlist/components/playlist.js +5 -0
  96. package/src/components/playlist/components/playlist.scss +15 -0
  97. package/src/components/playlist/components/upcoming-video-overlay.js +149 -0
  98. package/src/components/playlist/components/upcoming-video-overlay.scss +86 -0
  99. package/src/components/playlist/layout/playlist-layout-custom.js +21 -0
  100. package/src/components/playlist/layout/playlist-layout-horizontal.js +16 -0
  101. package/src/components/playlist/layout/playlist-layout-vertical.js +19 -0
  102. package/src/components/playlist/layout/playlist-layout.js +110 -0
  103. package/src/components/playlist/panel/playlist-panel-item.js +86 -0
  104. package/src/components/playlist/panel/playlist-panel.js +92 -0
  105. package/src/components/playlist/playlist-widget.js +119 -0
  106. package/src/components/playlist/playlist.const.js +14 -0
  107. package/src/components/playlist/playlist.js +413 -0
  108. package/src/components/playlist/thumbnail/thumbnail.js +69 -0
  109. package/src/components/progress-control-events-blocker/progress-control-events-blocker.js +17 -0
  110. package/src/components/qualitySelector/quality-selector.scss +10 -0
  111. package/src/components/qualitySelector/qualitySelector.js +152 -0
  112. package/src/components/recommendations-overlay/index.js +3 -0
  113. package/src/components/recommendations-overlay/recommendations-overlay-content.js +57 -0
  114. package/src/components/recommendations-overlay/recommendations-overlay-hide-button.js +18 -0
  115. package/src/components/recommendations-overlay/recommendations-overlay-item.js +35 -0
  116. package/src/components/recommendations-overlay/recommendations-overlay-primary-item.js +81 -0
  117. package/src/components/recommendations-overlay/recommendations-overlay-secondary-item.js +48 -0
  118. package/src/components/recommendations-overlay/recommendations-overlay-secondary-items-container.js +35 -0
  119. package/src/components/recommendations-overlay/recommendations-overlay.js +94 -0
  120. package/src/components/recommendations-overlay/recommendations-overlay.scss +182 -0
  121. package/src/components/shoppable-bar/layout/bar-layout.js +111 -0
  122. package/src/components/shoppable-bar/layout/shoppable-panel-toggle.js +64 -0
  123. package/src/components/shoppable-bar/layout/shoppable-products-overlay.js +87 -0
  124. package/src/components/shoppable-bar/panel/shoppable-panel-item.js +105 -0
  125. package/src/components/shoppable-bar/panel/shoppable-panel.js +172 -0
  126. package/src/components/shoppable-bar/shoppable-post-widget.js +110 -0
  127. package/src/components/shoppable-bar/shoppable-widget.const.js +52 -0
  128. package/src/components/shoppable-bar/shoppable-widget.js +111 -0
  129. package/src/components/shoppable-bar/shoppable-widget.scss +359 -0
  130. package/src/components/themeButton/themedButton.const.js +3 -0
  131. package/src/components/themeButton/themedButton.js +25 -0
  132. package/src/components/title-bar/title-bar.js +79 -0
  133. package/src/config/defaults.js +25 -0
  134. package/src/extended-events.js +228 -0
  135. package/src/index.js +18 -0
  136. package/src/mixins/eventable.js +54 -0
  137. package/src/mixins/playlistable.js +106 -0
  138. package/src/plugins/analytics/index.js +245 -0
  139. package/src/plugins/autoplay-on-scroll/index.js +86 -0
  140. package/src/plugins/cloudinary/common.js +216 -0
  141. package/src/plugins/cloudinary/event-handler-registry.js +46 -0
  142. package/src/plugins/cloudinary/index.js +345 -0
  143. package/src/plugins/cloudinary/models/audio-source/audio-source.const.js +11 -0
  144. package/src/plugins/cloudinary/models/audio-source/audio-source.js +82 -0
  145. package/src/plugins/cloudinary/models/base-source.js +107 -0
  146. package/src/plugins/cloudinary/models/image-source.js +26 -0
  147. package/src/plugins/cloudinary/models/video-source/video-source.const.js +32 -0
  148. package/src/plugins/cloudinary/models/video-source/video-source.js +239 -0
  149. package/src/plugins/cloudinary/models/video-source/video-source.utils.js +57 -0
  150. package/src/plugins/colors/index.js +303 -0
  151. package/src/plugins/context-menu/components/context-menu-item.js +12 -0
  152. package/src/plugins/context-menu/components/context-menu.js +63 -0
  153. package/src/plugins/context-menu/context-menu.scss +30 -0
  154. package/src/plugins/context-menu/contextMenuContent.js +53 -0
  155. package/src/plugins/context-menu/index.js +134 -0
  156. package/src/plugins/dash/index.js +26 -0
  157. package/src/plugins/dash/setup-audio-tracks.js +112 -0
  158. package/src/plugins/dash/setup-text-tracks.js +195 -0
  159. package/src/plugins/dash/videojs-dash.js +372 -0
  160. package/src/plugins/floating-player/floating-player.scss +74 -0
  161. package/src/plugins/floating-player/index.js +129 -0
  162. package/src/plugins/ima/index.js +1775 -0
  163. package/src/plugins/index.js +31 -0
  164. package/src/plugins/interactive-plugin/index.js +10 -0
  165. package/src/plugins/videojs-http-source-selector/components/SourceMenuButton.js +98 -0
  166. package/src/plugins/videojs-http-source-selector/components/SourceMenuItem.js +52 -0
  167. package/src/plugins/videojs-http-source-selector/plugin.js +82 -0
  168. package/src/plugins/videojs-http-source-selector/plugin.scss +9 -0
  169. package/src/plugins/vtt-thumbnails/index.js +526 -0
  170. package/src/plugins/vtt-thumbnails/vtt-thumbnails.scss +29 -0
  171. package/src/utils/api.js +32 -0
  172. package/src/utils/apply-with-props.js +32 -0
  173. package/src/utils/array.js +22 -0
  174. package/src/utils/assign.js +27 -0
  175. package/src/utils/attributes-normalizer.js +72 -0
  176. package/src/utils/cloudinary.js +165 -0
  177. package/src/utils/css-prefix.js +43 -0
  178. package/src/utils/dom.js +74 -0
  179. package/src/utils/find.js +28 -0
  180. package/src/utils/fontFace.js +25 -0
  181. package/src/utils/groupBy.js +12 -0
  182. package/src/utils/index.js +29 -0
  183. package/src/utils/matches.js +11 -0
  184. package/src/utils/mixin.js +5 -0
  185. package/src/utils/object.js +26 -0
  186. package/src/utils/playButton.js +9 -0
  187. package/src/utils/positioning.js +78 -0
  188. package/src/utils/querystring.js +12 -0
  189. package/src/utils/slicing.js +21 -0
  190. package/src/utils/string.js +15 -0
  191. package/src/utils/throttle.js +30 -0
  192. package/src/utils/time.js +77 -0
  193. package/src/utils/type-inference.js +35 -0
  194. package/src/validators/validators-functions.js +48 -0
  195. package/src/validators/validators-types.js +78 -0
  196. package/src/validators/validators.js +110 -0
  197. package/src/video-player.const.js +68 -0
  198. package/src/video-player.js +761 -0
  199. package/src/video-player.utils.js +123 -0
  200. package/test/adaptive-streaming.test.js +38 -0
  201. package/test/ads.test.js +35 -0
  202. package/test/analytics.test.js +111 -0
  203. package/test/api.test.js +111 -0
  204. package/test/autoplay.scroll.test.js +23 -0
  205. package/test/basic-ui.test.js +59 -0
  206. package/test/colors.test.js +58 -0
  207. package/test/components.test.js +21 -0
  208. package/test/custom-error.test.js +24 -0
  209. package/test/fluid.test.js +36 -0
  210. package/test/isValidConfig.test.js +224 -0
  211. package/test/mocks/cloudinary-core-mock.js +0 -0
  212. package/test/mocks/styleMock.js +1 -0
  213. package/test/multiplayer.test.js +25 -0
  214. package/test/playlist.test.js +60 -0
  215. package/test/puppeteer/vp-env.js +19 -0
  216. package/test/recommendations.test.js +38 -0
  217. package/test/title-bar.test.js +28 -0
  218. package/test/ui-conf.test.js +49 -0
  219. package/test/unit/cloudinaryConfig.test.js +22 -0
  220. package/test/unit/cloudinaryUtils.test.js +53 -0
  221. package/test/unit/utils.test.js +27 -0
  222. package/test/unit/videoSource.test.js +454 -0
  223. package/tsconfig.json +15 -0
  224. package/types/video-player-tests.js +12 -0
  225. package/types/video-player-tests.ts +31 -0
  226. package/types/video-player.d.ts +570 -0
@@ -0,0 +1,57 @@
1
+ import videojs from 'video.js';
2
+
3
+ import RecommendationsOverlayPrimaryItem from './recommendations-overlay-primary-item';
4
+ import RecommendationsOverlaySecondaryItemsContainer from './recommendations-overlay-secondary-items-container';
5
+
6
+ const Component = videojs.getComponent('Component');
7
+
8
+ class RecommendationsOverlayContent extends Component {
9
+
10
+ constructor(player, ...args) {
11
+ super(player, ...args);
12
+
13
+ this._content = new AspectRatioContent(player);
14
+ this.addChild(this._content);
15
+ }
16
+
17
+ setItems(primary, ...secondary) {
18
+ this._content.setItems(primary, ...secondary);
19
+ }
20
+
21
+ clearItems() {
22
+ this._content._primary.clearItem();
23
+ this._content._secondaryContainer.clearItems();
24
+ }
25
+
26
+ createEl() {
27
+ return super.createEl('div', {
28
+ className: 'vjs-recommendations-overlay-content'
29
+ });
30
+ }
31
+ }
32
+
33
+ class AspectRatioContent extends Component {
34
+
35
+ constructor(player, ...args) {
36
+ super(player, ...args);
37
+
38
+ this._primary = new RecommendationsOverlayPrimaryItem(player);
39
+ this._secondaryContainer = new RecommendationsOverlaySecondaryItemsContainer(player);
40
+
41
+ this.addChild(this._primary);
42
+ this.addChild(this._secondaryContainer);
43
+ }
44
+
45
+ setItems(primary, ...secondary) {
46
+ this._primary.setItem(primary);
47
+ this._secondaryContainer.setItems(...secondary);
48
+ }
49
+
50
+ createEl() {
51
+ return super.createEl('div', {
52
+ className: 'aspect-ratio-content'
53
+ });
54
+ }
55
+ }
56
+
57
+ export default RecommendationsOverlayContent;
@@ -0,0 +1,18 @@
1
+ import videojs from 'video.js';
2
+
3
+ const ClickableComponent = videojs.getComponent('ClickableComponent');
4
+
5
+ class RecommendationOverlayHideButton extends ClickableComponent {
6
+
7
+ createEl() {
8
+ return super.createEl('span', {
9
+ className: 'vjs-recommendations-overlay-hide vjs-icon-close'
10
+ });
11
+ }
12
+
13
+ handleClick() {
14
+ this.options_.clickHandler();
15
+ }
16
+ }
17
+
18
+ export default RecommendationOverlayHideButton;
@@ -0,0 +1,35 @@
1
+ import videojs from 'video.js';
2
+
3
+ const ClickableComponent = videojs.getComponent('ClickableComponent');
4
+
5
+ class RecommendationsOverlayItem extends ClickableComponent {
6
+
7
+ setItem(item) {
8
+ const { action, source } = item;
9
+ this.source = source;
10
+
11
+ const info = source.info();
12
+
13
+ this.setTitle(info.title || source.publicId());
14
+
15
+ this.setPoster(this.source.poster().url({ transformation: { aspect_ratio: '16:9', crop: 'pad', background: 'black' } }));
16
+
17
+ this.setAction(action);
18
+ }
19
+
20
+ setTitle(text) {
21
+ this.title.innerText = text;
22
+ }
23
+
24
+ setAction(action) {
25
+ this.action = action;
26
+ }
27
+
28
+ handleClick() {
29
+ super.handleClick();
30
+ this.player().trigger('recommendationshide');
31
+ this.action();
32
+ }
33
+ }
34
+
35
+ export default RecommendationsOverlayItem;
@@ -0,0 +1,81 @@
1
+ import videojs from 'video.js';
2
+ import RecommendationsOverlayItem from './recommendations-overlay-item';
3
+ import componentUtils from '../component-utils';
4
+
5
+ // support VJS5 & VJS6 at the same time
6
+ const dom = videojs.dom || videojs;
7
+
8
+ class RecommendationsOverlayPrimaryItem extends RecommendationsOverlayItem {
9
+
10
+ setItem(item) {
11
+ super.setItem(item);
12
+
13
+ const info = this.source.info();
14
+
15
+ this.setTitle(info.title);
16
+ this.setSubtitle(info.subtitle);
17
+
18
+ if (info.description) {
19
+ const descLength = 300;
20
+ const description = info.description.length > descLength ? info.description.substring(0, descLength) + '...' : info.description;
21
+ this.setDescription(description);
22
+ }
23
+ }
24
+
25
+ setPoster(url) {
26
+ this.poster.style.backgroundImage = `url('${url}')`;
27
+ }
28
+
29
+ setTitle(text) {
30
+ componentUtils.setText(this.title, text);
31
+ }
32
+
33
+ setSubtitle(text) {
34
+ componentUtils.setText(this.subtitle, text);
35
+ }
36
+
37
+ setDescription(text) {
38
+ componentUtils.setText(this.description, text);
39
+ }
40
+
41
+ clearItem() {
42
+ this.setTitle('');
43
+ this.setSubtitle('');
44
+ this.setDescription('');
45
+ this.poster.style.backgroundImage = null;
46
+ }
47
+
48
+ createEl() {
49
+ const el = super.createEl('div', {
50
+ className: 'vjs-recommendations-overlay-item vjs-recommendations-overlay-item-primary'
51
+ });
52
+
53
+ this.poster = dom.createEl('div', {
54
+ className: 'vjs-recommendations-overlay-item-primary-image'
55
+ });
56
+
57
+ this.title = dom.createEl('h2');
58
+ this.title.innerHTML = '';
59
+
60
+ this.subtitle = dom.createEl('h3');
61
+ this.subtitle.innerHTML = '';
62
+
63
+ this.description = dom.createEl('p');
64
+ this.description.innerHTML = '';
65
+
66
+ this.content = dom.createEl('div', {
67
+ className: 'vjs-recommendations-overlay-item-info vjs-recommendations-overlay-item-primary-content'
68
+ });
69
+
70
+ this.content.appendChild(this.title);
71
+ this.content.appendChild(this.subtitle);
72
+ this.content.appendChild(this.description);
73
+
74
+ el.appendChild(this.poster);
75
+ el.appendChild(this.content);
76
+
77
+ return el;
78
+ }
79
+ }
80
+
81
+ export default RecommendationsOverlayPrimaryItem;
@@ -0,0 +1,48 @@
1
+ import videojs from 'video.js';
2
+ import RecommendationsOverlayItem from './recommendations-overlay-item';
3
+
4
+ // support VJS5 & VJS6 at the same time
5
+ const dom = videojs.dom || videojs;
6
+
7
+ class RecommendationsOverlaySecondaryItem extends RecommendationsOverlayItem {
8
+
9
+ setItem(item) {
10
+ super.setItem(item);
11
+ this.setDuration('');
12
+ }
13
+
14
+ setPoster(url) {
15
+ this.el().style.backgroundImage = `url('${url}')`;
16
+ }
17
+
18
+ setDuration(text) {
19
+ this.duration.innerText = text;
20
+ }
21
+
22
+ createEl() {
23
+ const el = super.createEl('div', {
24
+ className: 'vjs-recommendations-overlay-item vjs-recommendations-overlay-item-secondary'
25
+ });
26
+
27
+ this.title = dom.createEl('span', { className: 'vjs-recommendations-overlay-item-secondary-title' });
28
+ this.title.innerHTML = '';
29
+
30
+ this.duration = dom.createEl('span', { className: 'vjs-recommendations-overlay-item-secondary-duration' });
31
+ this.duration.innerHTML = '';
32
+
33
+ const caption = dom.createEl('div', { className: 'vjs-recommendations-overlay-item-info' });
34
+ caption.appendChild(this.title);
35
+ caption.appendChild(this.duration);
36
+
37
+ el.appendChild(caption);
38
+
39
+ return el;
40
+ }
41
+
42
+ handleClick() {
43
+ super.handleClick();
44
+ this.action();
45
+ }
46
+ }
47
+
48
+ export default RecommendationsOverlaySecondaryItem;
@@ -0,0 +1,35 @@
1
+ import videojs from 'video.js';
2
+ import RecommendationsOverlaySecondaryItem from './recommendations-overlay-secondary-item';
3
+
4
+ const Component = videojs.getComponent('Component');
5
+
6
+ class RecommendationsOverlaySecondaryItemsContainer extends Component {
7
+
8
+ setItems(...items) {
9
+ this.clearItems();
10
+
11
+ if (!items) {
12
+ return;
13
+ }
14
+
15
+ items.forEach((item) => {
16
+ const component = new RecommendationsOverlaySecondaryItem(this.player());
17
+ component.setItem(item);
18
+ this.addChild(component);
19
+ });
20
+ }
21
+
22
+ clearItems() {
23
+ this.children().forEach(() => {
24
+ this.removeChild(this.children()[0]);
25
+ });
26
+ }
27
+
28
+ createEl() {
29
+ return super.createEl('div', {
30
+ className: 'vjs-recommendations-overlay-item-secondary-container'
31
+ });
32
+ }
33
+ }
34
+
35
+ export default RecommendationsOverlaySecondaryItemsContainer;
@@ -0,0 +1,94 @@
1
+ import videojs from 'video.js';
2
+ import RecommendationsOverlayContent from './recommendations-overlay-content';
3
+ import RecommendationsOverlayHideButton from './recommendations-overlay-hide-button';
4
+ import './recommendations-overlay.scss';
5
+
6
+ const MAXIMUM_ITEMS = 4;
7
+ const Component = videojs.getComponent('Component');
8
+
9
+ // TODO: Use Video.js's ModalDialog instead. It handles clicking block logic.
10
+ class RecommendationsOverlay extends Component {
11
+
12
+ constructor(player, options, ...args) {
13
+ super(player, ...args);
14
+
15
+ this._content = new RecommendationsOverlayContent(player);
16
+
17
+ this.addChild(this._content);
18
+
19
+ this.addChild(new RecommendationsOverlayHideButton(player, { clickHandler: () => {
20
+ this.close();
21
+ } }, ...args));
22
+
23
+ this.setEvents(player);
24
+
25
+ this.doNotOpen = false;
26
+ }
27
+
28
+ setEvents(player) {
29
+ this.on(player, 'recommendationschanged', (_, eventData) => {
30
+ this.setItems(...eventData.items);
31
+ });
32
+
33
+ this.on(player, 'recommendationsnoshow', this.setDoNotOpen);
34
+ this.on(player, 'recommendationsshow', this.open);
35
+ this.on(player, 'recommendationshide', this.close);
36
+ this.on(player, 'cldsourcechanged', () => {
37
+ this.clearItems();
38
+ this.close();
39
+ });
40
+ }
41
+
42
+ setDoNotOpen() {
43
+ this.doNotOpen = true;
44
+ }
45
+
46
+ open() {
47
+ if (!this.doNotOpen) {
48
+ // Only show controls on close if they were visible from the first place
49
+ this._showControlsOnClose = this.player().controls();
50
+ this.player().controls(false);
51
+ this.el().style.visibility = 'visible';
52
+ }
53
+ }
54
+
55
+ clearItems() {
56
+ this._content.clearItems();
57
+ }
58
+
59
+ close() {
60
+ this.el().style.visibility = 'hidden';
61
+ if (this._showControlsOnClose) {
62
+ this.player().controls(true);
63
+ }
64
+ }
65
+
66
+ createEl() {
67
+ const recommendationsOverlayClass = 'vjs-recommendations-overlay';
68
+
69
+ const el = super.createEl('div', {
70
+ className: recommendationsOverlayClass
71
+ });
72
+ videojs.dom.addClass(el, recommendationsOverlayClass);
73
+
74
+ return el;
75
+ }
76
+
77
+ setItems(primary, ...secondary) {
78
+ this.doNotOpen = false;
79
+ secondary = secondary.slice(0, MAXIMUM_ITEMS - 1);
80
+ this._content.setItems(primary, ...secondary);
81
+ }
82
+
83
+ handleClick() {
84
+ this.stopPropagation();
85
+ }
86
+
87
+ dispose() {
88
+ super.dispose();
89
+ }
90
+ }
91
+
92
+ videojs.registerComponent('recommendationsOverlay', RecommendationsOverlay);
93
+
94
+ export default RecommendationsOverlay;
@@ -0,0 +1,182 @@
1
+ @import '../../assets/styles/mixins/aspect-ratio';
2
+ @import '../../assets/styles/mixins/mixins.scss';
3
+
4
+ .vjs-recommendations-overlay {
5
+ display: flex;
6
+ align-items: center;
7
+ justify-content: center;
8
+
9
+ visibility: hidden;
10
+ position: absolute;
11
+ top: 0px;
12
+ left: 0px;
13
+ width: 100%;
14
+ height: 100%;
15
+ background-color: rgba(#000000, 0.5);
16
+
17
+ .vjs-recommendations-overlay-hide {
18
+ font-size: 1em;
19
+ cursor: pointer;
20
+ position: absolute;
21
+ display: inline-block;
22
+ top: 3.75%;
23
+ right: 1.72%;
24
+ }
25
+
26
+ .vjs-recommendations-overlay-content {
27
+ position: relative;
28
+ width: 85%;
29
+
30
+ @include aspect-ratio(16, 9);
31
+
32
+ .aspect-ratio-content {
33
+ display: flex;
34
+ flex-flow: column;
35
+
36
+ height: auto;
37
+
38
+ .vjs-recommendations-overlay-item {
39
+ border: 1px solid rgba(#FFFFFF, 0.5);
40
+ }
41
+
42
+ .vjs-recommendations-overlay-item-primary {
43
+ flex: 1.82;
44
+ display: flex;
45
+ flex-flow: row;
46
+
47
+ .vjs-recommendations-overlay-item-primary-image {
48
+ flex: 1;
49
+ background-size: cover;
50
+ }
51
+
52
+ .vjs-recommendations-overlay-item-primary-content {
53
+ flex: 0.5625;
54
+ display: flex;
55
+ flex-flow: column;
56
+
57
+ background: rgba(#000000, 0.6);
58
+ text-align: left;
59
+ padding: 3%;
60
+ min-width: 0; // for use with flex and white-space: nowrap
61
+
62
+ h2 {
63
+ @include ellipsis;
64
+ padding: 0 0 0 0;
65
+ font-size: 18px;
66
+ margin: 0 0 1em 0;
67
+ font-weight: 600;
68
+ }
69
+
70
+ h3 {
71
+ @include ellipsis;
72
+ padding: 0 0 0 0;
73
+ font-size: 20px;
74
+ margin: 0 0 1.3em 0;
75
+ font-weight: 500;
76
+ }
77
+
78
+ p {
79
+ padding: 0 0 0 0;
80
+ margin: 0 0 0 0;
81
+ font-size: 14px;
82
+ overflow: hidden;
83
+ line-height: 1.4em;
84
+ font-weight: 400;
85
+ }
86
+
87
+ @media only screen and (max-width: 1050px) {
88
+ h2 {
89
+ font-size: 16px
90
+ }
91
+
92
+ h3 {
93
+ font-size: 18px;
94
+ }
95
+
96
+ p {
97
+ font-size: 12px;
98
+ }
99
+ }
100
+
101
+ @media only screen and (max-width: 900px) {
102
+ p {
103
+ font-size: 10px;
104
+ }
105
+ }
106
+
107
+ @media only screen and (max-width: 768px) {
108
+ p {
109
+ display: none;
110
+ }
111
+ }
112
+ }
113
+ }
114
+
115
+ .vjs-recommendations-overlay-item-secondary-container {
116
+ flex: 1;
117
+ display: flex;
118
+ flex-flow: row wrap;
119
+ justify-content: flex-start;
120
+
121
+ .vjs-recommendations-overlay-item-secondary {
122
+ background-size: 100% 100%;
123
+ flex: 1;
124
+
125
+ max-width: 33%;
126
+
127
+ font-size: 1.16em;
128
+ position: relative;
129
+
130
+ margin: 2% 2% 0 0;
131
+
132
+ &:last-child {
133
+ margin-right: 0;
134
+ }
135
+
136
+ div {
137
+ display: flex;
138
+ flex-direction: row;
139
+ justify-content: space-between;
140
+
141
+ text-align: left;
142
+ line-height: normal;
143
+ position: absolute;
144
+ width: 100%;
145
+ bottom: 0;
146
+ left: 0;
147
+ padding: 20% 7% 4.5% 7%;
148
+
149
+ .cld-video-player-skin-light & {
150
+ padding: 5% 7%;
151
+ }
152
+
153
+ .cld-video-player-skin-dark & {
154
+
155
+ &.vjs-recommendations-overlay-item-info {
156
+ text-shadow: 1px 1px 0 rgba(#000, .3);
157
+ }
158
+ }
159
+
160
+ span {
161
+ display: block;
162
+ min-width: 0;
163
+ text-overflow: ellipsis;
164
+ overflow: hidden;
165
+ white-space: nowrap;
166
+
167
+ &.vjs-recommendations-overlay-item-secondary-title {
168
+ flex: 2.3;
169
+ font-size: 13px;
170
+ }
171
+
172
+ &.vjs-recommendations-overlay-item-secondary-duration {
173
+ text-align: right;
174
+ margin-left: 10px;
175
+ }
176
+ }
177
+ }
178
+ }
179
+ }
180
+ }
181
+ }
182
+ }
@@ -0,0 +1,111 @@
1
+
2
+ import videojs from 'video.js';
3
+ import { elMatches } from 'utils/matches';
4
+
5
+ const dom = videojs.dom || videojs;
6
+ const Component = videojs.getComponent('Component');
7
+ import ShoppableProductsOverlay from './shoppable-products-overlay';
8
+ import ShoppablePanelToggle from './shoppable-panel-toggle';
9
+ import {
10
+ CLD_SPBL_INNER_BAR,
11
+ SHOPPABLE_PANEL_HIDDEN_CLASS,
12
+ SHOPPABLE_PANEL_VISIBLE_CLASS
13
+ } from '../shoppable-widget.const';
14
+
15
+ class ShoppableBarLayout extends Component {
16
+ constructor(player, options) {
17
+ super(player, options);
18
+ this.player_ = player;
19
+
20
+ this.player().addClass('cld-shoppable-panel');
21
+ this.player().addClass(SHOPPABLE_PANEL_HIDDEN_CLASS);
22
+
23
+ this.contentWrpEl_ = dom.createEl('div', { className: 'cld-spbl-bar' });
24
+
25
+ this.contentBannerEl_ = dom.createEl('div', { className: 'cld-spbl-banner-msg base-color-text' }, {}, this.options_.bannerMsg || 'Shop the Video');
26
+ this.contentWrpEl_.appendChild(this.contentBannerEl_);
27
+
28
+ const productsOverlay = new ShoppableProductsOverlay(this.player_, this.options_);
29
+ this.contentWrpEl_.appendChild(productsOverlay.el_);
30
+
31
+ this.contentEl_ = dom.createEl('div', { className: CLD_SPBL_INNER_BAR });
32
+ this.contentWrpEl_.appendChild(this.contentEl_);
33
+
34
+ this.player().el().appendChild(this.contentWrpEl_);
35
+
36
+ this.addChild(new ShoppablePanelToggle(this.player_, {
37
+ toggleIcon: this.options_.toggleIcon,
38
+ clickHandler: () => {
39
+ this.togglePanel();
40
+ }
41
+ }));
42
+
43
+ this.addChild('ShoppablePanel', this.options_);
44
+
45
+ this.dispose = () => {
46
+ this.removeLayout();
47
+ super.dispose();
48
+ };
49
+
50
+ this.togglePanel = (open) => {
51
+ if (open === true) {
52
+ // Open
53
+ this.player().removeClass(SHOPPABLE_PANEL_HIDDEN_CLASS);
54
+ this.player().addClass(SHOPPABLE_PANEL_VISIBLE_CLASS);
55
+ } else if (open === false) {
56
+ // Close
57
+ this.player().removeClass(SHOPPABLE_PANEL_VISIBLE_CLASS);
58
+ this.player().addClass(SHOPPABLE_PANEL_HIDDEN_CLASS);
59
+ } else {
60
+ // Toggle
61
+ this.player().toggleClass(SHOPPABLE_PANEL_HIDDEN_CLASS);
62
+ this.player().toggleClass(SHOPPABLE_PANEL_VISIBLE_CLASS);
63
+ }
64
+ let eventName = this.player().hasClass(SHOPPABLE_PANEL_VISIBLE_CLASS) ? 'productBarMax' : 'productBarMin';
65
+ this.player().trigger(eventName);
66
+ };
67
+
68
+ // Open shoppable
69
+ if (this.options_.startState === 'open') {
70
+ this.togglePanel(true);
71
+ }
72
+
73
+ // On play start
74
+ this.player_.on('play', () => {
75
+ if (this.player_.currentTime() < 0.01) {
76
+
77
+ // Open shoppable on-play
78
+ if (this.options_.startState === 'openOnPlay') {
79
+ this.togglePanel(true, this.options_.autoClose);
80
+ }
81
+
82
+ // Auto-close shoppable
83
+ if (this.options_.autoClose && this.options_.startState.indexOf('open') !== -1) {
84
+ setTimeout(() => {
85
+ // Keep it open while hovered
86
+ if (!elMatches(this.contentEl_, ':hover')) {
87
+ this.togglePanel(false);
88
+ } else {
89
+ this.contentEl_.addEventListener('mouseleave', () => {
90
+ this.togglePanel(false);
91
+ }, { once: true });
92
+ }
93
+ }, this.options_.autoClose * 1000);
94
+ }
95
+
96
+ }
97
+
98
+ });
99
+ }
100
+
101
+ createEl() {
102
+ const el = super.createEl('div');
103
+
104
+ return el;
105
+ }
106
+
107
+ }
108
+
109
+ videojs.registerComponent('shoppableBarLayout', ShoppableBarLayout);
110
+
111
+ export default ShoppableBarLayout;