ravnur-player-public 3.4.2 → 3.4.4

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 (262) hide show
  1. package/.eslintignore +7 -0
  2. package/.eslintrc.js +206 -0
  3. package/.flowconfig +3 -0
  4. package/.vscode/extensions.json +7 -0
  5. package/.vscode/launch.json +37 -0
  6. package/.vscode/settings.json +4 -0
  7. package/README-Private.md +54 -0
  8. package/babel.config.js +28 -0
  9. package/bitbucket-pipelines.yml +61 -0
  10. package/cert.pem +23 -0
  11. package/demo/BaseM.mp4 +0 -0
  12. package/demo/HD.mp4 +0 -0
  13. package/demo/annotations.json +50 -0
  14. package/demo/annotations_ge.json +50 -0
  15. package/demo/base.mp3 +0 -0
  16. package/demo/cc_2125en.vtt +4958 -0
  17. package/demo/cc_en.vtt +171 -0
  18. package/demo/cc_ge.vtt +178 -0
  19. package/demo/chapters_en.vtt +38 -0
  20. package/demo/chapters_ge.vtt +5 -0
  21. package/demo/chapters_ge1.json +23 -0
  22. package/demo/hls/audio/stereo/en/128kbit.m3u8 +912 -0
  23. package/demo/hls/audio/stereo/none/128kbit.m3u8 +912 -0
  24. package/demo/hls/audio/surround/en/320kbit.m3u8 +912 -0
  25. package/demo/hls/playlist.m3u8 +31 -0
  26. package/demo/hls/video/10000kbit.m3u8 +894 -0
  27. package/demo/hls/video/1100kbit.m3u8 +894 -0
  28. package/demo/hls/video/1500kbit.m3u8 +894 -0
  29. package/demo/hls/video/250kbit.m3u8 +894 -0
  30. package/demo/hls/video/4000kbit.m3u8 +894 -0
  31. package/demo/hls/video/500kbit.m3u8 +894 -0
  32. package/demo/hls/video/6000kbit.m3u8 +894 -0
  33. package/demo/hls/video/800kbit.m3u8 +894 -0
  34. package/demo/hls.js +5 -0
  35. package/demo/hls.js.map +1 -0
  36. package/demo/hls.min.js +2 -0
  37. package/demo/hls.min.js.map +1 -0
  38. package/demo/playlist.m3u8 +31 -0
  39. package/demo/ravnur-flash-audio.swf +0 -0
  40. package/demo/ravnur-flash-video-hls.swf +0 -0
  41. package/demo/ravnur-flash-video.swf +0 -0
  42. package/demo/shaka/shaka-player.foo.debug.d.ts +4532 -0
  43. package/demo/shaka/shaka-player.foo.debug.externs.js +3886 -0
  44. package/demo/shaka/shaka-player.foo.debug.js +1746 -0
  45. package/demo/shaka/shaka-player.foo.debug.map +8 -0
  46. package/demo/shaka/wrapper.js +7 -0
  47. package/demo/test.html +458 -0
  48. package/dist/RavnurMediaPlayer.min.js +1 -1
  49. package/dist/cdn/RavnurMediaPlayer.min.js +1 -1
  50. package/jest.config.js +4 -0
  51. package/key.pem +27 -0
  52. package/lib/es5.js +344 -0
  53. package/lib/images/Spinner-small.gif +0 -0
  54. package/lib/images/close.png +0 -0
  55. package/lib/images/ic_check_box_black_24dp_1x.png +0 -0
  56. package/lib/images/ic_check_box_outline_blank_black_24dp_1x.png +0 -0
  57. package/lib/images/ic_chevron_left_white_24dp_1x.png +0 -0
  58. package/lib/images/ic_chevron_right_white_24dp_1x.png +0 -0
  59. package/lib/images/ic_closed_caption_white_24dp_1x.png +0 -0
  60. package/lib/images/ic_fast_forward_white_24dp_1x.png +0 -0
  61. package/lib/images/ic_fast_rewind_white_24dp_1x.png +0 -0
  62. package/lib/images/ic_fullscreen_exit_white_24dp_1x.png +0 -0
  63. package/lib/images/ic_fullscreen_white_24dp_1x.png +0 -0
  64. package/lib/images/ic_hd_white_24dp_1x.png +0 -0
  65. package/lib/images/ic_keyboard_arrow_left_black_24dp_1x.png +0 -0
  66. package/lib/images/ic_keyboard_arrow_right_black_24dp_1x.png +0 -0
  67. package/lib/images/ic_pause_white_24dp_1x.png +0 -0
  68. package/lib/images/ic_photo_white_24dp_1x.png +0 -0
  69. package/lib/images/ic_play_arrow_white_24dp_1x.png +0 -0
  70. package/lib/images/ic_refresh_white_24dp_1x.png +0 -0
  71. package/lib/images/ic_settings_white_24dp_1x.png +0 -0
  72. package/lib/images/ic_skip_next_white_24dp_1x.png +0 -0
  73. package/lib/images/ic_skip_previous_white_24dp_1x.png +0 -0
  74. package/lib/images/ic_toc_white_24dp_1x.png +0 -0
  75. package/lib/images/ic_volume_off_white_24dp_1x.png +0 -0
  76. package/lib/images/ic_volume_up_white_24dp_1x.png +0 -0
  77. package/lib/player4ie8.css +225 -0
  78. package/package.json +1 -5
  79. package/server.js +29 -0
  80. package/src/config/cc.js +56 -0
  81. package/src/config/i18n.js +101 -0
  82. package/src/config/options.js +123 -0
  83. package/src/config/playlist.js +9 -0
  84. package/src/config/source.js +23 -0
  85. package/src/config/statuses.js +8 -0
  86. package/src/config/styles.js +16 -0
  87. package/src/entity.js +27 -0
  88. package/src/events.js +5 -0
  89. package/src/extensions/annotations.js +142 -0
  90. package/src/extensions/audio-tarcks.js +115 -0
  91. package/src/extensions/backward.js +45 -0
  92. package/src/extensions/base.js +73 -0
  93. package/src/extensions/bottom-next.js +50 -0
  94. package/src/extensions/bottom-prev.js +50 -0
  95. package/src/extensions/buffering.js +78 -0
  96. package/src/extensions/c2pa.js +350 -0
  97. package/src/extensions/caption-search.js +230 -0
  98. package/src/extensions/cc.js +874 -0
  99. package/src/extensions/crawl.js +118 -0
  100. package/src/extensions/download.js +411 -0
  101. package/src/extensions/error.js +47 -0
  102. package/src/extensions/forward.js +44 -0
  103. package/src/extensions/fullscreen.js +84 -0
  104. package/src/extensions/help.js +201 -0
  105. package/src/extensions/helpers/FileSaver.js +157 -0
  106. package/src/extensions/helpers/clickOpener.js +180 -0
  107. package/src/extensions/helpers/opener.js +30 -0
  108. package/src/extensions/helpers/openerHeightChecker.js +13 -0
  109. package/src/extensions/helpers/popover.js +33 -0
  110. package/src/extensions/helpers/popoverPosition.js +30 -0
  111. package/src/extensions/helpers/scrollIntoView.js +9 -0
  112. package/src/extensions/helpers/storage.js +20 -0
  113. package/src/extensions/helpers/textContent.js +6 -0
  114. package/src/extensions/helpers/timeCodeToSeconds.js +44 -0
  115. package/src/extensions/helpers/transport.js +43 -0
  116. package/src/extensions/helpers/vtt-loader.js +42 -0
  117. package/src/extensions/index.js +87 -0
  118. package/src/extensions/live.js +76 -0
  119. package/src/extensions/mux.js +57 -0
  120. package/src/extensions/next-frame.js +44 -0
  121. package/src/extensions/next.js +48 -0
  122. package/src/extensions/placeholder.js +241 -0
  123. package/src/extensions/play.js +102 -0
  124. package/src/extensions/poster.js +47 -0
  125. package/src/extensions/prev-frame.js +44 -0
  126. package/src/extensions/prev.js +48 -0
  127. package/src/extensions/progress.js +465 -0
  128. package/src/extensions/resizer.js +37 -0
  129. package/src/extensions/settings.js +367 -0
  130. package/src/extensions/theater.js +56 -0
  131. package/src/extensions/title.js +38 -0
  132. package/src/extensions/toc.js +334 -0
  133. package/src/extensions/volume.js +196 -0
  134. package/src/flash/FlashPlugin.js +301 -0
  135. package/src/flash/MediaElement.js +361 -0
  136. package/src/flash/plugins.js +32 -0
  137. package/src/flash-detector.js +66 -0
  138. package/src/helpers/$t.js +10 -0
  139. package/src/helpers/binder.js +11 -0
  140. package/src/helpers/isAndroid.js +5 -0
  141. package/src/helpers/isBlackBerry.js +5 -0
  142. package/src/helpers/isCanvasSupported.js +6 -0
  143. package/src/helpers/isIE.js +21 -0
  144. package/src/helpers/isMobile.js +10 -0
  145. package/src/helpers/isWindows.js +5 -0
  146. package/src/helpers/isWindowsPhone.js +5 -0
  147. package/src/helpers/isiOS.js +5 -0
  148. package/src/html5media.js +19 -0
  149. package/src/index.js +2 -0
  150. package/src/logger.js +31 -0
  151. package/src/microevent.js +65 -0
  152. package/src/normalize-options.js +139 -0
  153. package/src/player.js +864 -0
  154. package/src/players/base.js +209 -0
  155. package/src/players/flash.js +172 -0
  156. package/src/players/hls.js +278 -0
  157. package/src/players/html.js +205 -0
  158. package/src/players/index.js +59 -0
  159. package/src/players/shaka.js +219 -0
  160. package/src/playlist.js +362 -0
  161. package/src/screenfull.js +121 -0
  162. package/src/state.js +474 -0
  163. package/src/static/es5.js +344 -0
  164. package/src/static/images/Spinner-small.gif +0 -0
  165. package/src/static/images/close.png +0 -0
  166. package/src/static/images/ic_check_box_black_24dp_1x.png +0 -0
  167. package/src/static/images/ic_check_box_outline_blank_black_24dp_1x.png +0 -0
  168. package/src/static/images/ic_chevron_left_white_24dp_1x.png +0 -0
  169. package/src/static/images/ic_chevron_right_white_24dp_1x.png +0 -0
  170. package/src/static/images/ic_closed_caption_white_24dp_1x.png +0 -0
  171. package/src/static/images/ic_fast_forward_white_24dp_1x.png +0 -0
  172. package/src/static/images/ic_fast_rewind_white_24dp_1x.png +0 -0
  173. package/src/static/images/ic_fullscreen_exit_white_24dp_1x.png +0 -0
  174. package/src/static/images/ic_fullscreen_white_24dp_1x.png +0 -0
  175. package/src/static/images/ic_hd_white_24dp_1x.png +0 -0
  176. package/src/static/images/ic_keyboard_arrow_left_black_24dp_1x.png +0 -0
  177. package/src/static/images/ic_keyboard_arrow_right_black_24dp_1x.png +0 -0
  178. package/src/static/images/ic_pause_white_24dp_1x.png +0 -0
  179. package/src/static/images/ic_play_arrow_white_24dp_1x.png +0 -0
  180. package/src/static/images/ic_refresh_white_24dp_1x.png +0 -0
  181. package/src/static/images/ic_settings_white_24dp_1x.png +0 -0
  182. package/src/static/images/ic_skip_next_white_24dp_1x.png +0 -0
  183. package/src/static/images/ic_skip_previous_white_24dp_1x.png +0 -0
  184. package/src/static/images/ic_toc_white_24dp_1x.png +0 -0
  185. package/src/static/images/ic_volume_off_white_24dp_1x.png +0 -0
  186. package/src/static/images/ic_volume_up_white_24dp_1x.png +0 -0
  187. package/src/static/player4ie8.css +225 -0
  188. package/src/styles/bplaylist.css.js +124 -0
  189. package/src/styles/index.js +1966 -0
  190. package/src/styles/playlist.css.js +84 -0
  191. package/src/styles/rplaylist.css.js +98 -0
  192. package/src/svgs.js +111 -0
  193. package/src/types/Logger.js +10 -0
  194. package/src/types/Options.js +179 -0
  195. package/src/types/Playlist.js +3 -0
  196. package/src/types/Source.js +28 -0
  197. package/src/types/State.js +46 -0
  198. package/src/types/Styles.js +11 -0
  199. package/src/types/TimeData.js +8 -0
  200. package/src/types/Translation.js +69 -0
  201. package/src/utils/absolutizeUrl.js +9 -0
  202. package/src/utils/addClass.js +9 -0
  203. package/src/utils/addEvent.js +31 -0
  204. package/src/utils/addProperty.js +65 -0
  205. package/src/utils/appendChild.js +14 -0
  206. package/src/utils/buff2hex.js +5 -0
  207. package/src/utils/contains.js +33 -0
  208. package/src/utils/createElement.js +24 -0
  209. package/src/utils/each.js +34 -0
  210. package/src/utils/escapeHTML.js +8 -0
  211. package/src/utils/existy.js +4 -0
  212. package/src/utils/extend.js +17 -0
  213. package/src/utils/filter.js +16 -0
  214. package/src/utils/find.js +11 -0
  215. package/src/utils/findIndex.js +20 -0
  216. package/src/utils/first.js +5 -0
  217. package/src/utils/get.js +19 -0
  218. package/src/utils/has.js +5 -0
  219. package/src/utils/hasClass.js +6 -0
  220. package/src/utils/head.js +11 -0
  221. package/src/utils/inRange.js +16 -0
  222. package/src/utils/index.js +73 -0
  223. package/src/utils/isArray.js +4 -0
  224. package/src/utils/isBoolean.js +3 -0
  225. package/src/utils/isElement.js +7 -0
  226. package/src/utils/isEmpty.js +6 -0
  227. package/src/utils/isEqual.js +33 -0
  228. package/src/utils/isEqualBuffer.js +13 -0
  229. package/src/utils/isFunction.js +3 -0
  230. package/src/utils/isNotEmpty.js +5 -0
  231. package/src/utils/isObject.js +5 -0
  232. package/src/utils/isString.js +9 -0
  233. package/src/utils/last.js +4 -0
  234. package/src/utils/map.js +11 -0
  235. package/src/utils/negate.js +8 -0
  236. package/src/utils/noop.js +1 -0
  237. package/src/utils/notExisty.js +5 -0
  238. package/src/utils/reduce.js +8 -0
  239. package/src/utils/remove.js +7 -0
  240. package/src/utils/removeClass.js +8 -0
  241. package/src/utils/removeEvent.js +7 -0
  242. package/src/utils/toArray.js +7 -0
  243. package/src/utils/toggleClass.js +16 -0
  244. package/src/utils/uidGenerator.js +8 -0
  245. package/src/utils/upperFirst.js +4 -0
  246. package/tests/extensions/__snapshots__/download.spec.js.snap +226 -0
  247. package/tests/extensions/__snapshots__/fullscreen.spec.js.snap +30 -0
  248. package/tests/extensions/__snapshots__/title.spec.js.snap +16 -0
  249. package/tests/extensions/download.spec.js +111 -0
  250. package/tests/extensions/fullscreen.spec.js +56 -0
  251. package/tests/extensions/title.spec.js +35 -0
  252. package/tests/mocks/assets/BaseM.mp4 +0 -0
  253. package/tests/mocks/assets/hls.min.js +5 -0
  254. package/tests/mocks/assets/styleMock.js +1 -0
  255. package/tests/mocks/base-player-options.js +47 -0
  256. package/tests/mocks/sources.js +58 -0
  257. package/tests/mocks/timedata/cc_en.vtt +171 -0
  258. package/tests/mocks/timedata/cc_ge.vtt +178 -0
  259. package/tests/utils/wait.js +1 -0
  260. package/webpack.config.js +78 -0
  261. package/dist/.DS_Store +0 -0
  262. package/dist/cdn/.DS_Store +0 -0
