jclic 2.2.1 → 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 -672
  8. package/TRANSLATIONS.md +0 -11
  9. package/build-locales.mjs +0 -82
  10. package/dist/jclic-node.js +0 -31680
  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 -660
  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
@@ -1,152 +0,0 @@
1
- /**
2
- * File : skins/Counter.js
3
- * Created : 07/05/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
- /**
33
- * This class encapsulates the operation of a numeric counter, used to display the current
34
- * values of score, actions and time.
35
- */
36
- export class Counter {
37
- /**
38
- * Counter constructor
39
- * @param {string} id - The type of information stored on this counter
40
- * @param {external:jQuery} [$div] - The HTML element where this counter will show values (can be _null_)
41
- */
42
- constructor(id, $div) {
43
- if (id)
44
- this.id = id;
45
- if ($div)
46
- this.$div = $div;
47
- }
48
-
49
- /**
50
- * Gets the current display value of this counter
51
- * @returns {number}
52
- */
53
- getDisplayValue() {
54
- let result = this.countDown > 0 ? this.countDown - this.value : this.value;
55
- if (this.displayDiffFrom)
56
- result = result - this.displayDiffFrom.value;
57
- return Math.max(0, Math.min(this.MAX_DISPLAY_VALUE, result));
58
- }
59
-
60
- /**
61
- * Paints the value of this counter on screen
62
- * (method to be overridden by subclasses)
63
- */
64
- refreshDisplay() {
65
- if (this.$div)
66
- this.$div.html(this.enabled ? (this.getDisplayValue() + 1000).toString().substring(1) : '000');
67
- }
68
-
69
- /**
70
- * Enables or disables this counter
71
- * @param {boolean} enabled - State been assigned to this counter
72
- */
73
- setEnabled(enabled) {
74
- if (this.enabled !== enabled) {
75
- this.enabled = enabled;
76
- if (this.$div) {
77
- this.refreshDisplay();
78
- this.$div.css('opacity', this.enabled ? 1.0 : 0.3);
79
- }
80
- }
81
- }
82
-
83
- /**
84
- * Sets the initial value of the counter
85
- * @param {number} maxValue - Value from which the countdown will start
86
- */
87
- setCountDown(maxValue) {
88
- if (this.countDown !== (this.countDown = maxValue))
89
- this.refreshDisplay();
90
- }
91
-
92
- /**
93
- * Increments by one the value of this counter
94
- */
95
- incValue() {
96
- this.value++;
97
- if (this.enabled)
98
- this.refreshDisplay();
99
- }
100
-
101
- /**
102
- * Sets a specific value to this counter
103
- * @param {number} value - The value to set
104
- */
105
- setValue(value) {
106
- if (this.enabled && this.value !== (this.value = value))
107
- this.refreshDisplay();
108
- }
109
- }
110
-
111
- Object.assign(Counter.prototype, {
112
- /**
113
- * Type of counter (usually: `score`, `actions` or `time`)
114
- * @name module:skins/Counter.Counter#id
115
- * @type {string} */
116
- id: '',
117
- /**
118
- * The HTML element where this counter shows its value
119
- * @name module:skins/Counter.Counter#$div
120
- * @type {external:jQuery}
121
- */
122
- $div: null,
123
- /**
124
- * Current value of this counter
125
- * @name module:skins/Counter.Counter#value
126
- * @type {number} */
127
- value: 0,
128
- /**
129
- * When set, the counter displays a countdown from this value to zero
130
- * @name module:skins/Counter.Counter#countDown
131
- * @type {number} */
132
- countDown: 0,
133
- /**
134
- * Flag indicating if this counter is currently enabled
135
- * @name module:skins/Counter.Counter#enabled
136
- * @type {boolean} */
137
- enabled: true,
138
- /**
139
- * Maximum value to be displayed by this counter
140
- * @name module:skins/Counter.Counter#MAX_DISPLAY_VALUE
141
- * @type {number} */
142
- MAX_DISPLAY_VALUE: 999,
143
- /**
144
- * An optional Counter used as a subtractor to display the current value.
145
- * Useful to display `errors` subtracting `score` from `actions`.
146
- * @name module:skins/Counter.Counter#displayDiffFrom
147
- * @type {module:skins/Counter.Counter}
148
- */
149
- displayDiffFrom: null,
150
- });
151
-
152
- export default Counter;
@@ -1,412 +0,0 @@
1
- /**
2
- * File : skins/CustomSkin.js
3
- * Created : 12/02/2018
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
- import $ from 'jquery';
33
- import Skin from './Skin.js';
34
- import Counter from './Counter.js';
35
- import { getMsg, checkColor, getImgClipUrl } from '../Utils.js';
36
- import { Rectangle } from '../AWT.js';
37
- import ActiveBox from '../boxes/ActiveBox.js';
38
-
39
- /**
40
- * Custom {@link module:skins/Skin.Skin Skin} for JClic.js, built assembling specific cuts of a canvas (usually a PNG file) defined in an XML file
41
- * @extends module:skins/Skin.Skin
42
- */
43
- export class CustomSkin extends Skin {
44
-
45
- /**
46
- * CustomSkin constructor
47
- *
48
- * @param {module:JClicPlayer.JClicPlayer} ps - The PlayStation (currently a {@link module:JClicPlayer.JClicPlayer JClicPlayer}) used to load and
49
- * realize the media objects needed tot build the Skin.
50
- * @param {string} [name] - The skin class name
51
- * @param {object} [options] - Optional parameter with additional options
52
- */
53
- constructor(ps, name = null, options = null) {
54
- // CustomSkin extends [Skin](Skin.html)
55
- super(ps, name, options);
56
- //console.log(this.options)
57
-
58
- this.$mainPanel = $('<div/>', { class: 'JClicCustomMainPanel' });
59
- this.$gridPanel = $('<div/>', { class: 'JClicGridPanel' });
60
- for (let i = 0; i < 9; i++)
61
- this.$gridPanel.append($('<div/>', { class: `JClicCell JClicCell${i + 1}` }));
62
- this.$mainPanel.append(this.$gridPanel);
63
- this.$playerCnt.detach().addClass('JClicPlayerCell').appendTo(this.$mainPanel);
64
- this.$div.prepend(this.$mainPanel);
65
-
66
- // Add buttons
67
- if (options.buttons) {
68
- Object.keys(options.buttons.button).forEach(k => {
69
- const k2 = k === 'about' ? 'reports' : k;
70
- const msg = getMsg(this.msgKeys[k2] || k2);
71
- this.buttons[k2] = $('<button/>', { class: `JClicBtn JClicTransform Btn-${k2}`, title: msg, 'aria-label': msg, disabled: typeof this.msgKeys[k2] === 'undefined' })
72
- .on('click', evt => { if (ps.actions[k2]) ps.actions[k2].processEvent(evt); });
73
- this.$mainPanel.append(this.buttons[k2]);
74
- });
75
- }
76
-
77
- // Add message box
78
- if (options.rectangle.messages) {
79
- this.msgBox = new ActiveBox();
80
- this.msgBox.role = 'message';
81
- this.$msgBoxDiv = $('<div/>', { class: 'JClicMsgBox' })
82
- .on('click', () => {
83
- this.msgBox.playMedia(ps);
84
- return false;
85
- });
86
- this.$mainPanel.append(this.$msgBoxDiv);
87
- }
88
-
89
- // Add counters
90
- if (false !== this.ps.options.counters && options.counters && options.counters.counter) {
91
- $.each(Skin.prototype.counters, (name, _val) => {
92
- if (options.counters.counter[name]) {
93
- const msg = getMsg(name);
94
- this.counters[name] = new Counter(name, $('<div/>', { class: `JClicCounter JClicTransform Counter-${name}`, title: msg, 'aria-label': msg })
95
- .html('000')
96
- .appendTo(this.$mainPanel));
97
- }
98
- });
99
- }
100
-
101
- // Add progress animation
102
- if (options.progressAnimation) {
103
- this.$progressAnimation = $('<div/>', { class: 'JClicProgressAnimation JClicTransform' });
104
- this.$mainPanel.append(this.$progressAnimation);
105
- }
106
-
107
- }
108
-
109
- /**
110
- * Enables or disables the `tabindex` attribute of the main buttons. Useful when a modal dialog
111
- * overlay is active, to avoid direct access to controls not related with the dialog.
112
- * @param {boolean} status - `true` to make main controls navigable, `false` otherwise
113
- */
114
- enableMainButtons(status) {
115
- this.$mainPanel.find('.JClicBtn').attr('tabindex', status ? '0' : '-1');
116
- }
117
-
118
- /**
119
- * Computes the CSS styles used by this skin in thre moodes: main, half ant twoThirds.
120
- * The resulting strings will be stored in `cssVariants`
121
- * @returns {string}
122
- */
123
- _computeStyleSheets() {
124
- const
125
- maxw = this.options.dimension.preferredSize.width,
126
- maxh = this.options.dimension.preferredSize.height;
127
-
128
- this.twoThirdsMedia = { width: maxw, height: maxh };
129
- this.halfMedia = {
130
- width: Math.round(2 * maxw / 3),
131
- height: Math.round(2 * maxh / 3)
132
- };
133
-
134
- // Panels:
135
- const
136
- ph0 = this.options.rectangle.frame.left,
137
- ph1 = ph0 + this.options.rectangle.player.left,
138
- ph2 = ph0 + this.options.slicer.left,
139
- ph3 = ph0 + this.options.slicer.right,
140
- ph4 = ph1 + this.options.rectangle.player.width,
141
- ph5 = ph0 + this.options.rectangle.frame.width,
142
- pv0 = this.options.rectangle.frame.top,
143
- pv1 = pv0 + this.options.rectangle.player.top,
144
- pv2 = pv0 + this.options.slicer.top,
145
- pv3 = pv0 + this.options.slicer.bottom,
146
- pv4 = pv1 + this.options.rectangle.player.height,
147
- pv5 = pv0 + this.options.rectangle.frame.height,
148
- imgElement = this.ps.project.mediaBag.getElement(this.options.image, true),
149
- imgUrl = imgElement.data && imgElement.data.src ? imgElement.data.src : '',
150
- box1 = imgElement.data ? getImgClipUrl(imgElement.data, new Rectangle(ph0, pv0, ph2 - ph0, pv2 - pv0)) : '',
151
- box2 = imgElement.data ? getImgClipUrl(imgElement.data, new Rectangle(ph2 - ph0, pv0, ph3 - ph2, pv2 - pv0)) : '',
152
- box3 = imgElement.data ? getImgClipUrl(imgElement.data, new Rectangle(ph3, pv0, ph5 - ph3, pv2 - pv0)) : '',
153
- box4 = imgElement.data ? getImgClipUrl(imgElement.data, new Rectangle(ph0, pv2 - pv0, ph2 - ph0, pv3 - pv2)) : '',
154
- box6 = imgElement.data ? getImgClipUrl(imgElement.data, new Rectangle(ph3 - ph0, pv2 - pv0, ph5 - ph3, pv3 - pv2)) : '',
155
- box7 = imgElement.data ? getImgClipUrl(imgElement.data, new Rectangle(ph0, pv3 - pv0, ph2 - ph0, pv5 - pv3)) : '',
156
- box8 = imgElement.data ? getImgClipUrl(imgElement.data, new Rectangle(ph2 - ph0, pv3 - pv0, ph3 - ph2, pv5 - pv3)) : '',
157
- box9 = imgElement.data ? getImgClipUrl(imgElement.data, new Rectangle(ph3, pv3 - pv0, ph5 - ph3, pv5 - pv3)) : '';
158
-
159
- let css = `
160
- .ID .JClicCustomMainPanel {flex-grow:1;position:relative;background-color: ${checkColor(this.options.color.fill.value)};}
161
- .ID .JClicGridPanel {position:absolute;width:100%;height:100%;display:grid;grid-template-columns:${ph2 - ph0}px 1fr ${ph5 - ph3}px;grid-template-rows:${pv2 - pv0}px 1fr ${pv5 - pv3}px;}
162
- .ID .JClicCell {background-repeat:no-repeat;background-size:contain;}
163
- .ID .JClicPlayerCell {position:absolute;top:${pv1 - pv0}px;right:${ph5 - ph4}px;bottom:${pv5 - pv4}px;left:${ph1 - ph0}px;}
164
- .ID .JClicCell1 {background-image:url(${box1});}
165
- .ID .JClicCell2 {background-image:url(${box2});background-repeat:repeat-x;}
166
- .ID .JClicCell3 {background-image:url(${box3});}
167
- .ID .JClicCell4 {background-image:url(${box4});background-repeat:repeat-y;}
168
- .ID .JClicCell5 {}
169
- .ID .JClicCell6 {background-image:url(${box6});background-repeat:repeat-y;}
170
- .ID .JClicCell7 {background-image:url(${box7});}
171
- .ID .JClicCell8 {background-image:url(${box8});background-repeat:repeat-x;}
172
- .ID .JClicCell9 {background-image:url(${box9});}`;
173
-
174
- let cssHalf = `
175
- .ID .JClicGridPanel {grid-template-columns:${Math.round((ph2 - ph0) / 2)}px 1fr ${Math.round((ph5 - ph3) / 2)}px;grid-template-rows:${Math.round((pv2 - pv0) / 2)}px 1fr ${Math.round((pv5 - pv3) / 2)}px;}
176
- .ID .JClicPlayerCell {top:${Math.round((pv1 - pv0) / 2)}px;right:${Math.round((ph5 - ph4) / 2)}px;bottom:${Math.round((pv5 - pv4) / 2)}px;left:${Math.round((ph1 - ph0) / 2)}px;}
177
- .ID .JClicTransform {transform: scale(0.5);}`;
178
-
179
- let cssTwoThirds = `
180
- .ID .JClicGridPanel {grid-template-columns:${Math.round(2 * (ph2 - ph0) / 3)}px 1fr ${Math.round(2 * (ph5 - ph3) / 3)}px;grid-template-rows:${Math.round(2 * (pv2 - pv0) / 3)}px 1fr ${Math.round(2 * (pv5 - pv3) / 3)}px;}
181
- .ID .JClicPlayerCell {top:${Math.round(2 * (pv1 - pv0) / 3)}px;right:${Math.round(2 * (ph5 - ph4) / 3)}px;bottom:${Math.round(2 * (pv5 - pv4) / 3)}px;left:${Math.round(2 * (ph1 - ph0) / 3)}px;}
182
- .ID .JClicTransform {transform: scale(0.666);}`;
183
-
184
- // Buttons:
185
- if (this.options.buttons) {
186
- const bt = this.options.buttons;
187
- let wBase = 30, hBase = 30, offsetBase = {};
188
- if (bt.settings) {
189
- if (bt.settings.dimension) {
190
- wBase = bt.settings.dimension.width || wBase;
191
- hBase = bt.settings.dimension.height || hBase;
192
- }
193
- if (bt.settings.offset)
194
- Object.assign(offsetBase, bt.settings.offset);
195
- }
196
- Object.keys(this.options.buttons.button).forEach(k => {
197
- const
198
- btn = bt.button[k],
199
- k2 = k === 'about' ? 'reports' : k;
200
- let w = wBase, h = hBase, offset = offsetBase;
201
- if (btn.settings) {
202
- if (btn.settings.dimension) {
203
- w = btn.settings.dimension.width || w;
204
- h = btn.settings.dimension.height || h;
205
- }
206
- if (btn.settings.offset)
207
- offset = Object.assign({}, offsetBase, btn.settings.offset);
208
- }
209
- const
210
- x = btn.point.pos.left,
211
- xp = x < ph2 ? `left:${x}` : `right:${ph5 - x - w}`,
212
- xpHalf = x < ph2 ? `left:${Math.round(x / 2 - w / 4)}` : `right:${Math.round((ph5 - x - w) / 2 - w / 4)}`,
213
- xpTwoThirds = x < ph2 ? `left:${Math.round(2 * x / 3 - w / 6)}` : `right:${Math.round(2 * (ph5 - x - w) / 3 - w / 6)}`,
214
- y = btn.point.pos.top,
215
- yp = y < pv2 ? `top:${y}` : `bottom:${pv5 - y - h}`,
216
- ypHalf = y < pv2 ? `top:${Math.round(y / 2 - h / 4)}` : `bottom:${Math.round((pv5 - y - h) / 2 - h / 4)}`,
217
- ypTwoThirds = y < pv2 ? `top:${Math.round(2 * y / 3 - h / 6)}` : `bottom:${Math.round(2 * (pv5 - y - h) / 3 - h / 6)}`,
218
- xs = btn.point.source.left,
219
- ys = btn.point.source.top;
220
- css += `.ID .Btn-${k2} {position:absolute;${xp}px;${yp}px;width:${w}px;height:${h}px;background:url(${imgUrl}) !important;background-position:-${xs}px -${ys}px !important;}\n`;
221
- cssHalf += `.ID .Btn-${k2} {${xpHalf}px;${ypHalf}px;}\n`;
222
- cssTwoThirds += `.ID .Btn-${k2} {${xpTwoThirds}px;${ypTwoThirds}px;}\n`;
223
- if (offset.active)
224
- css += `.ID .Btn-${k2}:active {background-position:-${xs + offset.active.right}px -${ys + offset.active.down}px !important;}\n`;
225
- if (offset.over)
226
- css += `.ID .Btn-${k2}:hover {background-position:-${xs + offset.over.right}px -${ys + offset.over.down}px !important;}\n`;
227
- if (offset.disabled)
228
- css += `.ID .Btn-${k2}:disabled {background-position:-${xs + offset.disabled.right}px -${ys + offset.disabled.down}px !important;}\n`;
229
- });
230
- }
231
-
232
- // Counters:
233
- if (this.options.counters && this.options.counters.settings) {
234
- const cnt = this.options.counters;
235
- let wBase = 35, hBase = 20;
236
- if (cnt.settings.dimension && cnt.settings.dimension.counter) {
237
- wBase = (cnt.settings.dimension.counter.width || wBase);
238
- hBase = cnt.settings.dimension.counter.height || hBase;
239
- }
240
- let wLb = 37, hLb = 14;
241
- if (cnt.settings.dimension && cnt.settings.dimension.label) {
242
- wLb = (cnt.settings.dimension.label.width || wLb);
243
- hLb = cnt.settings.dimension.label.height || hLb;
244
- }
245
- let bColor = 'black';
246
- if (cnt.style && cnt.style.color && cnt.style.color.foreground)
247
- bColor = checkColor(cnt.style.color.foreground.value || bColor);
248
- let lbFntSize = hLb - 4;
249
- let lbFntFamily = 'Roboto';
250
- if (cnt.style && cnt.style.font && cnt.style.font.label) {
251
- lbFntSize = Math.max(8, cnt.style.font.label.size || lbFntSize);
252
- lbFntFamily = `${cnt.style.font.label.family || 'Roboto'},Roboto,sans-serif`;
253
- }
254
-
255
- css += `.ID .JClicCounter {font-size:${hBase - 2}px;color:${bColor}}\n`;
256
- Object.keys(this.options.counters.counter).forEach(k => {
257
- const
258
- counter = cnt.counter[k];
259
- let w = wBase, h = hBase;
260
- const
261
- x = counter.point.counter.left,
262
- xl = counter.point.label.left || (x - Math.round((wLb - wBase) / 2)),
263
- xp = x < ph2 ? `left:${x}` : `right:${ph5 - x - w}`,
264
- xpHalf = x < ph2 ? `left:${Math.round(x / 2 - w / 4)}` : `right:${Math.round((ph5 - x - w) / 2 - w / 4)}`,
265
- xpTwoThirds = x < ph2 ? `left:${Math.round(2 * x / 3 - w / 6)}` : `right:${Math.round(2 * (ph5 - x - w) / 3 - w / 6)}`,
266
- y = counter.point.counter.top,
267
- yl = counter.point.label.top || (y - hLb),
268
- yp = y < pv2 ? `top:${y}` : `bottom:${pv5 - y - h}`,
269
- ypHalf = y < pv2 ? `top:${Math.round(y / 2 - h / 4)}` : `bottom:${Math.round((pv5 - y - h) / 2 - h / 4)}`,
270
- ypTwoThirds = y < pv2 ? `top:${Math.round(2 * y / 3 - h / 6)}` : `bottom:${Math.round(2 * (pv5 - y - h) / 3 - h / 6)}`;
271
- // counter:
272
- css += `.ID .Counter-${k} {position:absolute;${xp}px;${yp}px;width:${w}px;height:${h}px;line-height:${h}px;}\n`;
273
- // label:
274
- css += `.ID .Counter-${k}:before {content:"${getMsg(k)}";font-size:${lbFntSize}px;font-family:${lbFntFamily};width:${wLb}px;height:${hLb}px;line-height:${hLb}px;position:absolute;top:${yl - y}px;left:${xl - x}px;}`;
275
- // reduced sizes:
276
- cssHalf += `.ID .Counter-${k} {${xpHalf}px;${ypHalf}px;}\n`;
277
- cssTwoThirds += `.ID .Counter-${k} {${xpTwoThirds}px;${ypTwoThirds}px;}\n`;
278
- });
279
- }
280
-
281
- // Progress animation:
282
- if (this.options.progressAnimation) {
283
- const pa = this.options.progressAnimation;
284
- let w = 30, h = 30;
285
- if (pa.dimension) {
286
- w = pa.dimension.width || w;
287
- h = pa.dimension.height || h;
288
- }
289
- const
290
- x = pa.point.pos.left,
291
- xp = x < ph2 ? `left:${x}` : `right:${ph5 - x - w}`,
292
- xpHalf = x < ph2 ? `left:${Math.round(x / 2 - w / 4)}` : `right:${Math.round((ph5 - x - w) / 2 - w / 4)}`,
293
- xpTwoThirds = x < ph2 ? `left:${Math.round(2 * x / 3 - w / 6)}` : `right:${Math.round(2 * (ph5 - x - w) / 3 - w / 6)}`,
294
- y = pa.point.pos.top,
295
- yp = y < pv2 ? `top:${y}` : `bottom:${pv5 - y - h}`,
296
- ypHalf = y < pv2 ? `top:${Math.round(y / 2 - h / 4)}` : `bottom:${Math.round((pv5 - y - h) / 2 - h / 4)}`,
297
- ypTwoThirds = y < pv2 ? `top:${Math.round(2 * y / 3 - h / 6)}` : `bottom:${Math.round(2 * (pv5 - y - h) / 3 - h / 6)}`,
298
- xs = pa.point.source.left,
299
- ys = pa.point.source.top;
300
- css += `.ID .JClicProgressAnimation {position:absolute;${xp}px;${yp}px;width:${w}px;height:${h}px;background:url(${imgUrl});background-position:-${xs}px -${ys}px;}\n`;
301
- cssHalf += `.ID .JClicProgressAnimation {${xpHalf}px;${ypHalf}px;}\n`;
302
- cssTwoThirds += `.ID .JClicProgressAnimation {${xpTwoThirds}px;${ypTwoThirds}px;}\n`;
303
-
304
- if (pa.frames && pa.direction) {
305
- const
306
- dx = (pa.step || w) * (pa.direction === 'right' ? 1 : pa.direction === 'left' ? -1 : 0),
307
- dy = (pa.step || h) * (pa.direction === 'down' ? 1 : pa.direction === 'up' ? -1 : 0);
308
- css += `\n@keyframes anim {100% {background-position:${(xs + dx * pa.frames) * -1}px ${(ys + dy * pa.frames) * -1}px;}}\n.ID .JClicProgressAnimation {animation: anim ${pa.frames * pa.delay}ms steps(${pa.frames}) infinite;}`;
309
- }
310
- }
311
-
312
- // Messages box:
313
- if (this.options.rectangle.messages) {
314
- const
315
- bx = this.options.rectangle.messages,
316
- left = ph0 + bx.left,
317
- right = ph5 - bx.width - bx.left - ph0,
318
- tb = bx.top < pv2 ? `top:${bx.top}` : `bottom:${pv5 - bx.height - bx.top}`,
319
- tbHalf = bx.top < pv2 ? `top:${Math.round(bx.top / 2)}` : `bottom:${Math.round((pv5 - bx.height - bx.top) / 2)}`,
320
- tbTwoThirds = bx.top < pv2 ? `top:${Math.round(2 * bx.top / 3)}` : `bottom:${Math.round(2 * (pv5 - bx.height - bx.top) / 3)}`;
321
-
322
- css += `.ID .JClicMsgBox {position:absolute;left:${left}px;right:${right}px;height:${bx.height}px;${tb}px;}`;
323
- cssHalf += `.ID .JClicMsgBox {left:${Math.round(left / 2)}px;right:${Math.round(right / 2)}px;height:${Math.round(bx.height / 2)}px;${tbHalf}px;}`;
324
- cssTwoThirds += `.ID .JClicMsgBox {left:${Math.round(2 * left / 3)}px;right:${Math.round(2 * right / 3)}px;height:${Math.round(2 * bx.height / 3)}px;${tbTwoThirds}px;}`;
325
- }
326
-
327
- // TODO: Implement status messages?
328
-
329
- // Store results in `cssVariants`
330
- this.cssVariants = {
331
- default: this.mainCSS + css,
332
- half: cssHalf,
333
- twoThirds: cssTwoThirds
334
- };
335
- }
336
-
337
- /**
338
- * Returns the CSS styles used by this skin. This method should be called only from
339
- * the `Skin` constructor, and overridded by subclasses if needed.
340
- * @param {string} media - A specific media size. Possible values are: 'default', 'half' and 'twoThirds'
341
- * @override
342
- * @returns {string}
343
- */
344
- _getStyleSheets(media = 'default') {
345
- if (!this.cssVariants)
346
- this._computeStyleSheets();
347
- return `${super._getStyleSheets(media)}${this.cssVariants[media] || ''}`;
348
- }
349
-
350
- /**
351
- * Sets/unsets the 'wait' state
352
- * @override
353
- * @param {boolean} status - Whether to set or unset the wait status. When `undefined`, the
354
- * `waitCursorCount` member is evaluated to decide if the wait state should be activated or deactivated.
355
- */
356
- setWaitCursor(status) {
357
- super.setWaitCursor(status);
358
- if (this.$progressAnimation)
359
- this.$progressAnimation.css('animation-play-state', this.waitCursorCount > 0 ? 'running' : 'paused');
360
- }
361
- }
362
-
363
- Object.assign(CustomSkin.prototype, {
364
- /**
365
- * Class name of this skin. It will be used as a base selector in the definition of all CSS styles.
366
- * @name module:skins/CustomSkin.CustomSkin#skinId
367
- * @override
368
- * @type {string} */
369
- skinId: 'JClicCustomSkin',
370
- /**
371
- * The name of the image file to be used as a base of this skin.
372
- * @name module:skins/CustomSkin.CustomSkin#image
373
- * @type {string} */
374
- image: null,
375
- /**
376
- * Styles used in this skin
377
- * @name module:skins/CustomSkin.CustomSkin#skinCSS
378
- * @override
379
- * @type {string} */
380
- mainCSS: '\
381
- .ID .JClicPlayerCnt {margin:0;}\
382
- .ID .JClicBtn:focus {outline:0;}\
383
- .ID .JClicCounter {font-family:Roboto,sans-serif;text-align:center;}',
384
- /**
385
- * Specifc styles (`default`, `half` and `twoThirds`) computed at run-time,
386
- * based on the provided XML file
387
- * @name module:skins/CustomSkin.CustomSkin#cssVariants
388
- * @type {object} */
389
- cssVariants: null,
390
- /**
391
- * Key ids of currently supported buttons, associated with its helper literal
392
- * @name module:skins/CustomSkin.CustomSkin#msgKeys
393
- * @type {object} */
394
- msgKeys: {
395
- next: 'Next activity',
396
- prev: 'Previous activity',
397
- info: 'Information',
398
- help: 'Help',
399
- reports: 'Reports',
400
- // TODO: Implement audio on/off!
401
- audio: 'Audio on/off',
402
- reset: 'Reset activity',
403
- },
404
- /**
405
- * Graphic indicator of loading progress
406
- * @name module:skins/CustomSkin.Skin#$progressAnimation
407
- * @type {external:jQuery} */
408
- $progressAnimation: null,
409
- });
410
-
411
- // Register this class in the list of available skins
412
- export default Skin.registerClass('custom', CustomSkin);