@oat-sa/tao-core-ui 1.58.1 → 1.58.2

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 (233) hide show
  1. package/dist/actionbar.js +386 -395
  2. package/dist/adder.js +21 -19
  3. package/dist/animable/absorbable/absorbable.js +204 -213
  4. package/dist/animable/absorbable/css/absorb.css +1 -0
  5. package/dist/animable/absorbable/css/absorb.css.map +1 -1
  6. package/dist/animable/pulsable/pulsable.js +168 -177
  7. package/dist/autocomplete/css/autocomplete.css +1 -0
  8. package/dist/autocomplete/css/autocomplete.css.map +1 -1
  9. package/dist/autocomplete.js +68 -66
  10. package/dist/badge/badge.js +188 -197
  11. package/dist/badge/css/badge.css +1 -0
  12. package/dist/badge/css/badge.css.map +1 -1
  13. package/dist/breadcrumbs.js +275 -284
  14. package/dist/btngrouper.js +5 -5
  15. package/dist/bulkActionPopup.js +490 -495
  16. package/dist/button.js +283 -291
  17. package/dist/cascadingComboBox.js +249 -258
  18. package/dist/ckeditor/ckConfigurator.js +26 -19
  19. package/dist/ckeditor/dtdHandler.js +11 -9
  20. package/dist/class/selector.js +441 -450
  21. package/dist/component/resizable.js +1 -1
  22. package/dist/component/windowed.js +285 -294
  23. package/dist/component.js +419 -428
  24. package/dist/contextualPopup.js +417 -426
  25. package/dist/dashboard.js +300 -309
  26. package/dist/datalist.js +753 -762
  27. package/dist/datatable/filterStrategy/multiple.js +1 -1
  28. package/dist/datatable/filterStrategy/single.js +1 -1
  29. package/dist/datatable.js +1527 -1550
  30. package/dist/dateRange/dateRange.js +393 -402
  31. package/dist/datetime/picker.js +665 -672
  32. package/dist/deleter.js +368 -377
  33. package/dist/destination/selector.js +286 -295
  34. package/dist/dialog/alert.js +3 -3
  35. package/dist/dialog/confirm.js +1 -1
  36. package/dist/dialog/confirmDelete.js +216 -225
  37. package/dist/dialog.js +650 -654
  38. package/dist/disabler.js +8 -8
  39. package/dist/documentViewer/providers/pdfViewer/fallback/viewer.js +166 -175
  40. package/dist/documentViewer/providers/pdfViewer/pdfjs/findBar.js +518 -527
  41. package/dist/documentViewer/providers/pdfViewer/pdfjs/pageView.js +380 -389
  42. package/dist/documentViewer/providers/pdfViewer/pdfjs/searchEngine.js +539 -548
  43. package/dist/documentViewer/providers/pdfViewer/pdfjs/viewer.js +369 -378
  44. package/dist/documentViewer/providers/pdfViewer.js +184 -193
  45. package/dist/documentViewer.js +292 -301
  46. package/dist/dropdown.js +383 -392
  47. package/dist/durationer.js +5 -5
  48. package/dist/dynamicComponent.js +597 -598
  49. package/dist/feedback.js +356 -362
  50. package/dist/figure/FigureStateActive.js +117 -108
  51. package/dist/filesender.js +2 -2
  52. package/dist/filter.js +230 -239
  53. package/dist/form/dropdownForm.js +355 -357
  54. package/dist/form/form.js +919 -690
  55. package/dist/form/simpleForm.js +1 -1
  56. package/dist/form/validator/renderer.js +233 -235
  57. package/dist/form/validator/validator.js +257 -189
  58. package/dist/form/widget/definitions.js +1 -1
  59. package/dist/form/widget/providers/checkBox.js +254 -259
  60. package/dist/form/widget/providers/comboBox.js +187 -192
  61. package/dist/form/widget/providers/default.js +8 -9
  62. package/dist/form/widget/providers/hidden.js +170 -179
  63. package/dist/form/widget/providers/hiddenBox.js +262 -267
  64. package/dist/form/widget/providers/radioBox.js +216 -225
  65. package/dist/form/widget/providers/textArea.js +187 -196
  66. package/dist/form/widget/providers/textBox.js +2 -3
  67. package/dist/form/widget/widget.js +473 -475
  68. package/dist/formValidator/formValidator.js +1 -1
  69. package/dist/formValidator/highlighters/message.js +1 -1
  70. package/dist/generis/form/form.js +314 -323
  71. package/dist/generis/validator/validator.js +209 -218
  72. package/dist/generis/widget/checkBox/checkBox.js +218 -227
  73. package/dist/generis/widget/comboBox/comboBox.js +179 -188
  74. package/dist/generis/widget/hiddenBox/hiddenBox.js +220 -229
  75. package/dist/generis/widget/textBox/textBox.js +169 -178
  76. package/dist/generis/widget/widget.js +246 -255
  77. package/dist/groupedComboBox.js +222 -231
  78. package/dist/groupvalidator.js +2 -2
  79. package/dist/highlighter.js +967 -958
  80. package/dist/image/ImgStateActive/helper.js +7 -5
  81. package/dist/image/ImgStateActive/initHelper.js +49 -43
  82. package/dist/image/ImgStateActive/initMediaEditor.js +24 -20
  83. package/dist/image/ImgStateActive/mediaSizer.js +14 -12
  84. package/dist/image/ImgStateActive.js +72 -70
  85. package/dist/incrementer.js +6 -6
  86. package/dist/inplacer.js +6 -6
  87. package/dist/itemButtonList/css/item-button-list.css +1 -0
  88. package/dist/itemButtonList/css/item-button-list.css.map +1 -1
  89. package/dist/itemButtonList.js +439 -435
  90. package/dist/keyNavigation/navigableDomElement.js +51 -38
  91. package/dist/keyNavigation/navigator.js +85 -70
  92. package/dist/listbox.js +460 -469
  93. package/dist/liststyler.js +8 -8
  94. package/dist/loadingButton/loadingButton.js +209 -218
  95. package/dist/lock.js +476 -485
  96. package/dist/login/login.js +475 -484
  97. package/dist/maths/calculator/basicCalculator.js +235 -244
  98. package/dist/maths/calculator/calculatorComponent.js +3 -3
  99. package/dist/maths/calculator/core/board.js +772 -781
  100. package/dist/maths/calculator/core/expression.js +476 -485
  101. package/dist/maths/calculator/core/labels.js +228 -237
  102. package/dist/maths/calculator/core/tokenizer.js +1 -1
  103. package/dist/maths/calculator/core/tokens.js +163 -170
  104. package/dist/maths/calculator/plugins/keyboard/templateKeyboard/templateKeyboard.js +244 -253
  105. package/dist/maths/calculator/plugins/screen/simpleScreen/simpleScreen.js +279 -288
  106. package/dist/maths/calculator/scientificCalculator.js +327 -336
  107. package/dist/mediaEditor/mediaEditorComponent.js +238 -245
  108. package/dist/mediaEditor/plugins/mediaAlignment/helper.js +7 -7
  109. package/dist/mediaEditor/plugins/mediaAlignment/mediaAlignmentComponent.js +229 -235
  110. package/dist/mediaEditor/plugins/mediaDimension/mediaDimensionComponent.js +580 -589
  111. package/dist/mediaplayer/players/html5.js +666 -675
  112. package/dist/mediaplayer/players/youtube.js +419 -424
  113. package/dist/mediaplayer/support.js +11 -10
  114. package/dist/mediaplayer/utils/reminder.js +14 -13
  115. package/dist/mediaplayer/utils/timeObserver.js +10 -11
  116. package/dist/mediaplayer/youtubeManager.js +164 -145
  117. package/dist/mediaplayer.js +1565 -1520
  118. package/dist/mediasizer.js +669 -678
  119. package/dist/modal.js +10 -17
  120. package/dist/pageSizeSelector.js +219 -228
  121. package/dist/pagination/providers/pages.js +280 -289
  122. package/dist/pagination/providers/simple.js +192 -201
  123. package/dist/previewer.js +30 -30
  124. package/dist/progressbar.js +4 -4
  125. package/dist/report.js +347 -356
  126. package/dist/resource/filters.js +271 -280
  127. package/dist/resource/list.js +1264 -1273
  128. package/dist/resource/selector.js +865 -874
  129. package/dist/resource/tree.js +1483 -1492
  130. package/dist/resourcemgr/fileBrowser.js +564 -569
  131. package/dist/resourcemgr/filePreview.js +16 -16
  132. package/dist/resourcemgr/fileSelector.js +515 -524
  133. package/dist/resourcemgr/util/updatePermissions.js +2 -2
  134. package/dist/resourcemgr.js +306 -315
  135. package/dist/searchModal/advancedSearch.js +796 -767
  136. package/dist/searchModal.js +114 -91
  137. package/dist/switch/switch.js +298 -307
  138. package/dist/tabs.js +598 -575
  139. package/dist/taskQueue/status.js +312 -321
  140. package/dist/taskQueue/table.js +375 -384
  141. package/dist/taskQueue/taskQueueModel.js +488 -472
  142. package/dist/taskQueueButton/taskable.js +264 -273
  143. package/dist/taskQueueButton/treeButton.js +189 -198
  144. package/dist/themeLoader.js +24 -23
  145. package/dist/themes.js +1 -1
  146. package/dist/toggler.js +3 -3
  147. package/dist/tooltip.js +295 -304
  148. package/dist/transformer.js +2 -2
  149. package/dist/tristateCheckboxGroup.js +311 -320
  150. package/dist/uploader.js +687 -696
  151. package/dist/validator/Report.js +1 -1
  152. package/dist/validator/Validator.js +3 -3
  153. package/dist/validator/validators.js +9 -9
  154. package/dist/validator.js +240 -230
  155. package/dist/waitForMedia.js +1 -1
  156. package/package.json +3 -3
  157. package/src/animable/absorbable/css/absorb.css +1 -0
  158. package/src/animable/absorbable/css/absorb.css.map +1 -1
  159. package/src/autocomplete/css/autocomplete.css +1 -0
  160. package/src/autocomplete/css/autocomplete.css.map +1 -1
  161. package/src/badge/css/badge.css +1 -0
  162. package/src/badge/css/badge.css.map +1 -1
  163. package/src/ckeditor/ckConfigurator.js +4 -0
  164. package/src/itemButtonList/css/item-button-list.css +1 -0
  165. package/src/itemButtonList/css/item-button-list.css.map +1 -1
  166. package/src/.DS_Store +0 -0
  167. package/src/css/basic.css +0 -7826
  168. package/src/css/basic.css.map +0 -1
  169. package/src/css/ckeditor/skins/tao/css/dialog.css +0 -950
  170. package/src/css/ckeditor/skins/tao/css/dialog.css.map +0 -1
  171. package/src/css/ckeditor/skins/tao/css/editor.css +0 -1850
  172. package/src/css/ckeditor/skins/tao/css/editor.css.map +0 -1
  173. package/src/scss/.DS_Store +0 -0
  174. package/src/scss/basic.scss +0 -16
  175. package/src/scss/ckeditor/skins/tao/scss/dialog.scss +0 -763
  176. package/src/scss/ckeditor/skins/tao/scss/editor.scss +0 -111
  177. package/src/scss/ckeditor/skins/tao/scss/inc/_ck-icons.scss +0 -59
  178. package/src/scss/ckeditor/skins/tao/scss/inc/_colorpanel.scss +0 -118
  179. package/src/scss/ckeditor/skins/tao/scss/inc/_elementspath.scss +0 -69
  180. package/src/scss/ckeditor/skins/tao/scss/inc/_mainui.scss +0 -194
  181. package/src/scss/ckeditor/skins/tao/scss/inc/_menu.scss +0 -181
  182. package/src/scss/ckeditor/skins/tao/scss/inc/_panel.scss +0 -200
  183. package/src/scss/ckeditor/skins/tao/scss/inc/_presets.scss +0 -32
  184. package/src/scss/ckeditor/skins/tao/scss/inc/_reset.scss +0 -101
  185. package/src/scss/ckeditor/skins/tao/scss/inc/_richcombo.scss +0 -213
  186. package/src/scss/ckeditor/skins/tao/scss/inc/_tao.scss +0 -59
  187. package/src/scss/ckeditor/skins/tao/scss/inc/_toolbar.scss +0 -301
  188. package/src/scss/font/source-sans-pro/source-sans-pro-italic.eot +0 -0
  189. package/src/scss/font/source-sans-pro/source-sans-pro-italic.eot.b64 +0 -1
  190. package/src/scss/font/source-sans-pro/source-sans-pro-italic.woff +0 -0
  191. package/src/scss/font/source-sans-pro/source-sans-pro-italic.woff.b64 +0 -1
  192. package/src/scss/font/source-sans-pro/source-sans-pro-regular.eot +0 -0
  193. package/src/scss/font/source-sans-pro/source-sans-pro-regular.eot.b64 +0 -1
  194. package/src/scss/font/source-sans-pro/source-sans-pro-regular.woff +0 -0
  195. package/src/scss/font/source-sans-pro/source-sans-pro-regular.woff.b64 +0 -1
  196. package/src/scss/font/source-sans-pro/source-sans-pro-semibold-italic.eot +0 -0
  197. package/src/scss/font/source-sans-pro/source-sans-pro-semibold-italic.eot.b64 +0 -1
  198. package/src/scss/font/source-sans-pro/source-sans-pro-semibold-italic.woff +0 -0
  199. package/src/scss/font/source-sans-pro/source-sans-pro-semibold-italic.woff.b64 +0 -1
  200. package/src/scss/font/source-sans-pro/source-sans-pro-semibold.eot +0 -0
  201. package/src/scss/font/source-sans-pro/source-sans-pro-semibold.eot.b64 +0 -1
  202. package/src/scss/font/source-sans-pro/source-sans-pro-semibold.woff +0 -0
  203. package/src/scss/font/source-sans-pro/source-sans-pro-semibold.woff.b64 +0 -1
  204. package/src/scss/font/tao/tao.eot +0 -0
  205. package/src/scss/font/tao/tao.svg +0 -235
  206. package/src/scss/font/tao/tao.ttf +0 -0
  207. package/src/scss/font/tao/tao.woff +0 -0
  208. package/src/scss/inc/_base.scss +0 -496
  209. package/src/scss/inc/_bootstrap.scss +0 -6
  210. package/src/scss/inc/_buttons.scss +0 -114
  211. package/src/scss/inc/_colors.scss +0 -88
  212. package/src/scss/inc/_feedback.scss +0 -150
  213. package/src/scss/inc/_flex-grid.scss +0 -15
  214. package/src/scss/inc/_fonts.scss +0 -4
  215. package/src/scss/inc/_forms.scss +0 -827
  216. package/src/scss/inc/_functions.scss +0 -283
  217. package/src/scss/inc/_grid.scss +0 -66
  218. package/src/scss/inc/_jquery.nouislider.scss +0 -254
  219. package/src/scss/inc/_normalize.scss +0 -528
  220. package/src/scss/inc/_report.scss +0 -68
  221. package/src/scss/inc/_secondary-properties.scss +0 -89
  222. package/src/scss/inc/_select2.scss +0 -634
  223. package/src/scss/inc/_toolbars.scss +0 -155
  224. package/src/scss/inc/_tooltip.scss +0 -312
  225. package/src/scss/inc/_variables.scss +0 -21
  226. package/src/scss/inc/base/_highlight.scss +0 -5
  227. package/src/scss/inc/base/_list-style.scss +0 -59
  228. package/src/scss/inc/base/_svg.scss +0 -3
  229. package/src/scss/inc/base/_table.scss +0 -63
  230. package/src/scss/inc/fonts/_source-sans-pro.scss +0 -29
  231. package/src/scss/inc/fonts/_tao-icon-classes.scss +0 -226
  232. package/src/scss/inc/fonts/_tao-icon-def.scss +0 -12
  233. package/src/scss/inc/fonts/_tao-icon-vars.scss +0 -240
