jclic 2.2.0 → 2.3.0

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 (177) hide show
  1. package/README.md +5 -7
  2. package/dist-node/jclic-node.js +14157 -0
  3. package/dist-node/jclic-node.umd.cjs +530 -0
  4. package/package.json +38 -26
  5. package/.vscode/launch.json +0 -33
  6. package/.vscode/settings.json +0 -13
  7. package/CHANGELOG.md +0 -664
  8. package/TRANSLATIONS.md +0 -11
  9. package/build-locales.mjs +0 -82
  10. package/dist/jclic-node.js +0 -31678
  11. package/dist/jclic-node.js.map +0 -1
  12. package/dist/jclic.components.LICENSE +0 -2254
  13. package/dist/jclic.min.js +0 -27
  14. package/dist/jclic.min.js.map +0 -1
  15. package/eslint.config.mjs +0 -31
  16. package/jsdoc.config.js +0 -71
  17. package/locales/ar.po +0 -244
  18. package/locales/ast.po +0 -246
  19. package/locales/bs.po +0 -247
  20. package/locales/ca.po +0 -248
  21. package/locales/ca_ES@valencia.po +0 -248
  22. package/locales/cs.po +0 -244
  23. package/locales/da.po +0 -244
  24. package/locales/de.po +0 -246
  25. package/locales/el.po +0 -244
  26. package/locales/es.po +0 -248
  27. package/locales/eu.po +0 -244
  28. package/locales/fr.po +0 -244
  29. package/locales/gl.po +0 -244
  30. package/locales/he.po +0 -244
  31. package/locales/hr.po +0 -245
  32. package/locales/it.po +0 -246
  33. package/locales/ja.po +0 -242
  34. package/locales/jclic.js.pot +0 -241
  35. package/locales/nb_NO.po +0 -244
  36. package/locales/nl.po +0 -244
  37. package/locales/pl.po +0 -244
  38. package/locales/pt.po +0 -244
  39. package/locales/pt_BR.po +0 -248
  40. package/locales/ro.po +0 -248
  41. package/locales/ru.po +0 -245
  42. package/locales/ta.po +0 -244
  43. package/locales/tr.po +0 -246
  44. package/locales/uk.po +0 -247
  45. package/locales/vec.po +0 -244
  46. package/locales/zh_TW.po +0 -246
  47. package/patches/po2json+1.0.0-beta-3.patch +0 -12
  48. package/src/AWT.js +0 -2067
  49. package/src/Activity.js +0 -1311
  50. package/src/Deps.js +0 -232
  51. package/src/GlobalData.js +0 -5
  52. package/src/JClic.js +0 -196
  53. package/src/JClicPlayer.js +0 -1308
  54. package/src/PlayerHistory.js +0 -305
  55. package/src/Utils.js +0 -1355
  56. package/src/activities/associations/ComplexAssociation.js +0 -321
  57. package/src/activities/associations/SimpleAssociation.js +0 -519
  58. package/src/activities/memory/MemoryGame.js +0 -423
  59. package/src/activities/panels/Explore.js +0 -349
  60. package/src/activities/panels/Identify.js +0 -356
  61. package/src/activities/panels/InformationScreen.js +0 -262
  62. package/src/activities/panels/Menu.js +0 -209
  63. package/src/activities/panels/icons/ico00.png +0 -0
  64. package/src/activities/panels/icons/ico01.png +0 -0
  65. package/src/activities/panels/icons/ico02.png +0 -0
  66. package/src/activities/panels/icons/ico03.png +0 -0
  67. package/src/activities/panels/icons/icofolder.png +0 -0
  68. package/src/activities/puzzles/DoublePuzzle.js +0 -424
  69. package/src/activities/puzzles/ExchangePuzzle.js +0 -374
  70. package/src/activities/puzzles/HolePuzzle.js +0 -360
  71. package/src/activities/text/Complete.js +0 -127
  72. package/src/activities/text/Evaluator.js +0 -534
  73. package/src/activities/text/FillInBlanks.js +0 -426
  74. package/src/activities/text/IdentifyText.js +0 -253
  75. package/src/activities/text/OrderText.js +0 -421
  76. package/src/activities/text/TextActivityBase.js +0 -557
  77. package/src/activities/text/TextActivityDocument.js +0 -658
  78. package/src/activities/text/WrittenAnswer.js +0 -557
  79. package/src/activities/textGrid/CrossWord.js +0 -565
  80. package/src/activities/textGrid/WordSearch.js +0 -458
  81. package/src/activities/textGrid/icons/hIcon.svg +0 -3
  82. package/src/activities/textGrid/icons/vIcon.svg +0 -3
  83. package/src/automation/AutoContentProvider.js +0 -182
  84. package/src/automation/arith/Arith.js +0 -864
  85. package/src/bags/ActivitySequence.js +0 -318
  86. package/src/bags/ActivitySequenceElement.js +0 -161
  87. package/src/bags/ActivitySequenceJump.js +0 -140
  88. package/src/bags/ConditionalJumpInfo.js +0 -113
  89. package/src/bags/JumpInfo.js +0 -136
  90. package/src/bags/MediaBag.js +0 -215
  91. package/src/bags/MediaBagElement.js +0 -516
  92. package/src/boxes/AbstractBox.js +0 -699
  93. package/src/boxes/ActiveBagContent.js +0 -494
  94. package/src/boxes/ActiveBox.js +0 -810
  95. package/src/boxes/ActiveBoxBag.js +0 -357
  96. package/src/boxes/ActiveBoxContent.js +0 -484
  97. package/src/boxes/ActiveBoxGrid.js +0 -179
  98. package/src/boxes/BoxBag.js +0 -500
  99. package/src/boxes/BoxBase.js +0 -398
  100. package/src/boxes/BoxConnector.js +0 -325
  101. package/src/boxes/TextGrid.js +0 -887
  102. package/src/boxes/TextGridContent.js +0 -215
  103. package/src/init-jsdom.js +0 -65
  104. package/src/jclic-node.js +0 -219
  105. package/src/media/ActiveMediaBag.js +0 -145
  106. package/src/media/ActiveMediaPlayer.js +0 -297
  107. package/src/media/AudioBuffer.js +0 -219
  108. package/src/media/EventSounds.js +0 -169
  109. package/src/media/EventSoundsElement.js +0 -155
  110. package/src/media/MediaContent.js +0 -328
  111. package/src/media/MidiAudioPlayer.js +0 -254
  112. package/src/media/icons/audio.svg +0 -3
  113. package/src/media/icons/generic.svg +0 -3
  114. package/src/media/icons/mic.svg +0 -3
  115. package/src/media/icons/movie.svg +0 -3
  116. package/src/media/icons/music.svg +0 -3
  117. package/src/media/icons/url.svg +0 -3
  118. package/src/media/sounds/actionError.mp3 +0 -0
  119. package/src/media/sounds/actionOk.mp3 +0 -0
  120. package/src/media/sounds/click.mp3 +0 -0
  121. package/src/media/sounds/finishedError.mp3 +0 -0
  122. package/src/media/sounds/finishedOk.mp3 +0 -0
  123. package/src/media/sounds/start.mp3 +0 -0
  124. package/src/project/JClicProject.js +0 -282
  125. package/src/project/ProjectSettings.js +0 -273
  126. package/src/report/ActionReg.js +0 -123
  127. package/src/report/ActivityReg.js +0 -271
  128. package/src/report/EncryptMin.js +0 -210
  129. package/src/report/Reporter.js +0 -727
  130. package/src/report/SCORM.js +0 -272
  131. package/src/report/SequenceReg.js +0 -275
  132. package/src/report/SessionReg.js +0 -340
  133. package/src/report/SessionStorageReporter.js +0 -131
  134. package/src/report/TCPReporter.js +0 -628
  135. package/src/shapers/ClassicJigSaw.js +0 -138
  136. package/src/shapers/Holes.js +0 -77
  137. package/src/shapers/JigSaw.js +0 -161
  138. package/src/shapers/Rectangular.js +0 -78
  139. package/src/shapers/Shaper.js +0 -386
  140. package/src/shapers/TriangularJigSaw.js +0 -121
  141. package/src/skins/BlueSkin.js +0 -80
  142. package/src/skins/Counter.js +0 -152
  143. package/src/skins/CustomSkin.js +0 -412
  144. package/src/skins/DefaultSkin.js +0 -376
  145. package/src/skins/EmptySkin.js +0 -82
  146. package/src/skins/GreenSkin.js +0 -94
  147. package/src/skins/MiniSkin.js +0 -130
  148. package/src/skins/OrangeSkin.js +0 -78
  149. package/src/skins/SimpleSkin.js +0 -92
  150. package/src/skins/Skin.js +0 -1021
  151. package/src/skins/assets/actionsIcon.svg +0 -3
  152. package/src/skins/assets/appLogo.svg +0 -8
  153. package/src/skins/assets/basic.css +0 -41
  154. package/src/skins/assets/closeDialogIcon.svg +0 -3
  155. package/src/skins/assets/closeIcon.svg +0 -3
  156. package/src/skins/assets/copyIcon.svg +0 -3
  157. package/src/skins/assets/fullScreenExitIcon.svg +0 -3
  158. package/src/skins/assets/fullScreenIcon.svg +0 -3
  159. package/src/skins/assets/infoIcon.svg +0 -3
  160. package/src/skins/assets/main.css +0 -43
  161. package/src/skins/assets/mainHalf.css +0 -23
  162. package/src/skins/assets/mainTwoThirds.css +0 -23
  163. package/src/skins/assets/mini.css +0 -15
  164. package/src/skins/assets/nextIcon.svg +0 -3
  165. package/src/skins/assets/okDialogIcon.svg +0 -3
  166. package/src/skins/assets/prevIcon.svg +0 -3
  167. package/src/skins/assets/reports.css +0 -156
  168. package/src/skins/assets/reportsIcon.svg +0 -3
  169. package/src/skins/assets/scoreIcon.svg +0 -3
  170. package/src/skins/assets/simple.css +0 -16
  171. package/src/skins/assets/simpleHalf.css +0 -11
  172. package/src/skins/assets/simpleTwoThirds.css +0 -11
  173. package/src/skins/assets/timeIcon.svg +0 -4
  174. package/src/skins/assets/waitAnim.css +0 -54
  175. package/src/skins/assets/waitImgBig.svg +0 -3
  176. package/src/skins/assets/waitImgSmall.svg +0 -3
  177. package/webpack.config.mjs +0 -169