@@ -0,0 +1,362 @@
1
+ // @flow
2
+
3
+ import Entity from './entity';
4
+
5
+ import {
6
+ each, createElement, addClass, removeClass, hasClass, findIndex, head
7
+ } from './utils';
8
+
9
+ import MicroEvent from './microevent';
10
+ import type { Player$Logger } from './types/Logger';
11
+ import type { Player$PlaylistMode } from './types/Playlist';
12
+ import type { Player$Source } from './types/Source';
13
+
14
+ import createSvg, { BACK, NEXT } from './svgs';
15
+
16
+ const CN = 'rplayer';
17
+ const PLAYLIST_CN = `${CN}__playlist`;
18
+
19
+ const PLAYLIST_WRAPPER_CN = `${CN}__playlist-wrapper`;
20
+ const PLAYLIST_WRAPPER_WITHOUT_TITLE_CN = `${PLAYLIST_WRAPPER_CN}--wot-title`;
21
+ const PLAYLIST_HEADER_CN = `${CN}__playlist-header`;
22
+ const PLAYLIST_OF_CN = `${CN}__playlist-of`;
23
+ const PLAYLIST_CURRENT_TITLE_CN = `${CN}__playlist-current-title`;
24
+
25
+ const PLAYLIST_ITEM_CN = `${CN}__playlist-item`;
26
+ const PLAYLIST_INNER_ITEM_CN = `${CN}__playlist-item-thumb`;
27
+ const PLAYLIST_CURRENT_ITEM_CN = `${PLAYLIST_ITEM_CN}--current`;
28
+ const PLAYLIST_ITEM_TITLE_CN = `${CN}__playlist-item-title`;
29
+ const PLAYLIST_LEFT_BTN_CN = `${CN}__playlist-left-btn`;
30
+ const PLAYLIST_RIGHT_BTN_CN = `${CN}__playlist-right-btn`;
31
+
32
+ const SLIDE_DELTA = 250;
33
+
34
+ const SPACE_CODE = 32;
35
+
36
+ type PlaylistOptions = {
37
+ mode: Player$PlaylistMode,
38
+ bus: MicroEvent,
39
+ title: string,
40
+ label: string,
41
+ forcePoint: number,
42
+ logger: Player$Logger,
43
+ loop: boolean
44
+ };
45
+
46
+ type ResizeEvent = { width: number, height: number, outerWidth: number };
47
+
48
+ export default class Playlist extends Entity {
49
+ $element: HTMLElement
50
+ $wrapper: HTMLElement
51
+ $of: HTMLElement
52
+ $currentTitle: HTMLElement
53
+ $header: HTMLElement
54
+ $left: HTMLElement;
55
+ $right: HTMLElement;
56
+
57
+ $items = [];
58
+ _playlist: Player$Source[] = [];
59
+ _current: ?HTMLElement = null;
60
+ _header = '';
61
+ _label = 'videos';
62
+ _point: number;
63
+ _mode: string;
64
+ _forceDowngrade: boolean = false;
65
+ _isLoop: boolean = false;
66
+
67
+ constructor(playlist: Player$Source[], options: PlaylistOptions) {
68
+ super(options.bus, options.logger);
69
+ this._playlist = playlist;
70
+ this._mode = options.mode;
71
+ this._header = options.title;
72
+ this._label = options.label;
73
+ this._point = options.forcePoint;
74
+ this._isLoop = options.loop;
75
+
76
+ // $FlowFixMe
77
+ this._onResize = this._onResize.bind(this);
78
+ // $FlowFixMe
79
+ this._onFullScreenChanged = this._onFullScreenChanged.bind(this);
80
+ // $FlowFixMe
81
+ this._gotoNextTrack = this._gotoNextTrack.bind(this);
82
+ // $FlowFixMe
83
+ this._gotoPrevTrack = this._gotoPrevTrack.bind(this);
84
+
85
+ options.bus.on('resizeplayer', this._onResize);
86
+ options.bus.on('nexttrack', this._gotoNextTrack);
87
+ options.bus.on('prevtrack', this._gotoPrevTrack);
88
+ options.bus.on('fullscreenchanged', this._onFullScreenChanged);
89
+
90
+ this.render();
91
+
92
+ this.addEvent(this.$left, 'click', () => this.slideLeft(SLIDE_DELTA));
93
+ this.addEvent(this.$right, 'click', () => this.slideRight(SLIDE_DELTA));
94
+ }
95
+
96
+ isBottom() {
97
+ return this._forceDowngrade ? true : this._mode === 'bottom';
98
+ }
99
+
100
+ _gotoNextTrack() {
101
+ let idx = findIndex(this.$items, this._current);
102
+ let item = this.$items[++idx];
103
+
104
+ if (this._isLoop && !item) {
105
+ item = this.$items[0];
106
+ }
107
+
108
+ eventFire(item, 'click');
109
+ }
110
+
111
+ _gotoPrevTrack() {
112
+ let idx = findIndex(this.$items, this._current);
113
+ const item = this.$items[--idx];
114
+ if (item) {
115
+ eventFire(item, 'click');
116
+ }
117
+ }
118
+
119
+ render() {
120
+ this.$wrapper = createElement('div', { class: `${PLAYLIST_WRAPPER_CN} ${this._header ? '' : PLAYLIST_WRAPPER_WITHOUT_TITLE_CN}` });
121
+ this.$header = createElement('h3', { class: PLAYLIST_HEADER_CN, title: this._header }, this.$wrapper);
122
+ this.$header.textContent = this._header;
123
+ this.$of = createElement('span', { class: PLAYLIST_OF_CN }, this.$wrapper);
124
+ this.$currentTitle = createElement('span', { class: PLAYLIST_CURRENT_TITLE_CN }, this.$wrapper);
125
+ this.$element = createElement('div', { class: PLAYLIST_CN, tabindex: -1 }, this.$wrapper);
126
+
127
+ const params = { type: 'button', class: PLAYLIST_LEFT_BTN_CN, style: 'display: none;' };
128
+ this.$left = createElement('button', params, this.$wrapper);
129
+ createSvg(this.$left, BACK);
130
+ this.$left.setAttribute('aria-label', 'Scroll left');
131
+
132
+ this.$right = createElement('button', { type: 'button', class: PLAYLIST_RIGHT_BTN_CN }, this.$wrapper);
133
+ createSvg(this.$right, NEXT);
134
+ this.$right.setAttribute('aria-label', 'Scroll right');
135
+
136
+ // find(this._playlist, pl => pl.default) ||
137
+ let options = head(this._playlist);
138
+
139
+ each(this._playlist, opts => {
140
+ const wrapper = this._renderItem(opts);
141
+ if (opts === options) {
142
+ this._changeSource(options);
143
+ this._changeCurrent(wrapper);
144
+ }
145
+ this.$items.push(wrapper);
146
+ });
147
+ }
148
+
149
+ _changeSource(options: Player$Source) {
150
+ this.bus.emit('changesource', options);
151
+ this.bus.emit('changeplaylistmode', this.isBottom() ? 'bottom' : 'right');
152
+ const idx = this._playlist.indexOf(options) + 1;
153
+ this.$of.textContent = `${idx}/${this._playlist.length} ${this._label}`;
154
+ this.$currentTitle.textContent = options.title;
155
+ this.$currentTitle.setAttribute('title', options.title);
156
+ }
157
+
158
+ _changeCurrent(current: HTMLElement) {
159
+ if (this._current) {
160
+ removeClass(this._current, PLAYLIST_CURRENT_ITEM_CN);
161
+ }
162
+ addClass(current, PLAYLIST_CURRENT_ITEM_CN);
163
+
164
+ this._current = current;
165
+ this._stablePlaylist();
166
+ }
167
+
168
+ _stablePlaylist() {
169
+ if (!this._current) {
170
+ return;
171
+ }
172
+ const rect = this._current.getBoundingClientRect();
173
+ if ( this.isBottom() ) {
174
+ if ( this.$left ) {
175
+ let leftRect = this.$left.getBoundingClientRect();
176
+ if (leftRect.right > rect.left) {
177
+ this.slideLeft(leftRect.right - rect.left);
178
+ }
179
+ }
180
+
181
+ if ( this.$right ) {
182
+ let rightRect = this.$right.getBoundingClientRect();
183
+ if (rightRect.left < rect.right) {
184
+ this.slideRight(rect.right - rightRect.left);
185
+ }
186
+ }
187
+ } else {
188
+ const parentRect = this.$element.getBoundingClientRect();
189
+ this.$element.scrollTop -= Math.max(0, parentRect.top - rect.top);
190
+ this.$element.scrollTop += Math.max(0, rect.bottom - parentRect.bottom);
191
+ }
192
+ }
193
+
194
+ _renderItem(options: Player$Source) {
195
+ const wrapper = createElement(
196
+ 'div',
197
+ { class: PLAYLIST_ITEM_CN, title: options.title, tabindex: 0 },
198
+ this.$element
199
+ );
200
+ const inner = createElement('div', { class: PLAYLIST_INNER_ITEM_CN }, wrapper);
201
+ createElement('img', { src: options.poster }, inner);
202
+ const span = createElement('span', { class: PLAYLIST_ITEM_TITLE_CN }, wrapper);
203
+ span.textContent = options.title;
204
+ createElement('b', { }, wrapper);
205
+
206
+ const handler = () => {
207
+ if ( hasClass(wrapper, PLAYLIST_CURRENT_ITEM_CN) ) {
208
+ return;
209
+ }
210
+ this._changeSource(options);
211
+ this._changeCurrent(wrapper);
212
+ };
213
+
214
+ this.addEvent(wrapper, 'click', handler);
215
+ this.addEvent(wrapper, 'keydown', (e: KeyboardEvent) => {
216
+ if (e.keyCode !== SPACE_CODE) return;
217
+ e.preventDefault();
218
+ handler();
219
+ });
220
+
221
+ return wrapper;
222
+ }
223
+
224
+ _onResize(data: ResizeEvent) {
225
+ const { outerWidth } = data;
226
+
227
+ if ( this._forceDowngrade !== outerWidth < this._point ) {
228
+ this._forceDowngrade = !this._forceDowngrade;
229
+ this.bus.emit('changeplaylistmode', this.isBottom() ? 'bottom' : 'right');
230
+ this.$wrapper.style.height = '';
231
+ this.$element.style.width = '';
232
+ this.$element.style.marginLeft = '';
233
+ this._stablePlaylist();
234
+ }
235
+
236
+ if (this.isBottom()) {
237
+ this._resize4bottom(data);
238
+ } else {
239
+ this._resize4right(data);
240
+ }
241
+ }
242
+
243
+ _resize4right({height}: ResizeEvent) {
244
+ this.$wrapper.style.height = `${height}px`;
245
+ if (!this._current) {
246
+ return;
247
+ }
248
+
249
+ const current = this._current.getBoundingClientRect();
250
+ const parent = this.$element.getBoundingClientRect();
251
+
252
+ if ( parent.top > current.top ) {
253
+ this.$element.scrollTop = this.$element.scrollTop - ( parent.top - current.top );
254
+ } else if (parent.bottom < current.bottom) {
255
+ this.$element.scrollTop = this.$element.scrollTop + current.bottom - parent.bottom;
256
+ }
257
+ }
258
+
259
+ _resize4bottom({ width }: ResizeEvent) {
260
+ each(this.$items, c => {
261
+ c.style.width = '';
262
+ });
263
+ this.$element.style.width = `${width}px`;
264
+
265
+ width = 0;
266
+ each(this.$items, c => {
267
+ width += c.offsetWidth;
268
+ const style = c.currentStyle || window.getComputedStyle(c);
269
+ width += parseFloat(style.marginRight);
270
+ });
271
+ this.$element.style.width = `${width}px`;
272
+ this._stableBottomPosition();
273
+ }
274
+
275
+ _stableBottomPosition() {
276
+ if (!this._current) {
277
+ return;
278
+ }
279
+ const current = this._current.getBoundingClientRect();
280
+ const parent = this.$wrapper.getBoundingClientRect();
281
+
282
+ if ( parent.left > current.left ) {
283
+ eventFire(this.$left, 'click');
284
+ setTimeout(() => this._stableBottomPosition());
285
+ } else if (parent.right < current.right) {
286
+ eventFire(this.$right, 'click');
287
+ setTimeout(() => this._stableBottomPosition());
288
+ }
289
+ }
290
+
291
+ _onFullScreenChanged(isFullScreenMode: boolean) {
292
+ this.$element.style.display = isFullScreenMode ? 'none' : 'block';
293
+ }
294
+
295
+ slideLeft(delta: number) {
296
+ let ml = parseInt(this.$element.style.marginLeft, 10) || 0;
297
+ ml = Math.min(0, ml + delta);
298
+ this.$element.style.marginLeft = `${ml}px`;
299
+ this.$right.style.display = 'block';
300
+ if (!ml) {
301
+ this.$left.style.display = 'none';
302
+ }
303
+ }
304
+
305
+ slideRight(delta: number) {
306
+ const parent = this.$element.parentNode;
307
+ if (!(parent instanceof HTMLElement)) {
308
+ return;
309
+ }
310
+ let ml = parseInt(this.$element.style.marginLeft, 10) || 0;
311
+ ml -= delta;
312
+ const min = parent.offsetWidth - this.$element.offsetWidth;
313
+ ml = Math.max(min, ml);
314
+ this.$element.style.marginLeft = `${ml}px`;
315
+ this.$left.style.display = 'block';
316
+ if (ml === min) {
317
+ this.$right.style.display = 'none';
318
+ }
319
+ }
320
+
321
+ getElement() {
322
+ return this.$wrapper;
323
+ }
324
+
325
+ destroy() {
326
+ super.destroy();
327
+ this.bus.off('resizeplayer', this._onResize);
328
+ this.bus.off('nexttrack', this._gotoNextTrack);
329
+ this.bus.off('prevtrack', this._gotoPrevTrack);
330
+ this.bus.off('fullscreenchanged', this._onFullScreenChanged);
331
+ if (this.$element.parentNode) {
332
+ this.$element.parentNode.removeChild(this.$element);
333
+ }
334
+
335
+ // this.$element = null;
336
+ this.$items.length = 0;
337
+ this._playlist.length = 0;
338
+ this._current = null;
339
+ }
340
+ }
341
+
342
+ function eventFire(el, etype) {
343
+ var event;
344
+ if (document.createEvent) {
345
+ event = document.createEvent('HTMLEvents');
346
+ event.initEvent(etype, true, true);
347
+ } else {
348
+ // $FlowFixMe
349
+ event = document.createEventObject();
350
+ event.eventType = etype;
351
+ }
352
+
353
+ // $FlowFixMe
354
+ event.eventName = etype;
355
+
356
+ if (el.dispatchEvent) {
357
+ el.dispatchEvent(event);
358
+ } else {
359
+ // $FlowFixMe
360
+ el.fireEvent('on' + etype, event);
361
+ }
362
+ }
@@ -0,0 +1,121 @@
1
+ import { addProperty, noop } from './utils';
2
+
3
+ // var keyboardAllowed = typeof Element !== 'undefined' && 'ALLOW_KEYBOARD_INPUT' in Element;
4
+
5
+ var fn = (() => {
6
+ var val;
7
+ var valLength;
8
+
9
+ var fnMap = [
10
+ [
11
+ 'requestFullscreen',
12
+ 'exitFullscreen',
13
+ 'fullscreenElement',
14
+ 'fullscreenEnabled',
15
+ 'fullscreenchange',
16
+ 'fullscreenerror'
17
+ ],
18
+ // new WebKit
19
+ [
20
+ 'webkitRequestFullscreen',
21
+ 'webkitExitFullscreen',
22
+ 'webkitFullscreenElement',
23
+ 'webkitFullscreenEnabled',
24
+ 'webkitfullscreenchange',
25
+ 'webkitfullscreenerror'
26
+
27
+ ],
28
+ // old WebKit (Safari 5.1)
29
+ [
30
+ 'webkitRequestFullScreen',
31
+ 'webkitCancelFullScreen',
32
+ 'webkitCurrentFullScreenElement',
33
+ 'webkitCancelFullScreen',
34
+ 'webkitfullscreenchange',
35
+ 'webkitfullscreenerror'
36
+
37
+ ],
38
+ [
39
+ 'mozRequestFullScreen',
40
+ 'mozCancelFullScreen',
41
+ 'mozFullScreenElement',
42
+ 'mozFullScreenEnabled',
43
+ 'mozfullscreenchange',
44
+ 'mozfullscreenerror'
45
+ ],
46
+ [
47
+ 'msRequestFullscreen',
48
+ 'msExitFullscreen',
49
+ 'msFullscreenElement',
50
+ 'msFullscreenEnabled',
51
+ 'MSFullscreenChange',
52
+ 'MSFullscreenError'
53
+ ]
54
+ ];
55
+
56
+ var i = 0;
57
+ var l = fnMap.length;
58
+ var ret = {};
59
+
60
+ for (; i < l; i++) {
61
+ val = fnMap[i];
62
+ if (val && val[1] in document) {
63
+ for (i = 0, valLength = val.length; i < valLength; i++) {
64
+ ret[fnMap[0][i]] = val[i];
65
+ }
66
+ return ret;
67
+ }
68
+ }
69
+
70
+ return false;
71
+ })();
72
+
73
+ const screenfull = {
74
+ request(elem) {
75
+ var request = fn.requestFullscreen;
76
+
77
+ elem = elem || document.documentElement;
78
+
79
+ // Work around Safari 5.1 bug: reports support for
80
+ // keyboard in fullscreen even though it doesn't.
81
+ // Browser sniffing, since the alternative with
82
+ // setTimeout is even worse.
83
+ if (/5\.1[\.\d]* Safari/.test(navigator.userAgent)) {
84
+ elem[request]();
85
+ } else {
86
+ elem[request]();
87
+ // keyboardAllowed && Element.ALLOW_KEYBOARD_INPUT
88
+ }
89
+ },
90
+ exit() {
91
+ if (this.isFullscreen) {
92
+ document[fn.exitFullscreen]();
93
+ }
94
+ },
95
+ toggle(elem) {
96
+ if (this.isFullscreen) {
97
+ this.exit();
98
+ } else {
99
+ this.request(elem);
100
+ }
101
+ },
102
+ raw: fn
103
+ };
104
+
105
+ addProperty(screenfull, 'isFullscreen', isFullscreen, noop);
106
+ addProperty(screenfull, 'element', element, noop);
107
+ addProperty(screenfull, 'enabled', enabled, noop);
108
+
109
+ export default fn ? screenfull : false;
110
+
111
+ function isFullscreen() {
112
+ return Boolean(document[fn.fullscreenElement]);
113
+ }
114
+
115
+ function element() {
116
+ return document[fn.fullscreenElement];
117
+ }
118
+
119
+ function enabled() {
120
+ return Boolean(document[fn.fullscreenEnabled]);
121
+ }