@@ -1,770 +1,761 @@
1
1
  define(['jquery', 'util/urlParser', 'core/eventifier', 'ui/mediaplayer/support', 'handlebars', 'i18n', 'lodash', 'lib/dompurify/purify', 'ui/mediaplayer/utils/reminder', 'ui/mediaplayer/utils/timeObserver'], function ($$1, UrlParser, eventifier, support, Handlebars, __, _, DOMPurify, reminderManagerFactory, timeObserverFactory) { 'use strict';
2
2
 
3
- $$1 = $$1 && Object.prototype.hasOwnProperty.call($$1, 'default') ? $$1['default'] : $$1;
4
- UrlParser = UrlParser && Object.prototype.hasOwnProperty.call(UrlParser, 'default') ? UrlParser['default'] : UrlParser;
5
- eventifier = eventifier && Object.prototype.hasOwnProperty.call(eventifier, 'default') ? eventifier['default'] : eventifier;
6
- support = support && Object.prototype.hasOwnProperty.call(support, 'default') ? support['default'] : support;
7
- Handlebars = Handlebars && Object.prototype.hasOwnProperty.call(Handlebars, 'default') ? Handlebars['default'] : Handlebars;
8
- __ = __ && Object.prototype.hasOwnProperty.call(__, 'default') ? __['default'] : __;
9
- _ = _ && Object.prototype.hasOwnProperty.call(_, 'default') ? _['default'] : _;
10
- DOMPurify = DOMPurify && Object.prototype.hasOwnProperty.call(DOMPurify, 'default') ? DOMPurify['default'] : DOMPurify;
11
- reminderManagerFactory = reminderManagerFactory && Object.prototype.hasOwnProperty.call(reminderManagerFactory, 'default') ? reminderManagerFactory['default'] : reminderManagerFactory;
12
- timeObserverFactory = timeObserverFactory && Object.prototype.hasOwnProperty.call(timeObserverFactory, 'default') ? timeObserverFactory['default'] : timeObserverFactory;
13
-
3
+ $$1 = $$1 && Object.prototype.hasOwnProperty.call($$1, 'default') ? $$1['default'] : $$1;
4
+ UrlParser = UrlParser && Object.prototype.hasOwnProperty.call(UrlParser, 'default') ? UrlParser['default'] : UrlParser;
5
+ eventifier = eventifier && Object.prototype.hasOwnProperty.call(eventifier, 'default') ? eventifier['default'] : eventifier;
6
+ support = support && Object.prototype.hasOwnProperty.call(support, 'default') ? support['default'] : support;
7
+ Handlebars = Handlebars && Object.prototype.hasOwnProperty.call(Handlebars, 'default') ? Handlebars['default'] : Handlebars;
8
+ __ = __ && Object.prototype.hasOwnProperty.call(__, 'default') ? __['default'] : __;
9
+ _ = _ && Object.prototype.hasOwnProperty.call(_, 'default') ? _['default'] : _;
10
+ DOMPurify = DOMPurify && Object.prototype.hasOwnProperty.call(DOMPurify, 'default') ? DOMPurify['default'] : DOMPurify;
11
+ reminderManagerFactory = reminderManagerFactory && Object.prototype.hasOwnProperty.call(reminderManagerFactory, 'default') ? reminderManagerFactory['default'] : reminderManagerFactory;
12
+ timeObserverFactory = timeObserverFactory && Object.prototype.hasOwnProperty.call(timeObserverFactory, 'default') ? timeObserverFactory['default'] : timeObserverFactory;
13
+
14
+ function _typeof(obj) {
15
+ "@babel/helpers - typeof";
16
+
17
+ return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) {
18
+ return typeof obj;
19
+ } : function (obj) {
20
+ return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
21
+ }, _typeof(obj);
22
+ }
23
+
24
+ function Helpers0 (hb) {
25
+ //register a i18n helper
26
+ hb.registerHelper('__', function (key) {
27
+ return __(key);
28
+ });
14
29
  /**
15
- * This program is free software; you can redistribute it and/or
16
- * modify it under the terms of the GNU General Public License
17
- * as published by the Free Software Foundation; under version 2
18
- * of the License (non-upgradable).
19
- *
20
- * This program is distributed in the hope that it will be useful,
21
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
22
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23
- * GNU General Public License for more details.
24
- *
25
- * You should have received a copy of the GNU General Public License
26
- * along with this program; if not, write to the Free Software
27
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
28
- *
29
- * Copyright (c) 2013-2019 (original work) Open Assessment Technologies SA (under the project TAO-PRODUCT);
30
- *
30
+ * Register dompurify helper
31
31
  *
32
+ * https://github.com/cure53/DOMPurify
33
+ * with config SAFE_FOR_TEMPLATES: true
34
+ * to make output safe for template systems
32
35
  */
33
- function Helpers0 (hb) {
34
- //register a i18n helper
35
- hb.registerHelper('__', function (key) {
36
- return __(key);
37
- });
38
- /**
39
- * Register dompurify helper
40
- *
41
- * https://github.com/cure53/DOMPurify
42
- * with config SAFE_FOR_TEMPLATES: true
43
- * to make output safe for template systems
44
- */
45
-
46
- hb.registerHelper('dompurify', function (context) {
47
- return DOMPurify.sanitize(context);
48
- });
49
- /**
50
- * Register join helper
51
- *
52
- * Example :
53
- * var values = {a:v1, b:v2, c:v3};
54
- * Using {{{join attributes '=' ' ' '"'}}} will return : a="v1" b="v2" c="v3"
55
- * Using {{{join values null ' or ' '*'}}} will return : *v1* or *v2* or *v3*
56
- */
57
-
58
- hb.registerHelper('join', function (arr, keyValueGlue, fragmentGlue, wrapper) {
59
- var fragments = [];
60
- keyValueGlue = typeof keyValueGlue === 'string' ? keyValueGlue : undefined;
61
- fragmentGlue = typeof fragmentGlue === 'string' ? fragmentGlue : ' ';
62
- wrapper = typeof wrapper === 'string' ? wrapper : '"';
63
-
64
- _.forIn(arr, function (value, key) {
65
- var fragment = '';
66
-
67
- if (value !== null || value !== undefined) {
68
- if (typeof value === 'boolean') {
69
- value = value ? 'true' : 'false';
70
- } else if (typeof value === 'object') {
71
- value = _.values(value).join(' ');
72
- }
73
- } else {
74
- value = '';
75
- }
76
36
 
77
- if (keyValueGlue !== undefined) {
78
- fragment += key + keyValueGlue;
79
- }
37
+ hb.registerHelper('dompurify', function (context) {
38
+ return DOMPurify.sanitize(context);
39
+ });
40
+ /**
41
+ * Register join helper
42
+ *
43
+ * Example :
44
+ * var values = {a:v1, b:v2, c:v3};
45
+ * Using {{{join attributes '=' ' ' '"'}}} will return : a="v1" b="v2" c="v3"
46
+ * Using {{{join values null ' or ' '*'}}} will return : *v1* or *v2* or *v3*
47
+ */
80
48
 
81
- fragment += wrapper + value + wrapper;
82
- fragments.push(fragment);
83
- });
49
+ hb.registerHelper('join', function (arr, keyValueGlue, fragmentGlue, wrapper) {
50
+ var fragments = [];
51
+ keyValueGlue = typeof keyValueGlue === 'string' ? keyValueGlue : undefined;
52
+ fragmentGlue = typeof fragmentGlue === 'string' ? fragmentGlue : ' ';
53
+ wrapper = typeof wrapper === 'string' ? wrapper : '"';
84
54
 
85
- return fragments.join(fragmentGlue);
86
- }); //register a classic "for loop" helper
87
- //it also adds a local variable "i" as the index in each iteration loop
55
+ _.forIn(arr, function (value, key) {
56
+ var fragment = '';
88
57
 
89
- hb.registerHelper('for', function (startIndex, stopIndex, increment, options) {
90
- var ret = '';
91
- startIndex = parseInt(startIndex);
92
- stopIndex = parseInt(stopIndex);
93
- increment = parseInt(increment);
58
+ if (value !== null || value !== undefined) {
59
+ if (typeof value === 'boolean') {
60
+ value = value ? 'true' : 'false';
61
+ } else if (_typeof(value) === 'object') {
62
+ value = _.values(value).join(' ');
63
+ }
64
+ } else {
65
+ value = '';
66
+ }
94
67
 
95
- for (var i = startIndex; i < stopIndex; i += increment) {
96
- ret += options.fn(_.extend({}, this, {
97
- i: i
98
- }));
68
+ if (keyValueGlue !== undefined) {
69
+ fragment += key + keyValueGlue;
99
70
  }
100
71
 
101
- return ret;
72
+ fragment += wrapper + value + wrapper;
73
+ fragments.push(fragment);
102
74
  });
103
- hb.registerHelper('equal', function (var1, var2, options) {
104
- if (var1 == var2) {
105
- return options.fn(this);
106
- } else {
107
- return options.inverse(this);
108
- }
109
- }); // register a "get property" helper
110
- // it gets the named property from the provided context
111
75
 
112
- hb.registerHelper('property', function (name, context) {
113
- return context[name] || '';
114
- }); // register an 'includes' helper
115
- // it checks if value is in array
76
+ return fragments.join(fragmentGlue);
77
+ }); //register a classic "for loop" helper
78
+ //it also adds a local variable "i" as the index in each iteration loop
116
79
 
117
- hb.registerHelper('includes', function (haystack, needle, options) {
118
- if (_.contains(haystack, needle)) {
119
- return options.fn(this);
120
- }
121
- });
122
- }
80
+ hb.registerHelper('for', function (startIndex, stopIndex, increment, options) {
81
+ var ret = '';
82
+ startIndex = parseInt(startIndex);
83
+ stopIndex = parseInt(stopIndex);
84
+ increment = parseInt(increment);
123
85
 
124
- if (!Helpers0.__initialized) {
125
- Helpers0(Handlebars);
126
- Helpers0.__initialized = true;
127
- }
128
- var Template = Handlebars.template(function (Handlebars,depth0,helpers,partials,data) {
129
- this.compilerInfo = [4,'>= 1.0.0'];
130
- helpers = this.merge(helpers, Handlebars.helpers); data = data || {};
131
- var buffer = "", stack1, helper, options, functionType="function", escapeExpression=this.escapeExpression, helperMissing=helpers.helperMissing, self=this;
132
-
133
- function program1(depth0,data) {
134
-
135
-
136
- return "crossorigin";
86
+ for (var i = startIndex; i < stopIndex; i += increment) {
87
+ ret += options.fn(_.extend({}, this, {
88
+ i: i
89
+ }));
137
90
  }
138
91
 
139
- function program3(depth0,data) {
140
-
141
- var buffer = "", stack1, helper, options;
142
- buffer += "\n <a href=\"";
143
- if (helper = helpers.link) { stack1 = helper.call(depth0, {hash:{},data:data}); }
144
- else { helper = (depth0 && depth0.link); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }
145
- buffer += escapeExpression(stack1)
146
- + "\">"
147
- + escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "Please download the track and listen offline.", options) : helperMissing.call(depth0, "__", "Please download the track and listen offline.", options)))
148
- + "</a>\n";
149
- return buffer;
92
+ return ret;
93
+ });
94
+ hb.registerHelper('equal', function (var1, var2, options) {
95
+ if (var1 == var2) {
96
+ return options.fn(this);
97
+ } else {
98
+ return options.inverse(this);
150
99
  }
100
+ }); // register a "get property" helper
101
+ // it gets the named property from the provided context
151
102
 
152
- buffer += "<audio class=\"media audio\" preload=\"";
153
- if (helper = helpers.preload) { stack1 = helper.call(depth0, {hash:{},data:data}); }
154
- else { helper = (depth0 && depth0.preload); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }
155
- buffer += escapeExpression(stack1)
156
- + "\" controls ";
157
- stack1 = helpers['if'].call(depth0, (depth0 && depth0.cors), {hash:{},inverse:self.noop,fn:self.program(1, program1, data),data:data});
158
- if(stack1 || stack1 === 0) { buffer += stack1; }
159
- buffer += ">\n "
160
- + escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "Your browser doesn’t support the audio player.", options) : helperMissing.call(depth0, "__", "Your browser doesn’t support the audio player.", options)))
161
- + "\n";
162
- stack1 = helpers['if'].call(depth0, (depth0 && depth0.link), {hash:{},inverse:self.noop,fn:self.program(3, program3, data),data:data});
163
- if(stack1 || stack1 === 0) { buffer += stack1; }
164
- buffer += "\n</audio>\n";
165
- return buffer;
166
- });
167
- function audioTpl(data, options, asString) {
168
- var html = Template(data, options);
169
- return (asString || true) ? html : $(html);
170
- }
103
+ hb.registerHelper('property', function (name, context) {
104
+ return context[name] || '';
105
+ }); // register an 'includes' helper
106
+ // it checks if value is in array
171
107
 
172
- if (!Helpers0.__initialized) {
173
- Helpers0(Handlebars);
174
- Helpers0.__initialized = true;
175
- }
176
- var Template$1 = Handlebars.template(function (Handlebars,depth0,helpers,partials,data) {
177
- this.compilerInfo = [4,'>= 1.0.0'];
178
- helpers = this.merge(helpers, Handlebars.helpers); data = data || {};
179
- var buffer = "", stack1, helper, options, functionType="function", escapeExpression=this.escapeExpression, helperMissing=helpers.helperMissing, self=this;
180
-
181
- function program1(depth0,data) {
182
-
183
-
184
- return "crossorigin";
185
- }
186
-
187
- function program3(depth0,data) {
188
-
189
- var buffer = "", stack1, helper, options;
190
- buffer += "\n <a href=\"";
191
- if (helper = helpers.link) { stack1 = helper.call(depth0, {hash:{},data:data}); }
192
- else { helper = (depth0 && depth0.link); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }
193
- buffer += escapeExpression(stack1)
194
- + "\">"
195
- + escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "Please download the video and view offline.", options) : helperMissing.call(depth0, "__", "Please download the video and view offline.", options)))
196
- + "</a>\n";
197
- return buffer;
108
+ hb.registerHelper('includes', function (haystack, needle, options) {
109
+ if (_.contains(haystack, needle)) {
110
+ return options.fn(this);
198
111
  }
199
-
200
- buffer += "<video class=\"media video\" preload=\"";
201
- if (helper = helpers.preload) { stack1 = helper.call(depth0, {hash:{},data:data}); }
202
- else { helper = (depth0 && depth0.preload); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }
203
- buffer += escapeExpression(stack1)
204
- + "\" poster=\"";
205
- if (helper = helpers.poster) { stack1 = helper.call(depth0, {hash:{},data:data}); }
206
- else { helper = (depth0 && depth0.poster); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }
207
- buffer += escapeExpression(stack1)
208
- + "\" controls ";
209
- stack1 = helpers['if'].call(depth0, (depth0 && depth0.cors), {hash:{},inverse:self.noop,fn:self.program(1, program1, data),data:data});
210
- if(stack1 || stack1 === 0) { buffer += stack1; }
211
- buffer += ">\n "
212
- + escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "Your browser doesn’t support the video player.", options) : helperMissing.call(depth0, "__", "Your browser doesn’t support the video player.", options)))
213
- + "\n";
214
- stack1 = helpers['if'].call(depth0, (depth0 && depth0.link), {hash:{},inverse:self.noop,fn:self.program(3, program3, data),data:data});
215
- if(stack1 || stack1 === 0) { buffer += stack1; }
216
- buffer += "\n</video>\n";
217
- return buffer;
218
- });
219
- function videoTpl(data, options, asString) {
220
- var html = Template$1(data, options);
221
- return (asString || true) ? html : $(html);
112
+ });
113
+ }
114
+
115
+ if (!Helpers0.__initialized) {
116
+ Helpers0(Handlebars);
117
+ Helpers0.__initialized = true;
118
+ }
119
+ var Template = Handlebars.template(function (Handlebars,depth0,helpers,partials,data) {
120
+ this.compilerInfo = [4,'>= 1.0.0'];
121
+ helpers = this.merge(helpers, Handlebars.helpers); data = data || {};
122
+ var buffer = "", stack1, helper, options, functionType="function", escapeExpression=this.escapeExpression, helperMissing=helpers.helperMissing, self=this;
123
+
124
+ function program1(depth0,data) {
125
+
126
+
127
+ return "crossorigin";
222
128
  }
223
129
 
224
- if (!Helpers0.__initialized) {
225
- Helpers0(Handlebars);
226
- Helpers0.__initialized = true;
227
- }
228
- var Template$2 = Handlebars.template(function (Handlebars,depth0,helpers,partials,data) {
229
- this.compilerInfo = [4,'>= 1.0.0'];
230
- helpers = this.merge(helpers, Handlebars.helpers); data = data || {};
231
- var buffer = "", stack1, helper, functionType="function", escapeExpression=this.escapeExpression;
232
-
233
-
234
- buffer += "<source src=\"";
235
- if (helper = helpers.src) { stack1 = helper.call(depth0, {hash:{},data:data}); }
236
- else { helper = (depth0 && depth0.src); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }
237
- buffer += escapeExpression(stack1)
238
- + "\" type=\"";
239
- if (helper = helpers.type) { stack1 = helper.call(depth0, {hash:{},data:data}); }
240
- else { helper = (depth0 && depth0.type); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }
241
- buffer += escapeExpression(stack1)
242
- + "\">\n";
243
- return buffer;
244
- });
245
- function sourceTpl(data, options, asString) {
246
- var html = Template$2(data, options);
247
- return (asString || true) ? html : $(html);
130
+ function program3(depth0,data) {
131
+
132
+ var buffer = "", stack1, helper, options;
133
+ buffer += "\n <a href=\"";
134
+ if (helper = helpers.link) { stack1 = helper.call(depth0, {hash:{},data:data}); }
135
+ else { helper = (depth0 && depth0.link); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }
136
+ buffer += escapeExpression(stack1)
137
+ + "\">"
138
+ + escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "Please download the track and listen offline.", options) : helperMissing.call(depth0, "__", "Please download the track and listen offline.", options)))
139
+ + "</a>\n";
140
+ return buffer;
248
141
  }