package/src/skins/Skin.js DELETED
@@ -1,1021 +0,0 @@
1
- /**
2
- * File : skins/Skin.js
3
- * Created : 29/04/2015
4
- * By : Francesc Busquets <francesc@gmail.com>
5
- *
6
- * JClic.js
7
- * An HTML5 player of JClic activities
8
- * https://projectestac.github.io/jclic.js
9
- *
10
- * @source https://github.com/projectestac/jclic.js
11
- *
12
- * @license EUPL-1.2
13
- * @licstart
14
- * (c) 2000-2020 Educational Telematic Network of Catalonia (XTEC)
15
- *
16
- * Licensed under the EUPL, Version 1.1 or -as soon they will be approved by
17
- * the European Commission- subsequent versions of the EUPL (the "Licence");
18
- * You may not use this work except in compliance with the Licence.
19
- *
20
- * You may obtain a copy of the Licence at:
21
- * https://joinup.ec.europa.eu/software/page/eupl
22
- *
23
- * Unless required by applicable law or agreed to in writing, software
24
- * distributed under the Licence is distributed on an "AS IS" basis, WITHOUT
25
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
26
- * Licence for the specific language governing permissions and limitations
27
- * under the Licence.
28
- * @licend
29
- * @module
30
- */
31
-
32
- /* global Promise, window, document, navigator, ClipboardItem, Blob */
33
-
34
- import $ from 'jquery';
35
- import { appendStyleAtHead, cloneObject, getMsg, setLogLevel, log, getRootHead, toCssSize, $HTML, getPercent, getHMStime, settings } from '../Utils.js';
36
- import { Container, Dimension, Rectangle } from '../AWT.js';
37
-
38
- // Use Webpack to import CSS and SVG files
39
- import basicCSS from './assets/basic.css';
40
- import waitAnimCSS from './assets/waitAnim.css';
41
- import reportsCSS from './assets/reports.css';
42
- import waitImgSmall from './assets/waitImgSmall.svg';
43
- import waitImgBig from './assets/waitImgBig.svg';
44
- import appLogo from './assets/appLogo.svg';
45
- import closeDialogIcon from './assets/closeDialogIcon.svg';
46
- import okDialogIcon from './assets/okDialogIcon.svg';
47
- import copyIcon from './assets/copyIcon.svg';
48
-
49
- /**
50
- * This abstract class manages the layout, position ans size of the visual components of JClic:
51
- * player window, message box, counters, buttons, status... and also the appearance of the main
52
- * container.
53
- * The basic implementation of Skin is {@link module:skins/DefaultSkin.DefaultSkin DefaultSkin}.
54
- * @abstract
55
- * @extends module:AWT.Container
56
- */
57
- export class Skin extends Container {
58
- /**
59
- * Skin constructor
60
- * @param {module:JClicPlayer.JClicPlayer} ps - The `PlayStation` (currently a {@link module:JClicPlayer.JClicPlayer JClicPlayer}) used to load and
61
- * realize the media objects needed tot build the Skin.
62
- * @param {string} [name] - The skin name
63
- * @param {object} [options] - Optional parameter with additional options
64
- */
65
- constructor(ps, name = null, options = {}) {
66
-
67
- // Skin extends [AWT.Container](AWT.html)
68
- super();
69
-
70
- // Save parameters for later use
71
- this.ps = ps;
72
- if (name !== null)
73
- this.name = name;
74
- this.options = options;
75
-
76
- if (this.options.skinId)
77
- this.skinId = this.options.skinId;
78
-
79
- if (!Skin.registerStyleSheet(this.skinId, ps)) {
80
- let css = this._getStyleSheets('default');
81
- let twoThirds = this._getStyleSheets('twoThirds');
82
- if (twoThirds.length > 0)
83
- css += ` @media (max-width:${this.twoThirdsMedia.width}px),(max-height:${this.twoThirdsMedia.height}px){${twoThirds}}`;
84
- let half = this._getStyleSheets('half');
85
- if (half.length > 0)
86
- css += ` @media (max-width:${this.halfMedia.width}px),(max-height:${this.halfMedia.height}px){${half}}`;
87
- appendStyleAtHead(css.replace(/\.ID/g, `.${this.skinId}`), ps);
88
- }
89
-
90
- let msg = '';
91
-
92
- this.$div = $('<div/>', { class: this.skinId });
93
- this.$playerCnt = $('<div/>', { class: 'JClicPlayerCnt' });
94
-
95
- // Add waiting panel and progress bar
96
- this.$progress = $('<progress/>', { class: 'progressBar' })
97
- .css({ display: 'none' });
98
- this.$waitPanel = $('<div/>')
99
- .css({ display: 'none', 'background-color': 'rgba(255, 255, 255, .60)', 'z-index': 99 })
100
- .append($('<div/>', { class: 'waitPanel' }).css({ display: 'flex', 'flex-direction': 'column' })
101
- .append($('<div/>', { class: 'animImgBox' })
102
- .append($(this.waitImgBig), $(this.waitImgSmall)))
103
- .append(this.$progress));
104
- this.$playerCnt.append(this.$waitPanel);
105
-
106
- this.buttons = cloneObject(Skin.prototype.buttons);
107
- this.counters = cloneObject(Skin.prototype.counters);
108
- this.msgArea = cloneObject(Skin.prototype.msgArea);
109
-
110
- // Create dialog overlay and panel
111
- this.$dlgOverlay = $('<div/>', { class: 'dlgOverlay' }).css({
112
- 'z-index': 98,
113
- position: 'fixed',
114
- left: 0,
115
- top: 0,
116
- width: '100%',
117
- height: '100%',
118
- display: 'none',
119
- 'background-color': 'rgba(30,30,30,0.7)'
120
- }).on('click', () => {
121
- if (!this._isModalDlg)
122
- // Non-modal dialogs are closed on click outside the main area
123
- this._closeDlg(true);
124
- return false;
125
- });
126
-
127
- const $dlgDiv = $('<div/>', {
128
- class: 'dlgDiv',
129
- role: 'dialog',
130
- 'aria-labelledby': ps.getUniqueId('ReportsLb'),
131
- 'aria-describedby': ps.getUniqueId('ReportsCnt')
132
- }).css({
133
- display: 'inline-block',
134
- position: 'relative',
135
- top: '50%',
136
- left: '50%',
137
- transform: 'translate(-50%, -50%)'
138
- }).on('click', () => {
139
- // Clicks not passed to parent
140
- return false;
141
- });
142
-
143
- this.$dlgMainPanel = $('<div/>', { class: 'dlgMainPanel', id: ps.getUniqueId('ReportsCnt') });
144
- this.$dlgBottomPanel = $('<div/>', { class: 'dlgBottomPanel', role: 'navigation' });
145
-
146
- // Basic dialog structure:
147
- this.$div.append(
148
- this.$playerCnt,
149
- this.$dlgOverlay.append(
150
- $dlgDiv.append(
151
- this.$dlgMainPanel,
152
- this.$dlgBottomPanel)));
153
-
154
- msg = getMsg('JClic logo');
155
- this.$infoHead = $('<div/>', { class: 'infoHead' })
156
- .append($('<div/>', { class: 'headTitle unselectableText' })
157
- .append($(this.appLogo, { 'aria-label': msg }).css({ width: '1.5em', height: '1.5em', 'vertical-align': 'bottom' })
158
- .on('dblclick', () => {
159
- // Double click on JClic logo is a hidden method to increase verbosity on Javascript console
160
- setLogLevel('all');
161
- log('trace', 'Log level set to "trace"');
162
- }))
163
- .append($('<span/>').html('JClic.js')))
164
- .append($('<p/>').css({ 'margin-top': 0, 'margin-left': '3.5em' })
165
- .append($('<a/>', { href: 'https://projectes.xtec.cat/clic/' }).html('https://projectes.xtec.cat/clic/'))
166
- .append($('<br>'))
167
- .append($('<span/>').html(`${getMsg('Version')} ${settings.VERSION}`)));
168
-
169
- this.$reportsPanel = $('<div/>', { class: 'reportsPanel', role: 'document' });
170
-
171
- msg = getMsg('Copy data to clipboard');
172
- this.$copyBtn = $('<button/>', { title: msg, 'aria-label': msg })
173
- .append($(this.copyIcon).css({ width: '26px', height: '26px' }))
174
- .on('click', () => {
175
- const item = new ClipboardItem({
176
- 'text/plain': new Blob([`===> ${getMsg('The data has been copied in HTML format. Please paste them into a spreadsheet or in a rich text editor')} <===`], {type: 'text/plain'}),
177
- 'text/html': new Blob([this.$reportsPanel.html()], {type: 'text/html'}),
178
- });
179
- navigator.clipboard.write([item])
180
- .then(() => this.$copyBtn.parent().append(
181
- $('<div/>', { class: 'smallPopup' })
182
- .html(getMsg('The data has been copied to clipboard'))
183
- .fadeIn()
184
- .delay(3000)
185
- .fadeOut(function () { $(this).remove(); })))
186
- .catch(err => this.$copyBtn.parent().append(
187
- $('<div/>', { class: 'smallPopup' })
188
- .html(`ERROR: Unable to write data into the clipboard: ${err}`)
189
- .fadeIn()
190
- .delay(3000)
191
- .fadeOut(function () { $(this).remove(); })));
192
- });
193
-
194
- msg = getMsg('Close');
195
- this.$closeDlgBtn = $('<button/>', { title: msg, 'aria-label': msg })
196
- .append($(this.closeDialogIcon).css({ width: '26px', height: '26px' }))
197
- .on('click', () => this._closeDlg(true));
198
-
199
- msg = getMsg('OK');
200
- this.$okDlgBtn = $('<button/>', { title: msg, 'aria-label': msg })
201
- .append($(this.okDialogIcon).css({ width: '26px', height: '26px' }))
202
- .on('click', () => this._closeDlg(true));
203
-
204
- msg = getMsg('Cancel');
205
- this.$cancelDlgBtn = $('<button/>', { title: msg, 'aria-label': msg })
206
- .append($(this.closeDialogIcon).css({ width: '26px', height: '26px' }))
207
- .on('click', () => this._closeDlg(false));
208
-
209
- // Registers this Skin in the list of realized Skin objects
210
- Skin.skinStack.push(this);
211
- }
212
-
213
- /**
214
- * Registers a new type of skin
215
- * @param {string} skinName - The name used to identify this skin
216
- * @param {function} skinClass - The skin class, usually extending Skin
217
- * @returns {module:skins/Skin.Skin} - The provided skin class
218
- */
219
- static registerClass(skinName, skinClass) {
220
- Skin.CLASSES[skinName] = skinClass;
221
- return skinClass;
222
- }
223
-
224
- /**
225
- * Checks if the provided stylesheet ID is already registered in the root node where the current player is placed
226
- * @param {string} skinId - The unique identifier of the skin to check
227
- * @param {module:JClicPlayer.JClicPlayer} [ps] - An optional `PlayStation` (currently a {@link module:JClicPlayer.JClicPlayer JClicPlayer}) used as a base to find the root node
228
- * @returns {boolean} - _true_ when the skin stylesheet is already defined in the current root node, _false_ otherwise
229
- */
230
- static registerStyleSheet(skinId, ps) {
231
- let result = false;
232
- const root = getRootHead(ps);
233
- if (!root['__JClicID'])
234
- root.__JClicID = `SK${Skin.lastId++}`;
235
-
236
- let styles = Skin.rootStyles[root.__JClicID];
237
- if (!styles) {
238
- styles = [];
239
- Skin.rootStyles[root.__JClicID] = styles;
240
- }
241
-
242
- if (styles.indexOf(skinId) < 0) {
243
- log('trace', `Stylesheet "${skinId}" has been registered for root node labeled as "${root.__JClicID}"`);
244
- styles.push(skinId);
245
- } else
246
- result = true;
247
-
248
- return result;
249
- }
250
-
251
- /**
252
- * Gets the specified Skin from `skinStack`, or creates a new one if not found.
253
- * This function should be used only through `Skin.getSkin`
254
- * @param {string} skinName - The name of the searched skin
255
- * @param {module:JClicPlayer.JClicPlayer} ps - The PlayStation (usually a {@link module:JClicPlayer.JClicPlayer JClicPlayer}) used to build the new skin.
256
- * @param {object} [options] - Optional parameter with additional options
257
- * @returns {module:skins/Skin.Skin}
258
- */
259
- static getSkin(skinName = 'default', ps, options = {}) {
260
- skinName = skinName || 'default';
261
-
262
- // Correct old skin names
263
- if (skinName.charAt(0, 1) === '@' && skinName.endsWith('.xml'))
264
- skinName = skinName.substring(1, skinName.length - 4);
265
-
266
- // look for the skin in the stack of realized skins
267
- if (skinName && ps) {
268
- // TODO: Check also `options`!
269
- const sk = Skin.skinStack.find(s => s.name === skinName && s.ps === ps);
270
- if (sk)
271
- return sk;
272
- }
273
-
274
- // Locates the class of the requested Skin (or [DefaultSkin](DefaultSkin.html)
275
- // if not specified). When not found, a new one is created and registered in `skinStack`
276
- let cl = Skin.CLASSES[skinName];
277
- if (!cl) {
278
- // Process custom skin XML files
279
- const mbe = ps.project.mediaBag.getElement(skinName, false);
280
- if (mbe && mbe.data) {
281
- options = Object.assign({}, options, mbe.data);
282
- options.skinId = `JClic-${skinName.replace('.xml', '')}`;
283
- }
284
-
285
- if (!ps.zip
286
- && options.class === 'edu.xtec.jclic.skins.BasicSkin'
287
- && options.image
288
- && ps.project.mediaBag.getElement(options.image, false)
289
- && ps.project.mediaBag.getElement(options.image, false).data)
290
- cl = Skin.CLASSES.custom;
291
- else {
292
- log('warn', `Unknown skin class: ${skinName}`);
293
- cl = Skin.CLASSES.default;
294
- }
295
- }
296
-
297
- // Build and return the requested skin
298
- return new cl(ps, skinName, options);
299
- }
300
-
301
- /**
302
- * Returns the CSS styles used by this skin. This method should be called only from
303
- * the `Skin` constructor, and overridded by subclasses if needed.
304
- * @param {string} media - A specific media size. Possible values are: 'default', 'half' and 'twoThirds'
305
- * @returns {string}
306
- */
307
- _getStyleSheets(media = 'default') {
308
- return media === 'default' ? (this.basicCSS + this.waitAnimCSS + this.reportsCSS) : '';
309
- }
310
-
311
- /**
312
- * Attaches a {@link module:JClicPlayer.JClicPlayer JClicPlayer} object to this Skin
313
- * @param {module:JClicPlayer.JClicPlayer} player
314
- */
315
- attach(player) {
316
- this.detach();
317
- if (player !== null && player.skin !== null)
318
- player.skin.detach();
319
- this.player = player;
320
- this.$playerCnt.prepend(player.$div);
321
- this.setSkinSizes();
322
- player.$mainContainer.append(this.$div);
323
- }
324
-
325
- /**
326
- * Sets the 'size' CSS values (max, min and compulsory) to the main `div` of this skin
327
- * @param {boolean} full - `true` when the skin is in full screen mode
328
- */
329
- setSkinSizes(full) {
330
- const
331
- css = {},
332
- topHeight = this.player?.$topDiv.height() || 0,
333
- nilValue = this.player.fullScreenChecked ? 'inherit' : null;
334
-
335
- // When `full` no set, detect the current status
336
- if (typeof full === 'undefined')
337
- full = document && document.fullscreenElement ? true : false;
338
-
339
- toCssSize(full ? '100vw' : this.ps.options.minWidth, css, 'min-width', nilValue);
340
- toCssSize(full ? '100vh' : this.ps.options.minHeight, css, 'min-height', nilValue);
341
- toCssSize(full ? '100vw' : this.ps.options.maxWidth, css, 'max-width', nilValue);
342
- toCssSize(full ? '100vh' : this.ps.options.maxHeight, css, 'max-height', nilValue);
343
- toCssSize(full ? '100vw' : this.ps.options.width, css, 'width', '100%');
344
- toCssSize(full ? '100vh' : this.ps.options.height, css, 'height', topHeight > 0 ? '100%' : '100vh');
345
- this.$div.css(css);
346
- }
347
-
348
- /**
349
- * Detaches the `player` element from this Skin
350
- */
351
- detach() {
352
- if (this.player !== null) {
353
- this.player.$div.remove();
354
- this.$div.detach();
355
- this.player = null;
356
- }
357
- }
358
-
359
- /**
360
- * Updates the graphic contents of this skin.
361
- * This method should be called from {@link module:skins/Skin.Skin#update}
362
- * @override
363
- * @param {module:AWT.Rectangle} dirtyRegion - Specifies the area to be updated. When `null`, it's the
364
- * whole panel.
365
- */
366
- updateContent(dirtyRegion) {
367
- if (this.$msgBoxDivCanvas) {
368
- const ctx = this.$msgBoxDivCanvas.get(-1).getContext('2d');
369
- ctx.clearRect(0, 0, ctx.canvas.clientWidth, ctx.canvas.clientHeight);
370
- this.msgBox.update(ctx, dirtyRegion);
371
- }
372
- return super.updateContent();
373
- }
374
-
375
- /**
376
- * Resets all counters
377
- * @param {boolean} bEnabled - Leave it enabled/disabled
378
- */
379
- resetAllCounters(bEnabled) {
380
- $.each(this.counters, (_name, counter) => {
381
- if (counter !== null) {
382
- counter.value = 0;
383
- counter.countDown = 0;
384
- counter.enabled = bEnabled;
385
- counter.refreshDisplay();
386
- }
387
- });
388
- }
389
-
390
- /**
391
- * Sets/unsets the 'wait' state
392
- * @param {boolean} status - Whether to set or unset the wait status. When `undefined`, the
393
- * `waitCursorCount` member is evaluated to decide if the wait state should be activated or deactivated.
394
- */
395
- setWaitCursor(status) {
396
- if (typeof status === 'undefined') {
397
- if (this.$waitPanel)
398
- this.$waitPanel.css({
399
- display: this.waitCursorCount > 0 ? 'initial' : 'none'
400
- });
401
- } else {
402
- switch (status) {
403
- case true:
404
- this.waitCursorCount++;
405
- break;
406
- case false:
407
- if (--this.waitCursorCount < 0)
408
- this.waitCursorCount = 0;
409
- break;
410
- case 'reset':
411
- this.waitCursorCount = 0;
412
- break;
413
- }
414
- this.setWaitCursor();
415
- }
416
- }
417
-
418
- /**
419
- * Sets the current value of the progress bar
420
- * @param {number} val - The current value. Should be less or equal than `max`. When -1, the progress bar will be hidden.
421
- * @param {number} [max] - Optional parameter representing the maximum value. When passed, the progress bar will be displayed.
422
- */
423
- setProgress(val, max) {
424
- if (this.$progress) {
425
- this.currentProgress = val;
426
- if (val < 0)
427
- this.$progress.css({ display: 'none' });
428
- else {
429
- if (max) {
430
- this.maxProgress = max;
431
- this.$progress.attr('max', max).css({ display: 'initial' });
432
- }
433
- this.$progress.attr('value', val);
434
- }
435
- log('trace', `Progress: ${this.currentProgress}/${this.maxProgress}`);
436
- }
437
- }
438
-
439
- /**
440
- * Increments the progress bar value by the specified amount, only when the progress bar is running.
441
- * @param {number} [val] - The amount to increment. When not defined, it's 1.
442
- */
443
- incProgress(val) {
444
- if (this.currentProgress >= 0)
445
- this.setProgress(this.currentProgress + (val || 1));
446
- }
447
-
448
- /**
449
- * Shows a window with clues or help for the current activity
450
- * @param {external:jQuery} _$hlpComponent - A JQuery DOM element with the information to be shown.
451
- * It can be a string or number. When `null`, the help window (if any) must be closed.
452
- */
453
- showHelp(_$hlpComponent) {
454
- // TODO: Implement HelpWindow
455
- }
456
-
457
- /**
458
- * Shows a "dialog" panel, useful for displaying information or prompt something to users
459
- * @param {boolean} modal - When `true`, the dialog should be closed by any click outside the main panel
460
- * @param {object} options - This object should have two components: `main` and `bottom`, both
461
- * containing a jQuery HTML element (or array of elements) to be placed on the main and bottom panels
462
- * of the dialog.
463
- * @returns {external:Promise} - A Promise that will be fulfilled when the dialog is closed.
464
- */
465
- showDlg(modal, options) {
466
- return new Promise((resolve, reject) => {
467
- this._dlgOkValue = 'ok';
468
- this._dlgCancelValue = 'cancelled';
469
- this._isModalDlg = modal;
470
-
471
- this.$dlgMainPanel.children().detach();
472
- this.$dlgBottomPanel.children().detach();
473
- if (options.main)
474
- this.$dlgMainPanel.append(options.main);
475
- if (options.bottom)
476
- this.$dlgBottomPanel.append(options.bottom);
477
-
478
- this._closeDlg = resolved => {
479
- if (resolved && resolve)
480
- resolve(this._dlgOkValue);
481
- else if (!resolved && reject)
482
- reject(this._dlgCancelValue);
483
- this.$dlgOverlay.css({ display: 'none' });
484
- this.enableMainButtons(true);
485
- this._closeDlg = Skin.prototype._closeDlg;
486
- };
487
- this.enableMainButtons(false);
488
- this.$dlgOverlay.css({ display: 'initial' });
489
- });
490
- }
491
-
492
- /**
493
- * Enables or disables the `tabindex` attribute of the main buttons. Useful when a modal dialog
494
- * overlay is active, to avoid direct access to controls not related with the dialog.
495
- * @param {boolean} status - `true` to make main controls navigable, `false` otherwise
496
- */
497
- enableMainButtons(status) {
498
- this.$playerCnt.find('button').attr('tabindex', status ? '0' : '-1');
499
- }
500
-
501
- /**
502
- * Called when the dialog must be closed, usually only by Skin members.
503
- * This method is re-defined on each call to `showDlg`, so the `resolve` and `reject`
504
- * functions can be safely called.
505
- */
506
- _closeDlg() {
507
- // Do nothing
508
- }
509
-
510
- /**
511
- * Displays a dialog with a report of the current results achieved by the user.
512
- * @param {module:report/Reporter.Reporter} reporter - The reporter system currently in use
513
- * @returns {external:Promise} - The Promise returned by {@link module:skins/Skin.Skin.showDlg}.
514
- */
515
- showReports(reporter) {
516
- this.$reportsPanel.html(this.$printReport(reporter));
517
- return this.showDlg(false, {
518
- main: [this.$infoHead, this.$reportsPanel],
519
- bottom: [this.$copyBtn, this.$closeDlgBtn]
520
- });
521
- }
522
-
523
- /**
524
- * Formats the current report in a DOM tree, ready to be placed in `$reportsPanel`
525
- * @param {module:report/Reporter.Reporter} reporter - The reporter system currently in use
526
- * @returns {external:jQuery[]} - An array of jQuery objects containing the full report
527
- */
528
- $printReport(reporter) {
529
- let result = [];
530
- if (reporter) {
531
- const
532
- report = reporter.getData(),
533
- started = new Date(report.started);
534
-
535
- result.push($('<div/>', { class: 'subTitle', id: this.ps.getUniqueId('ReportsLb') }).html(getMsg('Current results')));
536
-
537
- const $t = $('<table/>', { class: 'JCGlobalResults' });
538
- $t.append(
539
- $HTML.doubleCell(
540
- getMsg('Session started:'),
541
- `${started.toLocaleDateString()} ${started.toLocaleTimeString()}`),
542
- $HTML.doubleCell(
543
- getMsg('Reports system:'),
544
- `${getMsg(report.descriptionKey)} ${report.descriptionDetail}`));
545
- if (report.userId)
546
- $t.append($HTML.doubleCell(
547
- getMsg('User:'),
548
- report.userId));
549
- else if (report.user) // SCORM user
550
- $t.append($HTML.doubleCell(
551
- getMsg('User:'),
552
- report.user));
553
-
554
- if (report.sequences > 0) {
555
- if (report.sessions.length > 1)
556
- $t.append($HTML.doubleCell(
557
- getMsg('Projects:'),
558
- report.sessions.length));
559
- $t.append(
560
- $HTML.doubleCell(
561
- getMsg('Sequences:'),
562
- report.sequences),
563
- $HTML.doubleCell(
564
- getMsg('Activities done:'),
565
- report.activitiesDone),
566
- $HTML.doubleCell(
567
- getMsg('Activities played at least once:'),
568
- `${report.playedOnce}/${report.reportable} (${getPercent(report.ratioPlayed / 100)})`));
569
- if (report.activitiesDone > 0) {
570
- $t.append($HTML.doubleCell(
571
- getMsg('Activities solved:'),
572
- `${report.activitiesSolved} (${getPercent(report.ratioSolved / 100)})`));
573
- if (report.actScore > 0)
574
- $t.append(
575
- $HTML.doubleCell(
576
- getMsg('Partial score:'),
577
- `${getPercent(report.partialScore / 100)} ${getMsg('(out of played activities)')}`),
578
- $HTML.doubleCell(
579
- getMsg('Global score:'),
580
- `${getPercent(report.globalScore / 100)} ${getMsg('(out of all project activities)')}`));
581
- $t.append(
582
- $HTML.doubleCell(
583
- getMsg('Total time in activities:'),
584
- getHMStime(report.time * 1000)),
585
- $HTML.doubleCell(
586
- getMsg('Actions done:'),
587
- report.actions));
588
- }
589
- result.push($t);
590
-
591
- report.sessions.forEach(sr => {
592
- if (sr.sequences.length > 0) {
593
- const $t = $('<table/>', { class: 'JCDetailed' });
594
- result.push($('<p/>').html(report.sessions.length > 1 ? `${getMsg('Project')} ${sr.projectName}` : ''));
595
- $t.append($('<thead/>').append($('<tr/>').append(
596
- $HTML.th(getMsg('sequence')),
597
- $HTML.th(getMsg('activity')),
598
- $HTML.th(getMsg('OK')),
599
- $HTML.th(getMsg('actions')),
600
- $HTML.th(getMsg('score')),
601
- $HTML.th(getMsg('time')))));
602
-
603
- sr.sequences.forEach(seq => {
604
- let $tr = $('<tr/>').append($('<td/>', { rowspan: seq.activities.length }).html(seq.sequence));
605
- seq.activities.forEach(act => {
606
- if (act.closed) {
607
- $tr.append($HTML.td(act.name));
608
- $tr.append(act.solved ? $HTML.td(getMsg('YES'), 'ok') : $HTML.td(getMsg('NO'), 'no'));
609
- $tr.append($HTML.td(act.actions));
610
- $tr.append($HTML.td(getPercent(act.precision / 100)));
611
- $tr.append($HTML.td(getHMStime(act.time * 1000)));
612
- } else {
613
- $tr.append($HTML.td(act.name, 'incomplete'));
614
- for (let r = 0; r < 4; r++)
615
- $tr.append($HTML.td('-', 'incomplete'));
616
- }
617
- $t.append($tr);
618
- $tr = $('<tr/>');
619
- });
620
- });
621
-
622
- $t.append($('<tr/>').append(
623
- $HTML.td(getMsg('Total:')),
624
- $HTML.td(`${sr.played} (${getPercent(sr.ratioPlayed / 100)})`),
625
- $HTML.td(`${sr.solved} (${getPercent(sr.ratioSolved / 100)})`),
626
- $HTML.td(sr.actions),
627
- $HTML.td(getPercent(sr.score / 100)),
628
- $HTML.td(getHMStime(sr.time * 1000))));
629
-
630
- result.push($t);
631
- }
632
- }, this);
633
- } else
634
- result.push($('<p/>').html(getMsg('No activities done!')));
635
- }
636
- return result;
637
- }
638
-
639
- /**
640
- * Enables or disables a specific counter
641
- * @param {string} counter - Which counter
642
- * @param {boolean} bEnabled - When `true`, the counter will be enabled.
643
- */
644
- enableCounter(counter, bEnabled) {
645
- if (this.counters[counter])
646
- this.counters[counter].setEnabled(bEnabled);
647
- }
648
-
649
- /**
650
- * Main method used to build the content of the skin. Resizes and places internal objects.
651
- */
652
- doLayout() {
653
- // Resize player
654
- this.player.doLayout();
655
-
656
- // Build ths canvas at the end of current thread, thus avoiding
657
- // invalid sizes due to incomplete layout of DOM objects
658
- if (this.$msgBoxDiv)
659
- window.setTimeout(() => {
660
-
661
- // Temporary remove canvas to let div get its natural size:
662
- if (this.$msgBoxDivCanvas)
663
- this.$msgBoxDivCanvas.remove();
664
-
665
- // Get current size of message box div without canvas
666
- const
667
- msgWidth = this.$msgBoxDiv.outerWidth(),
668
- msgHeight = this.$msgBoxDiv.outerHeight();
669
-
670
- // Replace existing canvas if size has changed
671
- if (this.$msgBoxDivCanvas === null ||
672
- this.msgBox.dim.widht !== msgWidth ||
673
- this.msgBox.dim.height !== msgHeight) {
674
- this.$msgBoxDivCanvas = $(`<canvas width="${msgWidth}" height="${msgHeight}"/>`);
675
- this.msgBox.setBounds(new Rectangle(0, 0, msgWidth + 1, msgHeight));
676
- this.msgBox.buildAccessibleElement(this.$msgBoxDivCanvas, this.$msgBoxDiv);
677
- }
678
- // restore canvas
679
- this.$msgBoxDiv.append(this.$msgBoxDivCanvas);
680
- this.updateContent();
681
- }, 0);
682
- }
683
-
684
- /**
685
- * adjusts the skin to the dimension of its `$div` container
686
- * @returns {module:AWT.Dimension} the new dimension of the skin
687
- */
688
- fit() {
689
- this.doLayout();
690
- return new Dimension(this.$div.width(), this.$div.height());
691
- }
692
-
693
- /**
694
- * Sets or unsets the player in fullscreen mode, when allowed, using the
695
- * {@link https://github.com/sindresorhus/screenfull.js|screenfull.js} library.
696
- * @param {boolean} status - Whether to set or unset the player in fullscreen mode. When `null`
697
- * or `undefined`, the status toggles between fullscreen and windowed modes.
698
- * @returns {boolean} `true` if the request was successful, `false` otherwise.
699
- */
700
- setScreenFull(status) {
701
- if (document && document.fullscreenEnabled && (
702
- status === true && !document.fullscreenElement ||
703
- status === false && !document.fullscreenElement ||
704
- status !== true && status !== false)) {
705
- // Save current value of fullScreen for later use
706
- const full = document.fullscreenElement ? true : false;
707
- if (!document.fullscreenElement) {
708
- const element = this.player.$mainContainer.get(-1);
709
- if (element && element.requestFullscreen)
710
- element.requestFullscreen();
711
- } else {
712
- if (document.exitFullscreen) {
713
- document.exitFullscreen();
714
- }
715
- }
716
- this.player.fullScreenChecked = true;
717
- // Firefox don't updates `document.fullscreenElement` in real time, so use the saved value instead
718
- this.setSkinSizes(!full);
719
- }
720
- }
721
-
722
- /**
723
- * Method used to notify this skin that a specific action has changed its enabled/disabled status
724
- * @param {module:AWT.Action} _action - The action originating the change event
725
- */
726
- actionStatusChanged(act) {
727
- if (act.name && this.buttons[act.name])
728
- this.setEnabled(this.buttons[act.name], act.enabled);
729
- }
730
-
731
- /**
732
- * Enables or disables an object
733
- * @param {external:jQuery} $object - A JQuery DOM element
734
- * @override
735
- * @param {boolean} enabled
736
- */
737
- setEnabled($object, enabled) {
738
- if ($object)
739
- $object.prop('disabled', enabled ? null : true);
740
- }
741
-
742
- /**
743
- * Compares two Skin objects
744
- * @param {module:skins/Skin.Skin} skin - The Skin to compare against this
745
- * @returns {boolean} - `true` if both skins are equivalent.
746
- */
747
- equals(skin) {
748
- return skin &&
749
- this.name === skin.name &&
750
- this.ps === skin.ps;
751
- }
752
-
753
- /**
754
- * Gets the {@link module:boxes/ActiveBox.ActiveBox ActiveBox} used to display the main messages of activities
755
- * @returns {module:boxes/ActiveBox.ActiveBox}
756
- */
757
- getMsgBox() {
758
- return this.msgBox;
759
- }
760
- }
761
-
762
- /**
763
- * Collection of realized __Skin__ objects.
764
- * @type {module:skins/Skin.Skin[]}
765
- */
766
- Skin.skinStack = [];
767
-
768
- /**
769
- * Collection of skin style sheets already registered on the current document
770
- * @type {object}
771
- */
772
- Skin.rootStyles = {};
773
-
774
- /**
775
- * Counter used to label root nodes with unique IDs
776
- * @type {number}
777
- */
778
- Skin.lastId = 1;
779
-
780
- /**
781
- * List of classes derived from Skin. It should be filled by real skin classes at declaration time.
782
- * @type {object}
783
- */
784
- Skin.CLASSES = {};
785
-
786
- Object.assign(Skin.prototype, {
787
- /**
788
- * Class name of this skin. It will be used as a base selector in the definition of all CSS styles.
789
- * @name module:skins/Skin.Skin#skinId
790
- * @type {string} */
791
- skinId: 'JClicBasicSkin',
792
- /**
793
- * The HTML div object used by this Skin
794
- * @name module:skins/Skin.Skin#$div
795
- * @type {external:jQuery} */
796
- $div: null,
797
- /**
798
- * The HTML div where JClic Player will be placed
799
- * @name module:skins/Skin.Skin#$playerCnt
800
- * @type {external:jQuery} */
801
- $playerCnt: null,
802
- /**
803
- * Current name of the skin.
804
- * @name module:skins/Skin.Skin#name
805
- * @type {string} */
806
- name: 'default',
807
- /**
808
- * Specific options of this skin
809
- * @name module:skins/Skin.Skin#options
810
- * @type {object} */
811
- options: {},
812
- /**
813
- * Waiting panel, displayed while loading resources.
814
- * @name module:skins/Skin.Skin#$waitPanel
815
- * @type {external:jQuery} */
816
- $waitPanel: null,
817
- /**
818
- * Graphic indicator of loading progress
819
- * @name module:skins/Skin.Skin#$progress
820
- * @type {external:jQuery} */
821
- $progress: null,
822
- /**
823
- * Current value of the progress bar
824
- * @name module:skins/Skin.Skin#currentProgress
825
- * @type {number} */
826
- currentProgress: -1,
827
- /**
828
- * Max value of the progress bar
829
- * @name module:skins/Skin.Skin#maxProgress
830
- * @type {number} */
831
- maxProgress: 0,
832
- /**
833
- * The box used to display the main messages of JClic activities
834
- * @name module:skins/Skin.DefaultSkin#msgBox
835
- * @type {module:boxes/ActiveBox.ActiveBox} */
836
- msgBox: null,
837
- /**
838
- * The `div` DOM object where `msgBox` is located
839
- * @name module:skins/Skin.DefaultSkin#$msgBoxDiv
840
- * @type {external:jQuery} */
841
- $msgBoxDiv: null,
842
- /*
843
- * An HTML `canvas` object created in `$msgBoxDiv`
844
- * @name module:skins/Skin.DefaultSkin#$msgBoxDivCanvas
845
- * @type {external:jQuery} */
846
- $msgBoxDivCanvas: null,
847
- /**
848
- * Main panel used to display modal and non-modal dialogs
849
- * @name module:skins/Skin.Skin#$dlgOverlay
850
- * @type {external:jQuery} */
851
- $dlgOverlay: null,
852
- /**
853
- * Main panel of dialogs, where relevant information must be placed
854
- * @name module:skins/Skin.Skin#$dlgMainPanel
855
- * @type {external:jQuery} */
856
- $dlgMainPanel: null,
857
- /**
858
- * Bottom panel of dialogs, used for action buttons
859
- * @name module:skins/Skin.Skin#$dlgBottomPanel
860
- * @type {external:jQuery} */
861
- $dlgBottomPanel: null,
862
- /**
863
- * Element usually used as header in dialogs, with JClic logo, name and version
864
- * @name module:skins/Skin.Skin#infoHead
865
- * @type {external:jQuery} */
866
- $infoHead: null,
867
- /**
868
- * Iconic button used to copy content to clipboard
869
- * @name module:skins/Skin.Skin#$copyBtn
870
- * @type {external:jQuery} */
871
- $copyBtn: null,
872
- /**
873
- * Iconic button used to close the dialog
874
- * @name module:skins/Skin.Skin#$closeDlgBtn
875
- * @type {external:jQuery} */
876
- $closeDlgBtn: null,
877
- /**
878
- * OK dialog button
879
- * @name module:skins/Skin.Skin#$okDlgBtn
880
- * @type {external:jQuery} */
881
- $okDlgBtn: null,
882
- /**
883
- * Cancel dialog button
884
- * @name module:skins/Skin.Skin#$cancelDlgBtn
885
- * @type {external:jQuery} */
886
- $cancelDlgBtn: null,
887
- /**
888
- * Value to be returned by the dialog promise when the presented task is fulfilled
889
- * @name module:skins/Skin.Skin#_dlgOkValue
890
- * @type {object} */
891
- _dlgOkValue: null,
892
- /**
893
- * Value to be returned in user-canceled dialogs
894
- * @name module:skins/Skin.Skin#_dlgCancelValue
895
- * @type {object} */
896
- _dlgCancelValue: null,
897
- /**
898
- * Flag indicating if the current dialog is modal or not
899
- * @name module:skins/Skin.Skin#_isModalDlg
900
- * @type {boolean} */
901
- _isModalDlg: false,
902
- /**
903
- * Div inside {@link module:skins/Skin.Skin#$dlgOverlay $dlgOverlay} where JClicPlayer will place the information to be shown
904
- * @name module:skins/Skin.Skin#$reportsPanel
905
- * @type {external:jQuery} */
906
- $reportsPanel: null,
907
- /**
908
- * The basic collection of buttons that most skins implement
909
- * @name module:skins/Skin.Skin#buttons
910
- * @type {object} */
911
- buttons: {
912
- 'prev': null,
913
- 'next': null,
914
- 'return': null,
915
- 'reset': null,
916
- 'info': null,
917
- 'help': null,
918
- 'audio': null,
919
- 'about': null,
920
- 'fullscreen': null,
921
- 'close': null
922
- },
923
- /**
924
- * The collection of counters
925
- * @name module:skins/Skin.Skin#counters
926
- * @type {object} */
927
- counters: {
928
- 'actions': null,
929
- 'score': null,
930
- 'time': null
931
- },
932
- /**
933
- * The collection of message areas
934
- * @name module:skins/Skin.Skin#msgArea
935
- * @type {object} */
936
- msgArea: {
937
- 'main': null,
938
- 'aux': null,
939
- 'mem': null
940
- },
941
- /**
942
- * The {@link module:JClicPlayer.JClicPlayer JClicPlayer} object associated to this skin
943
- * @name module:skins/Skin.Skin#player
944
- * @type {module:JClicPlayer.JClicPlayer} */
945
- player: null,
946
- /**
947
- * The {@link http://projectestac.github.io/jclic/apidoc/edu/xtec/jclic/PlayStation.html|PlayStation}
948
- * used by this Skin. Usually, the same as `player`
949
- * @name module:skins/Skin.Skin#ps
950
- * @type {module:JClicPlayer.JClicPlayer} */
951
- ps: null,
952
- /**
953
- * Counter to be incremented or decremented as `waitCursor` is requested or released.
954
- * @name module:skins/Skin.Skin#waitCursorCount
955
- * @type {number} */
956
- waitCursorCount: 0,
957
- //
958
- // Buttons and other graphical resources used by this skin.
959
- //
960
- /**
961
- * Main styles
962
- * @name module:skins/Skin.Skin#basicCSS
963
- * @type {string} */
964
- basicCSS,
965
- /**
966
- * Waiting screen styles
967
- * @name module:skins/Skin.Skin#waitAnimCSS
968
- * @type {string} */
969
- waitAnimCSS,
970
- /**
971
- * Animated image displayed while loading resources
972
- * Based on Ryan Allen's [svg-spinner](http://articles.dappergentlemen.com/2015/01/13/svg-spinner/)
973
- * @name module:skins/Skin.Skin#waitImgBig
974
- * @type {string} */
975
- waitImgBig,
976
- /**
977
- * Animated image displayed while loading resources (small)
978
- * @name module:skins/Skin.Skin#waitImgSmall
979
- * @type {string} */
980
- waitImgSmall,
981
- /**
982
- * Reports screen styles
983
- * @name module:skins/Skin.Skin#reportsCSS
984
- * @type {string} */
985
- reportsCSS,
986
- //
987
- // Icons used in buttons:
988
- //
989
- /**
990
- * Icon for 'close dialog' button
991
- * @name module:skins/Skin.Skin#closeDialogIcon
992
- * @type {string} */
993
- closeDialogIcon,
994
- /**
995
- * Icon for 'ok' button
996
- * @name module:skins/Skin.Skin#okDialogIcon
997
- * @type {string} */
998
- okDialogIcon,
999
- /**
1000
- * Icon for 'copy' button
1001
- * @name module:skins/Skin.Skin#copyIcon
1002
- * @type {string} */
1003
- copyIcon,
1004
- /**
1005
- * JClic logo
1006
- * @name module:skins/Skin.Skin#appLogo
1007
- * @type {string} */
1008
- appLogo,
1009
- /**
1010
- * Screen sizes (width and height) below which will half sized elements will be used
1011
- * @name module:skins/Skin.DefaultSkin#halfMedia
1012
- * @type {object} */
1013
- halfMedia: { width: 376, height: 282 },
1014
- /**
1015
- * Screen sizes (width and height) below which will two-thirds sized elements will be used
1016
- * @name module:skins/Skin.DefaultSkin#twoThirdsMedia
1017
- * @type {object} */
1018
- twoThirdsMedia: { width: 420, height: 315 },
1019
- });
1020
-
1021
- export default Skin;