249
142
 
250
- /**
251
- * This program is free software; you can redistribute it and/or
252
- * modify it under the terms of the GNU General Public License
253
- * as published by the Free Software Foundation; under version 2
254
- * of the License (non-upgradable).
255
- *
256
- * This program is distributed in the hope that it will be useful,
257
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
258
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
259
- * GNU General Public License for more details.
260
- *
261
- * You should have received a copy of the GNU General Public License
262
- * along with this program; if not, write to the Free Software
263
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
264
- *
265
- * Copyright (c) 2015-2021 (original work) Open Assessment Technologies SA ;
266
- */
267
- /**
268
- * CSS namespace
269
- * @type {string}
270
- */
143
+ buffer += "<audio class=\"media audio\" preload=\"";
144
+ if (helper = helpers.preload) { stack1 = helper.call(depth0, {hash:{},data:data}); }
145
+ else { helper = (depth0 && depth0.preload); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }
146
+ buffer += escapeExpression(stack1)
147
+ + "\" controls ";
148
+ stack1 = helpers['if'].call(depth0, (depth0 && depth0.cors), {hash:{},inverse:self.noop,fn:self.program(1, program1, data),data:data});
149
+ if(stack1 || stack1 === 0) { buffer += stack1; }
150
+ buffer += ">\n "
151
+ + escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "Your browser doesn’t support the audio player.", options) : helperMissing.call(depth0, "__", "Your browser doesn’t support the audio player.", options)))
152
+ + "\n";
153
+ stack1 = helpers['if'].call(depth0, (depth0 && depth0.link), {hash:{},inverse:self.noop,fn:self.program(3, program3, data),data:data});
154
+ if(stack1 || stack1 === 0) { buffer += stack1; }
155
+ buffer += "\n</audio>\n";
156
+ return buffer;
157
+ });
158
+ function audioTpl(data, options, asString) {
159
+ var html = Template(data, options);
160
+ return (asString || true) ? html : $(html);
161
+ }
162
+
163
+ if (!Helpers0.__initialized) {
164
+ Helpers0(Handlebars);
165
+ Helpers0.__initialized = true;
166
+ }
167
+ var Template$1 = Handlebars.template(function (Handlebars,depth0,helpers,partials,data) {
168
+ this.compilerInfo = [4,'>= 1.0.0'];
169
+ helpers = this.merge(helpers, Handlebars.helpers); data = data || {};
170
+ var buffer = "", stack1, helper, options, functionType="function", escapeExpression=this.escapeExpression, helperMissing=helpers.helperMissing, self=this;
171
+
172
+ function program1(depth0,data) {
173
+
174
+
175
+ return "crossorigin";
176
+ }
271
177
 
272
- const ns = '.mediaplayer';
273
- /**
274
- * Range value of the volume
275
- * @type {number}
276
- */
178
+ function program3(depth0,data) {
179
+
180
+ var buffer = "", stack1, helper, options;
181
+ buffer += "\n <a href=\"";
182
+ if (helper = helpers.link) { stack1 = helper.call(depth0, {hash:{},data:data}); }
183
+ else { helper = (depth0 && depth0.link); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }
184
+ buffer += escapeExpression(stack1)
185
+ + "\">"
186
+ + escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "Please download the video and view offline.", options) : helperMissing.call(depth0, "__", "Please download the video and view offline.", options)))
187
+ + "</a>\n";
188
+ return buffer;
189
+ }
277
190
 
278
- const volumeRange = 100;
279
- /**
280
- * Delay before considering a media stalled
281
- * @type {number}
282
- */
191
+ buffer += "<video class=\"media video\" preload=\"";
192
+ if (helper = helpers.preload) { stack1 = helper.call(depth0, {hash:{},data:data}); }
193
+ else { helper = (depth0 && depth0.preload); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }
194
+ buffer += escapeExpression(stack1)
195
+ + "\" poster=\"";
196
+ if (helper = helpers.poster) { stack1 = helper.call(depth0, {hash:{},data:data}); }
197
+ else { helper = (depth0 && depth0.poster); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }
198
+ buffer += escapeExpression(stack1)
199
+ + "\" controls ";
200
+ stack1 = helpers['if'].call(depth0, (depth0 && depth0.cors), {hash:{},inverse:self.noop,fn:self.program(1, program1, data),data:data});
201
+ if(stack1 || stack1 === 0) { buffer += stack1; }
202
+ buffer += ">\n "
203
+ + escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "Your browser doesn’t support the video player.", options) : helperMissing.call(depth0, "__", "Your browser doesn’t support the video player.", options)))
204
+ + "\n";
205
+ stack1 = helpers['if'].call(depth0, (depth0 && depth0.link), {hash:{},inverse:self.noop,fn:self.program(3, program3, data),data:data});
206
+ if(stack1 || stack1 === 0) { buffer += stack1; }
207
+ buffer += "\n</video>\n";
208
+ return buffer;
209
+ });
210
+ function videoTpl(data, options, asString) {
211
+ var html = Template$1(data, options);
212
+ return (asString || true) ? html : $(html);
213
+ }
214
+
215
+ if (!Helpers0.__initialized) {
216
+ Helpers0(Handlebars);
217
+ Helpers0.__initialized = true;
218
+ }
219
+ var Template$2 = Handlebars.template(function (Handlebars,depth0,helpers,partials,data) {
220
+ this.compilerInfo = [4,'>= 1.0.0'];
221
+ helpers = this.merge(helpers, Handlebars.helpers); data = data || {};
222
+ var buffer = "", stack1, helper, functionType="function", escapeExpression=this.escapeExpression;
223
+
224
+
225
+ buffer += "<source src=\"";
226
+ if (helper = helpers.src) { stack1 = helper.call(depth0, {hash:{},data:data}); }
227
+ else { helper = (depth0 && depth0.src); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }
228
+ buffer += escapeExpression(stack1)
229
+ + "\" type=\"";
230
+ if (helper = helpers.type) { stack1 = helper.call(depth0, {hash:{},data:data}); }
231
+ else { helper = (depth0 && depth0.type); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }
232
+ buffer += escapeExpression(stack1)
233
+ + "\">\n";
234
+ return buffer;
235
+ });
236
+ function sourceTpl(data, options, asString) {
237
+ var html = Template$2(data, options);
238
+ return (asString || true) ? html : $(html);
239
+ }
240
+
241
+ /**
242
+ * This program is free software; you can redistribute it and/or
243
+ * modify it under the terms of the GNU General Public License
244
+ * as published by the Free Software Foundation; under version 2
245
+ * of the License (non-upgradable).
246
+ *
247
+ * This program is distributed in the hope that it will be useful,
248
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
249
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
250
+ * GNU General Public License for more details.
251
+ *
252
+ * You should have received a copy of the GNU General Public License
253
+ * along with this program; if not, write to the Free Software
254
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
255
+ *
256
+ * Copyright (c) 2015-2021 (original work) Open Assessment Technologies SA ;
257
+ */
258
+ /**
259
+ * CSS namespace
260
+ * @type {string}
261
+ */
262
+
263
+ var ns = '.mediaplayer';
264
+ /**
265
+ * Range value of the volume
266
+ * @type {number}
267
+ */
268
+
269
+ var volumeRange = 100;
270
+ /**
271
+ * Delay before considering a media stalled
272
+ * @type {number}
273
+ */
274
+
275
+ var stalledDetectionDelay = 2000;
276
+ /**
277
+ * List of media events that can be listened to for debugging
278
+ * @type {string[]}
279
+ */
280
+
281
+ var mediaEvents = ['abort', 'canplay', 'canplaythrough', 'canshowcurrentframe', 'dataunavailable', 'durationchange', 'emptied', 'empty', 'ended', 'error', 'loadeddata', 'loadedfirstframe', 'loadedmetadata', 'loadstart', 'pause', 'play', 'playing', 'progress', 'ratechange', 'seeked', 'seeking', 'stalled', 'suspend', 'timeupdate', 'volumechange', 'waiting'];
282
+ /**
283
+ * List of player events that can be listened to for debugging
284
+ * @type {string[]}
285
+ */
286
+
287
+ var playerEvents = ['end', 'error', 'pause', 'play', 'playing', 'ready', 'resize', 'stalled', 'timeupdate'];
288
+ /**
289
+ * Defines a player object dedicated to the native HTML5 player
290
+ * @param {jQuery} $container - Where to render the player
291
+ * @param {object} config - The list of config entries
292
+ * @param {Array} config.sources - The list of media sources
293
+ * @param {string} [config.type] - The type of player (video or audio) (default: video)
294
+ * @param {boolean} [config.preview] - Enables the media preview (load media metadata)
295
+ * @param {boolean} [config.debug] - Enables the debug mode
296
+ * @param {number} [config.config.stalledDetectionDelay] - The delay before considering a media is stalled
297
+ * @returns {object} player
298
+ */
299
+
300
+ function html5PlayerFactory($container) {
301
+ var config = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
302
+ var type = config.type || 'video';
303
+ var sources = config.sources || [];
304
+ var updateObserver = reminderManagerFactory();
305
+ var timeObserver = timeObserverFactory();
306
+ config.stalledDetectionDelay = config.stalledDetectionDelay || stalledDetectionDelay;
307
+ var $media;
308
+ var media;
309
+ var state = {};
310
+
311
+ var getDebugContext = function getDebugContext(action) {
312
+ var networkState = media && media.networkState;
313
+ var readyState = media && media.readyState;
314
+ return "[html5-".concat(type, "(networkState=").concat(networkState, ",readyState=").concat(readyState, "):").concat(action, "]");
315
+ }; // eslint-disable-next-line
316
+
317
+
318
+ var debug = function debug(action) {
319
+ var _window$console;
320
+
321
+ for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
322
+ args[_key - 1] = arguments[_key];
323
+ }
283
324
 
284
- const stalledDetectionDelay = 2000;
285
- /**
286
- * List of media events that can be listened to for debugging
287
- * @type {string[]}
288
- */
325
+ return (config.debug === true || config.debug === action) && (_window$console = window.console).log.apply(_window$console, [getDebugContext(action)].concat(args));
326
+ };
327
+
328
+ return eventifier({
329
+ init: function init() {
330
+ var _this = this;
331
+
332
+ var tpl = 'audio' === type ? audioTpl : videoTpl;
333
+ var page = new UrlParser(window.location);
334
+ var cors = false;
335
+ var preload = config.preview ? 'metadata' : 'none';
336
+ var poster = '';
337
+ var link = '';
338
+ var result = false;
339
+ state = {};
340
+ sources.forEach(function (source) {
341
+ if (!page.sameDomain(source.src)) {
342
+ cors = true;
343
+ }
289
344
 
290
- const mediaEvents = ['abort', 'canplay', 'canplaythrough', 'canshowcurrentframe', 'dataunavailable', 'durationchange', 'emptied', 'empty', 'ended', 'error', 'loadeddata', 'loadedfirstframe', 'loadedmetadata', 'loadstart', 'pause', 'play', 'playing', 'progress', 'ratechange', 'seeked', 'seeking', 'stalled', 'suspend', 'timeupdate', 'volumechange', 'waiting'];
291
- /**
292
- * List of player events that can be listened to for debugging
293
- * @type {string[]}
294
- */
345
+ if (source.poster) {
346
+ poster = source.poster;
347
+ }
295
348
 
296
- const playerEvents = ['end', 'error', 'pause', 'play', 'playing', 'ready', 'resize', 'stalled', 'timeupdate'];
297
- /**
298
- * Defines a player object dedicated to the native HTML5 player
299
- * @param {jQuery} $container - Where to render the player
300
- * @param {object} config - The list of config entries
301
- * @param {Array} config.sources - The list of media sources
302
- * @param {string} [config.type] - The type of player (video or audio) (default: video)
303
- * @param {boolean} [config.preview] - Enables the media preview (load media metadata)
304
- * @param {boolean} [config.debug] - Enables the debug mode
305
- * @param {number} [config.config.stalledDetectionDelay] - The delay before considering a media is stalled
306
- * @returns {object} player
307
- */
349
+ if (source.link) {
350
+ link = source.link;
351
+ }
352
+ });
353
+ $media = $$1(tpl({
354
+ cors: cors,
355
+ preload: preload,
356
+ poster: poster,
357
+ link: link
358
+ }));
359
+ $container.append($media);
360
+ media = $media.get(0);
361
+ result = !!(media && support.checkSupport(media)); // Remove the browser native controls if we can use the API instead
362
+
363
+ if (support.canControl()) {
364
+ $media.removeAttr('controls');
365
+ } // Detect stalled video when the timer suddenly jump to the end
366
+
367
+
368
+ timeObserver.removeAllListeners().on('irregularity', function (position) {
369
+ if (state.playback && state.stallDetection) {
370
+ _this.stalled(position);
371
+ }
372
+ });
373
+ $media.on("play".concat(ns), function () {
374
+ state.playback = true;
375
+ state.playedViaApi = false;
376
+ timeObserver.init(media.currentTime, media.duration);
377
+
378
+ _this.trigger('play');
379
+ }).on("pause".concat(ns), function () {
380
+ if (state.stallDetection && !state.pausedViaApi && updateObserver.running && updateObserver.elapsed < 100) {
381
+ // The pause event may be triggered after a connectivity issue as the player is out of data
382
+ _this.stalled();
383
+ }
308
384
 
309
- function html5PlayerFactory($container) {
310
- let config = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
311
- const type = config.type || 'video';
312
- const sources = config.sources || [];
313
- const updateObserver = reminderManagerFactory();
314
- const timeObserver = timeObserverFactory();
315
- config.stalledDetectionDelay = config.stalledDetectionDelay || stalledDetectionDelay;
316
- let $media;
317
- let media;
318
- let state = {};
319
-
320
- const getDebugContext = action => {
321
- const networkState = media && media.networkState;
322
- const readyState = media && media.readyState;
323
- return `[html5-${type}(networkState=${networkState},readyState=${readyState}):${action}]`;
324
- }; // eslint-disable-next-line
325
-
326
-
327
- const debug = function (action) {
328
- for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
329
- args[_key - 1] = arguments[_key];
330
- }
385
+ state.pausedViaApi = false;
386
+ state.playing = false;
387
+ updateObserver.stop();
331
388
 
332
- return (config.debug === true || config.debug === action) && window.console.log(getDebugContext(action), ...args);
333
- };
334
-
335
- return eventifier({
336
- init() {
337
- const tpl = 'audio' === type ? audioTpl : videoTpl;
338
- const page = new UrlParser(window.location);
339
- let cors = false;
340
- let preload = config.preview ? 'metadata' : 'none';
341
- let poster = '';
342
- let link = '';
343
- let result = false;
344
- state = {};
345
- sources.forEach(source => {
346
- if (!page.sameDomain(source.src)) {
347
- cors = true;
348
- }
389
+ _this.trigger('pause');
390
+ }).on("seeked".concat(ns), function () {
391
+ // When the user try changing the current playing position while the network is down,
392
+ // the player will end the playback by moving straight to the end.
393
+ if (state.seekedViaApi && Math.floor(state.seekAt) !== Math.floor(media.currentTime)) {
394
+ state.stallDetection = true;
395
+ }
349
396
 
350
- if (source.poster) {
351
- poster = source.poster;
352
- }
397
+ state.seekedViaApi = false;
398
+ }).on("ended".concat(ns), function () {
399
+ updateObserver.forget().stop();
400
+ timeObserver.update(media.currentTime);
401
+ state.playback = false;
402
+ state.playing = false;
353
403
 
354
- if (source.link) {
355
- link = source.link;
356
- }
357
- });
358
- $media = $$1(tpl({
359
- cors,
360
- preload,
361
- poster,
362
- link
363
- }));
364
- $container.append($media);
365
- media = $media.get(0);
366
- result = !!(media && support.checkSupport(media)); // Remove the browser native controls if we can use the API instead
404
+ _this.trigger('end');
405
+ }).on("timeupdate".concat(ns), function () {
406
+ state.playing = true;
407
+ updateObserver.start();
408
+ timeObserver.update(media.currentTime);
367
409
 
368
- if (support.canControl()) {
369
- $media.removeAttr('controls');
370
- } // Detect stalled video when the timer suddenly jump to the end
410
+ _this.trigger('timeupdate');
411
+ }).on('loadstart', function () {
412
+ if (media.networkState === HTMLMediaElement.NETWORK_NO_SOURCE) {
413
+ _this.trigger('error');
414
+ }
371
415
 
416
+ if (!config.preview && media.networkState === HTMLMediaElement.NETWORK_IDLE) {
417
+ _this.trigger('ready');
418
+ } // The media may be unreachable straight from the beginning
419
+
420
+
421
+ _this.detectStalledNetwork();
422
+ }).on("waiting".concat(ns), function () {
423
+ // The "waiting" event means the player is pending data,
424
+ // it may be the symptom of a connectivity issue
425
+ _this.detectStalledNetwork();
426
+ }).on("error".concat(ns), function () {
427
+ if (media.networkState === HTMLMediaElement.NETWORK_NO_SOURCE || media.error instanceof MediaError && media.error.code === MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED) {
428
+ // No source means the player does not support the supplied media.
429
+ // Or it can be more explicit with the not supported error.
430
+ // There is nothing that we can do from this stage.
431
+ _this.trigger('error');
432
+ } else {
433
+ // Other errors need special attention as they can be recoverable
434
+ _this.handleError(media.error);
435
+ }
436
+ }).on('loadedmetadata', function () {
437
+ timeObserver.init(media.currentTime, media.duration);
372
438
 
373
- timeObserver.removeAllListeners().on('irregularity', position => {
374
- if (state.playback && state.stallDetection) {
375
- this.stalled(position);
376
- }
377
- });
378
- $media.on(`play${ns}`, () => {
379
- state.playback = true;
380
- state.playedViaApi = false;
381
- timeObserver.init(media.currentTime, media.duration);
382
- this.trigger('play');
383
- }).on(`pause${ns}`, () => {
384
- if (state.stallDetection && !state.pausedViaApi && updateObserver.running && updateObserver.elapsed < 100) {
385
- // The pause event may be triggered after a connectivity issue as the player is out of data
386
- this.stalled();
387
- }
439
+ _this.ready();
440
+ }).on("canplay".concat(ns), function () {
441
+ if (!state.stalled) {
442
+ _this.ready();
443
+ }
444
+ }).on("stalled".concat(ns), function () {
445
+ // The "stalled" event may be triggered once the player is halted after initialisation,
446
+ // but this does not mean the playback is actually stalled, hence we only take care of the playing state
447
+ if (state.playing && !media.paused) {
448
+ _this.handleError(media.error);
449
+ }
450
+ }).on("playing".concat(ns), function () {
451
+ if (state.stallDetection) {
452
+ // The "playing" event may occur after a connectivity issue.
453
+ // For the sake of the stall detection, we need to discard this event
454
+ return;
455
+ }
388
456
 
389
- state.pausedViaApi = false;
390
- state.playing = false;
391
- updateObserver.stop();
392
- this.trigger('pause');
393
- }).on(`seeked${ns}`, () => {
394
- // When the user try changing the current playing position while the network is down,
395
- // the player will end the playback by moving straight to the end.
396
- if (state.seekedViaApi && Math.floor(state.seekAt) !== Math.floor(media.currentTime)) {
397
- state.stallDetection = true;
398
- }
457
+ updateObserver.forget().start();
458
+ state.playing = true;
399
459
 
400
- state.seekedViaApi = false;
401
- }).on(`ended${ns}`, () => {
402
- updateObserver.forget().stop();
403
- timeObserver.update(media.currentTime);
404
- state.playback = false;
405
- state.playing = false;
406
- this.trigger('end');
407
- }).on(`timeupdate${ns}`, () => {
408
- state.playing = true;
409
- updateObserver.start();
410
- timeObserver.update(media.currentTime);
411
- this.trigger('timeupdate');
412
- }).on('loadstart', () => {
413
- if (media.networkState === HTMLMediaElement.NETWORK_NO_SOURCE) {
414
- this.trigger('error');
415
- }
460
+ _this.trigger('playing');
461
+ }); // install debug logger
416
462
 
417
- if (!config.preview && media.networkState === HTMLMediaElement.NETWORK_IDLE) {
418
- this.trigger('ready');
419
- } // The media may be unreachable straight from the beginning
420
-
421
-
422
- this.detectStalledNetwork();
423
- }).on(`waiting${ns}`, () => {
424
- // The "waiting" event means the player is pending data,
425
- // it may be the symptom of a connectivity issue
426
- this.detectStalledNetwork();
427
- }).on(`error${ns}`, () => {
428
- if (media.networkState === HTMLMediaElement.NETWORK_NO_SOURCE || media.error instanceof MediaError && media.error.code === MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED) {
429
- // No source means the player does not support the supplied media.
430
- // Or it can be more explicit with the not supported error.
431
- // There is nothing that we can do from this stage.
432
- this.trigger('error');
433
- } else {
434
- // Other errors need special attention as they can be recoverable
435
- this.handleError(media.error);
436
- }
437
- }).on('loadedmetadata', () => {
438
- timeObserver.init(media.currentTime, media.duration);
439
- this.ready();
440
- }).on(`canplay${ns}`, () => {
441
- if (!state.stalled) {
442
- this.ready();
443
- }
444
- }).on(`stalled${ns}`, () => {
445
- // The "stalled" event may be triggered once the player is halted after initialisation,
446
- // but this does not mean the playback is actually stalled, hence we only take care of the playing state
447
- if (state.playing && !media.paused) {
448
- this.handleError(media.error);
449
- }
450
- }).on(`playing${ns}`, () => {
451
- if (state.stallDetection) {
452
- // The "playing" event may occur after a connectivity issue.
453
- // For the sake of the stall detection, we need to discard this event
454
- return;
455
- }
456
-
457
- updateObserver.forget().start();
458
- state.playing = true;
459
- this.trigger('playing');
460
- }); // install debug logger
461
-
462
- if (config.debug) {
463
- debug('installed', media);
464
- mediaEvents.forEach(eventName => {
465
- $media.on(eventName + ns, e => debug('media event', eventName, media && media.currentSrc, e));
463
+ if (config.debug) {
464
+ debug('installed', media);
465
+ mediaEvents.forEach(function (eventName) {
466
+ $media.on(eventName + ns, function (e) {
467
+ return debug('media event', eventName, media && media.currentSrc, e);
466
468
  });
467
- playerEvents.forEach(eventName => {
468
- this.on(eventName, function () {
469
- for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
470
- args[_key2] = arguments[_key2];
471
- }
469
+ });
470
+ playerEvents.forEach(function (eventName) {
471
+ _this.on(eventName, function () {
472
+ for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
473
+ args[_key2] = arguments[_key2];
474
+ }
472
475
 
473
- return debug('player event', eventName, media && media.currentSrc, ...args);
474
- });
476
+ return debug.apply(void 0, ['player event', eventName, media && media.currentSrc].concat(args));
475
477
  });
476
- }
477
-
478
- result = result && sources.reduce((supported, source) => this.addMedia(source.src, source.type) || supported, false);
479
- return result;
480
- },
481
-
482
- handleError(error) {
483
- // Discard legitimate and non-blocking errors
484
- switch (error && error.name) {
485
- case 'NotAllowedError':
486
- debug('api call', 'handleError', 'the autoplay is not allowed without a user interaction', error);
487
- return;
488
-
489
- case 'AbortError':
490
- debug('api call', 'handleError', 'the action has been aborted for some reason', error);
491
- return;
492
- }
493
-
494
- debug('api call', 'handleError', error); // Detect if the playback can continue a bit
495
-
496
- const canContinueTemporarily = media && (media.readyState === HTMLMediaElement.HAVE_ENOUGH_DATA || media.readyState === HTMLMediaElement.HAVE_FUTURE_DATA || media.readyState === HTMLMediaElement.HAVE_CURRENT_DATA); // If a connectivity error occurs we may need to enter in stalled mode unless we can wait a bit
478
+ });
479
+ }
497
480
 
498
- if (error instanceof MediaError && (error.code === MediaError.MEDIA_ERR_NETWORK || error.code === MediaError.MEDIA_ERR_DECODE) && !canContinueTemporarily) {
499
- this.stalled();
481
+ result = result && sources.reduce(function (supported, source) {
482
+ return _this.addMedia(source.src, source.type) || supported;
483
+ }, false);
484
+ return result;
485
+ },
486
+ handleError: function handleError(error) {
487
+ var _this2 = this;
488
+
489
+ // Discard legitimate and non-blocking errors
490
+ switch (error && error.name) {
491
+ case 'NotAllowedError':
492
+ debug('api call', 'handleError', 'the autoplay is not allowed without a user interaction', error);
500
493
  return;
501
- } // To this point, there is a big chance the media is stalled.
502
- // We start an observer to remind as soon as an irregularity occurs on the time update
503
494
 
495
+ case 'AbortError':
496
+ debug('api call', 'handleError', 'the action has been aborted for some reason', error);
497
+ return;
498
+ }
504
499
 
505
- state.stallDetection = true;
506
- updateObserver.remind(() => {
507
- // The last time update is a bit old, the media is most probably stalled now
508
- if (updateObserver.elapsed >= config.stalledDetectionDelay) {
509
- this.stalled();
510
- }
511
- }, config.stalledDetectionDelay);
512
- updateObserver.start();
513
- },
500
+ debug('api call', 'handleError', error); // Detect if the playback can continue a bit
514
501
 
515
- ready() {
516
- if (!state.ready) {
517
- state.ready = true;
518
- this.trigger('ready');
519
- }
520
- },
521
-
522
- detectStalledNetwork() {
523
- // Install an observer that will watch the network state after a small delay.
524
- // It is needed since the network state may need time to settle.
525
- setTimeout(() => {
526
- if (media && media.networkState === HTMLMediaElement.NETWORK_NO_SOURCE && media.readyState === HTMLMediaElement.HAVE_NOTHING) {
527
- if (!state.ready) {
528
- this.trigger('ready');
529
- }
502
+ var canContinueTemporarily = media && (media.readyState === HTMLMediaElement.HAVE_ENOUGH_DATA || media.readyState === HTMLMediaElement.HAVE_FUTURE_DATA || media.readyState === HTMLMediaElement.HAVE_CURRENT_DATA); // If a connectivity error occurs we may need to enter in stalled mode unless we can wait a bit
530
503
 
531
- this.stalled();
532
- }
533
- }, config.stalledDetectionDelay);
534
- },
504
+ if (error instanceof MediaError && (error.code === MediaError.MEDIA_ERR_NETWORK || error.code === MediaError.MEDIA_ERR_DECODE) && !canContinueTemporarily) {
505
+ this.stalled();
506
+ return;
507
+ } // To this point, there is a big chance the media is stalled.
508
+ // We start an observer to remind as soon as an irregularity occurs on the time update
535
509
 
536
- stalled(position) {
537
- debug('api call', 'stalled');
538
510
 
539
- if (media) {
540
- if ('undefined' !== typeof position) {
541
- state.stalledAt = position;
542
- } else {
543
- state.stalledAt = timeObserver.position;
544
- }
511
+ state.stallDetection = true;
512
+ updateObserver.remind(function () {
513
+ // The last time update is a bit old, the media is most probably stalled now
514
+ if (updateObserver.elapsed >= config.stalledDetectionDelay) {
515
+ _this2.stalled();
545
516
  }
546
-
547
- state.stalled = true;
548
- state.stallDetection = false;
549
- updateObserver.forget().stop();
550
- this.pause();
551
- this.trigger('stalled');
552
- },
553
-
554
- recover() {
555
- debug('api call', 'recover');
556
- state.stalled = false;
557
- state.stallDetection = false;
558
-
559
- if (media) {
560
- // Special processing of video player to prevent visual glitch while reloading
561
- if (media.tagName === 'VIDEO') {
562
- // Temporarily set the size of the media to prevent a shrink while reloading it
563
- $media.width($media.width());
564
- $media.height($media.height());
565
- $media.on('loadedmetadata.recover', () => {
566
- $media.off('loadedmetadata.recover');
567
- $media.css({
568
- width: '',
569
- height: ''
570
- });
571
- });
572
- }
573
-
574
- media.load();
575
-
576
- if (state.stalledAt) {
577
- this.seek(state.stalledAt);
578
- }
579
-
580
- if (state.playback && !state.playing || state.playedViaApi) {
581
- this.play();
517
+ }, config.stalledDetectionDelay);
518
+ updateObserver.start();
519
+ },
520
+ ready: function ready() {
521
+ if (!state.ready) {
522
+ state.ready = true;
523
+ this.trigger('ready');
524
+ }
525
+ },
526
+ detectStalledNetwork: function detectStalledNetwork() {
527
+ var _this3 = this;
528
+
529
+ // Install an observer that will watch the network state after a small delay.
530
+ // It is needed since the network state may need time to settle.
531
+ setTimeout(function () {
532
+ if (media && media.networkState === HTMLMediaElement.NETWORK_NO_SOURCE && media.readyState === HTMLMediaElement.HAVE_NOTHING) {
533
+ if (!state.ready) {
534
+ _this3.trigger('ready');
582
535
  }
583
- }
584
- },
585
-
586
- destroy() {
587
- debug('api call', 'destroy');
588
- this.stop();
589
- this.removeAllListeners();
590
- updateObserver.forget();
591
- timeObserver.removeAllListeners();
592
536
 
593
- if ($media) {
594
- $media.off(ns).remove();
537
+ _this3.stalled();
595
538
  }
596
-
597
- $media = void 0;
598
- media = void 0;
599
- state = {};
600
- },
601
-
602
- getMedia() {
603
- debug('api call', 'getMedia', media);
604
- return media;
605
- },
606
-
607
- getMediaSize() {
608
- let size = {};
609
-
610
- if (media) {
611
- size = {
612
- width: media.videoWidth,
613
- height: media.videoHeight
614
- };
539
+ }, config.stalledDetectionDelay);
540
+ },
541
+ stalled: function stalled(position) {
542
+ debug('api call', 'stalled');
543
+
544
+ if (media) {
545
+ if ('undefined' !== typeof position) {
546
+ state.stalledAt = position;
547
+ } else {
548
+ state.stalledAt = timeObserver.position;
615
549
  }
550
+ }
616
551
 
617
- debug('api call', 'getMediaSize', size);
618
- return size;
619
- },
620
-
621
- getPosition() {
622
- let position = 0;
623
-
624
- if (media) {
625
- position = media.currentTime;
552
+ state.stalled = true;
553
+ state.stallDetection = false;
554
+ updateObserver.forget().stop();
555
+ this.pause();
556
+ this.trigger('stalled');
557
+ },
558
+ recover: function recover() {
559
+ debug('api call', 'recover');
560
+ state.stalled = false;
561
+ state.stallDetection = false;
562
+
563
+ if (media) {
564
+ // Special processing of video player to prevent visual glitch while reloading
565
+ if (media.tagName === 'VIDEO') {
566
+ // Temporarily set the size of the media to prevent a shrink while reloading it
567
+ $media.width($media.width());
568
+ $media.height($media.height());
569
+ $media.on('loadedmetadata.recover', function () {
570
+ $media.off('loadedmetadata.recover');
571
+ $media.css({
572
+ width: '',
573
+ height: ''
574
+ });
575
+ });
626
576
  }
627
577
 
628
- debug('api call', 'getPosition', position);
629
- return position;
630
- },
578
+ media.load();
631
579
 
632
- getDuration() {
633
- let duration = 0;
634
-
635
- if (media) {
636
- duration = media.duration;
580
+ if (state.stalledAt) {
581
+ this.seek(state.stalledAt);
637
582
  }
638
583
 
639
- debug('api call', 'getDuration', duration);
640
- return duration;
641
- },
642
-
643
- getVolume() {
644
- let volume = 0;
645
-
646
- if (media) {
647
- volume = parseFloat(media.volume) * volumeRange;
584
+ if (state.playback && !state.playing || state.playedViaApi) {
585
+ this.play();
648
586
  }
587
+ }
588
+ },
589
+ destroy: function destroy() {
590
+ debug('api call', 'destroy');
591
+ this.stop();
592
+ this.removeAllListeners();
593
+ updateObserver.forget();
594
+ timeObserver.removeAllListeners();
595
+
596
+ if ($media) {
597
+ $media.off(ns).remove();
598
+ }
649
599
 
650
- debug('api call', 'getVolume', volume);
651
- return volume;
652
- },
653
-
654
- setVolume(volume) {
655
- debug('api call', 'setVolume', volume);
600
+ $media = void 0;
601
+ media = void 0;
602
+ state = {};
603
+ },
604
+ getMedia: function getMedia() {
605
+ debug('api call', 'getMedia', media);
606
+ return media;
607
+ },
608
+ getMediaSize: function getMediaSize() {
609
+ var size = {};
610
+
611
+ if (media) {
612
+ size = {
613
+ width: media.videoWidth,
614
+ height: media.videoHeight
615
+ };
616
+ }
656
617
 
657
- if (media) {
658
- media.volume = parseFloat(volume) / volumeRange;
659
- }
660
- },
618
+ debug('api call', 'getMediaSize', size);
619
+ return size;
620
+ },
621
+ getPosition: function getPosition() {
622
+ var position = 0;
661
623
 
662
- setSize(width, height) {
663
- debug('api call', 'setSize', width, height);
664
- this.trigger('resize', width, height);
665
- },
624
+ if (media) {
625
+ position = media.currentTime;
626
+ }
666
627
 
667
- seek(time) {
668
- debug('api call', 'seek', time);
628
+ debug('api call', 'getPosition', position);
629
+ return position;
630
+ },
631
+ getDuration: function getDuration() {
632
+ var duration = 0;
669
633
 
670
- if (media) {
671
- media.currentTime = parseFloat(time);
672
- state.seekedViaApi = true;
673
- state.seekAt = media.currentTime;
674
- timeObserver.seek(media.currentTime);
634
+ if (media) {
635
+ duration = media.duration;
636
+ }
675
637
 
676
- if (!state.playback) {
677
- this.play();
678
- }
679
- }
680
- },
638
+ debug('api call', 'getDuration', duration);
639
+ return duration;
640
+ },
641
+ getVolume: function getVolume() {
642
+ var volume = 0;
681
643
 
682
- play() {
683
- debug('api call', 'play');
644
+ if (media) {
645
+ volume = parseFloat(media.volume) * volumeRange;
646
+ }
684
647
 
685
- if (media) {
686
- state.playedViaApi = true;
687
- const startPlayPromise = media.play();
648
+ debug('api call', 'getVolume', volume);
649
+ return volume;
650
+ },
651
+ setVolume: function setVolume(volume) {
652
+ debug('api call', 'setVolume', volume);
688
653
 
689
- if ('undefined' !== typeof startPlayPromise) {
690
- startPlayPromise.catch(error => this.handleError(error));
691
- }
654
+ if (media) {
655
+ media.volume = parseFloat(volume) / volumeRange;
656
+ }
657
+ },
658
+ setSize: function setSize(width, height) {
659
+ debug('api call', 'setSize', width, height);
660
+ this.trigger('resize', width, height);
661
+ },
662
+ seek: function seek(time) {
663
+ debug('api call', 'seek', time);
664
+
665
+ if (media) {
666
+ media.currentTime = parseFloat(time);
667
+ state.seekedViaApi = true;
668
+ state.seekAt = media.currentTime;
669
+ timeObserver.seek(media.currentTime);
670
+
671
+ if (!state.playback) {
672
+ this.play();
692
673
  }
693
- },
694
-
695
- pause() {
696
- debug('api call', 'pause');
697
-
698
- if (media) {
699
- if (!media.paused) {
700
- state.pausedViaApi = true;
701
- }
674
+ }
675
+ },
676
+ play: function play() {
677
+ var _this4 = this;
702
678
 
703
- media.pause();
704
- }
705
- },
679
+ debug('api call', 'play');
706
680
 
707
- stop() {
708
- debug('api call', 'stop');
681
+ if (media) {
682
+ state.playedViaApi = true;
683
+ var startPlayPromise = media.play();
709
684
 
710
- if (media && media.duration && state.playback && !state.stalled) {
711
- media.currentTime = media.duration;
685
+ if ('undefined' !== typeof startPlayPromise) {
686
+ startPlayPromise.catch(function (error) {
687
+ return _this4.handleError(error);
688
+ });
712
689
  }
713
- },
714
-
715
- mute(muted) {
716
- debug('api call', 'mute', muted);
690
+ }
691
+ },
692
+ pause: function pause() {
693
+ debug('api call', 'pause');
717
694
 
718
- if (media) {
719
- media.muted = !!muted;
695
+ if (media) {
696
+ if (!media.paused) {
697
+ state.pausedViaApi = true;
720
698
  }
721
- },
722
699
 
723
- isMuted() {
724
- let mute = false;
700
+ media.pause();
701
+ }
702
+ },
703
+ stop: function stop() {
704
+ debug('api call', 'stop');
725
705
 
726
- if (media) {
727
- mute = !!media.muted;
728
- }
706
+ if (media && media.duration && state.playback && !state.stalled) {
707
+ media.currentTime = media.duration;
708
+ }
709
+ },
710
+ mute: function mute(muted) {
711
+ debug('api call', 'mute', muted);
729
712
 
730
- debug('api call', 'isMuted', mute);
731
- return mute;
732
- },
713
+ if (media) {
714
+ media.muted = !!muted;
715
+ }
716
+ },
717
+ isMuted: function isMuted() {
718
+ var mute = false;
733
719
 
734
- addMedia(src, srcType) {
735
- debug('api call', 'addMedia', src, srcType);
720
+ if (media) {
721
+ mute = !!media.muted;
722
+ }
736
723
 
737
- if (media) {
738
- if (!support.checkSupport(media, srcType)) {
739
- return false;
740
- }
741
- }
724
+ debug('api call', 'isMuted', mute);
725
+ return mute;
726
+ },
727
+ addMedia: function addMedia(src, srcType) {
728
+ debug('api call', 'addMedia', src, srcType);
742
729
 
743
- if (src && $media) {
744
- $media.append(sourceTpl({
745
- src,
746
- type: srcType
747
- }));
748
- return true;
730
+ if (media) {
731
+ if (!support.checkSupport(media, srcType)) {
732
+ return false;
749
733
  }
734
+ }
750
735
 
751
- return false;
752
- },
753
-
754
- setMedia(src, srcType) {
755
- debug('api call', 'setMedia', src, srcType);
736
+ if (src && $media) {
737
+ $media.append(sourceTpl({
738
+ src: src,
739
+ type: srcType
740
+ }));
741
+ return true;
742
+ }
756
743
 
757
- if ($media) {
758
- $media.empty();
759
- return this.addMedia(src, srcType);
760
- }
744
+ return false;
745
+ },
746
+ setMedia: function setMedia(src, srcType) {
747
+ debug('api call', 'setMedia', src, srcType);
761
748
 
762
- return false;
749
+ if ($media) {
750
+ $media.empty();
751
+ return this.addMedia(src, srcType);
763
752
  }
764
753
 
765
- });
766
- }
754
+ return false;
755
+ }
756
+ });
757
+ }
767
758
 
768
- return html5PlayerFactory;
759
+ return html5PlayerFactory;
769
760
 
770
761
  });