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
@@ -1,273 +0,0 @@
1
- /**
2
- * File : project/ProjectSettings.js
3
- * Created : 01/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 window */
33
-
34
- import $ from 'jquery';
35
- import EventSounds from '../media/EventSounds.js';
36
- import { log, getXmlNodeText, parseXmlNode, reduceTextsToStrings, parseOldDate, cleanOldLanguageTag, getAttr, setAttr } from '../Utils.js';
37
-
38
- /**
39
- * This class contains miscellaneous settings of JClic projects.
40
- *
41
- * In addition to the members of this class, there can be other properties in JClic project files
42
- * that are not currently loaded:
43
- * - iconFileName
44
- * - descriptors
45
- * - area
46
- * - level
47
- * - locale
48
- * - authors
49
- * - organizations
50
- * - revisions
51
- */
52
- export class ProjectSettings {
53
- /**
54
- * ProjectSettings constructor
55
- * @param {module:project/JClicProject.JClicProject} project - The project to which this settings belongs
56
- */
57
- constructor(project) {
58
- this.project = project;
59
- this.authors = [];
60
- this.organizations = [];
61
- this.revisions = [];
62
- this.languages = [];
63
- this.locales = [];
64
- this.description = {};
65
- this.tags = {};
66
- }
67
-
68
- /**
69
- * Reads the ProjectSettings values from a JQuery XML element
70
- * @param {external:jQuery} $xml - The XML element to parse
71
- */
72
- setProperties($xml) {
73
- let single_description = null;
74
- const multiple_descriptions = [];
75
-
76
- $xml.children().each((_n, child) => {
77
- switch (child.nodeName) {
78
- case 'title':
79
- this.title = child.textContent;
80
- break;
81
- case 'description':
82
- single_description = getXmlNodeText(child);
83
- break;
84
- case 'descriptions':
85
- $(child).children().each((_n, desc) => multiple_descriptions.push(parseXmlNode(desc)));
86
- break;
87
- case 'author':
88
- this.authors.push(reduceTextsToStrings(parseXmlNode(child)));
89
- break;
90
- case 'organization':
91
- this.organizations.push(reduceTextsToStrings(parseXmlNode(child)));
92
- break;
93
- case 'revision':
94
- const revision = reduceTextsToStrings(parseXmlNode(child));
95
- if (revision.date)
96
- revision.date = parseOldDate(revision.date);
97
- this.revisions.push(revision);
98
- break;
99
- case 'language':
100
- this.languages.push(cleanOldLanguageTag(child.textContent));
101
- break;
102
- case 'eventSounds':
103
- this.eventSounds = new EventSounds();
104
- this.eventSounds.setProperties($(child));
105
- break;
106
- case 'skin':
107
- this.skinFileName = $(child).attr('file');
108
- break;
109
- case 'descriptors':
110
- this.tags = parseXmlNode(child, true);
111
- if (this.tags['#text']) {
112
- this.tags.other = this.tags['#text'].textContent;
113
- delete this.tags['#text'];
114
- }
115
- break;
116
- case 'license':
117
- this.license = getXmlNodeText(child);
118
- break;
119
- case 'cover':
120
- case 'thumb':
121
- const img = getXmlNodeText(child);
122
- if (img.file)
123
- this[child.nodeName] = img.file;
124
- break;
125
- }
126
- });
127
-
128
- this.buildLocales();
129
-
130
- multiple_descriptions.forEach(d => {
131
- if (d.language && d.text)
132
- this.description[d.language] = d.text;
133
- });
134
-
135
- if (single_description && this.languages.length > 0 && !this.description[this.languages[0]])
136
- this.description[this.languages[0]] = single_description;
137
-
138
- return this;
139
- }
140
-
141
- buildLocales() {
142
- // Try to find an array of valid locales
143
- // See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl
144
- if (this.languages.length > 0 && window.Intl && window.Intl.getCanonicalLocales) {
145
- this.locales = [];
146
- this.languages.forEach(lang => {
147
- // Languages usually are stored in the form: "English (en)"
148
- const matches = /\(([a-z,A-Z,-]+)\)/.exec(lang);
149
- if (matches && matches.length > 1) {
150
- try {
151
- const canonicals = window.Intl.getCanonicalLocales(matches[1]);
152
- if (canonicals)
153
- this.locales = this.locales.concat(canonicals);
154
- } catch (_err) {
155
- log('error', `Invalid language: ${lang}`);
156
- }
157
- }
158
- });
159
- }
160
- return this;
161
- }
162
-
163
- /**
164
- * Gets a object with the basic attributes needed to rebuild this instance excluding functions,
165
- * parent references, constants and also attributes retaining the default value.
166
- * The resulting object is commonly usued to serialize elements in JSON format.
167
- * @returns {object} - The resulting object, with minimal attrributes
168
- */
169
- getAttributes() {
170
- return getAttr(this, [
171
- 'title', 'description',
172
- 'tags', 'languages', 'license',
173
- 'authors', 'organizations',
174
- 'revisions',
175
- 'cover', 'thumb',
176
- 'skinFileName', 'eventSounds'
177
- ]);
178
- }
179
-
180
- /**
181
- * Reads the properties of this ProjectSettings from a data object
182
- * @param {object} data - The data object to be parsed, or just the text content
183
- * @returns {module:project/ProjectSettings.ProjectSettings}
184
- */
185
- setAttributes(data) {
186
- setAttr(this, data, [
187
- 'title', 'description',
188
- 'tags', 'languages', 'license',
189
- 'authors', 'organizations',
190
- 'revisions',
191
- 'cover', 'thumb',
192
- 'skinFileName', 'eventSounds'
193
- ]);
194
-
195
- // Build Date objects in revisions
196
- if (this.revisions)
197
- this.revisions.forEach(rv => {
198
- if (rv.date)
199
- rv.date = new Date(rv.date);
200
- });
201
-
202
- return this.buildLocales();
203
- }
204
- }
205
-
206
- Object.assign(ProjectSettings.prototype, {
207
- /**
208
- * The JClicProject to which this ProjectSettings belongs
209
- * @name module:project/ProjectSettings.ProjectSettings#project
210
- * @type {module:project/JClicProject.JClicProject} */
211
- project: null,
212
- /**
213
- * The project title
214
- * @name module:project/ProjectSettings.ProjectSettings#title
215
- * @type {string} */
216
- title: 'Untitled',
217
- /**
218
- * The authors of this project.
219
- * Each author is represented by an object with the following attributes:
220
- * `name` (mandatory), `mail`, `rol`, `organization` and `url`
221
- * @name module:project/ProjectSettings.ProjectSettings#authors
222
- * @type {object[]} */
223
- authors: null,
224
- /**
225
- * Schools, companies and other institutions involved on this project.
226
- * Each organization is represented by an object with the following attributes:
227
- * `name` (mandatory), `mail`, `url`, `address`, `pc`, `city`, `state`, `country`, `comments`
228
- * @name module:project/ProjectSettings.ProjectSettings#organizations
229
- * @type {object[]} */
230
- organizations: null,
231
- /**
232
- * The history of revisions made to this project.
233
- * Revisions are represented by objects with the following attributes:
234
- * `date` (mandatory), `description`, `comments` and `author`
235
- * @name module:project/ProjectSettings.ProjectSettings#revisions
236
- * @type {object[]} */
237
- revisions: null,
238
- /**
239
- * Project's description, maybe in multiple languages.
240
- * @name module:project/ProjectSettings.ProjectSettings#description
241
- * @type {object} */
242
- description: null,
243
- /**
244
- * JClic projects can use more than one language, so use a string array
245
- * @name module:project/ProjectSettings.ProjectSettings#languages
246
- * @type {string[]} */
247
- languages: null,
248
- tags: null,
249
- cover: null,
250
- thumb: null,
251
- license: {
252
- type: 'by-nc-sa',
253
- url: 'https://creativecommons.org/licenses/by-nc-sa/4.0',
254
- },
255
- /**
256
- * Array of canonical locales, as defined in
257
- * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl#Locale_identification_and_negotiation|Intl}
258
- * @name module:project/ProjectSettings.ProjectSettings#locales
259
- * @type {string[]} */
260
- locales: null,
261
- /**
262
- * The name of an optional 'skin' (visual aspect) can be set for the whole project, or for each {@link module:Activity.Activity Activity}
263
- * @name module:project/ProjectSettings.ProjectSettings#skinFileName
264
- * @type {string} */
265
- skinFileName: null,
266
- /**
267
- * The main {@link module:media/EventSounds.EventSounds EventSounds} object of the project
268
- * @name module:project/ProjectSettings.ProjectSettings#eventSounds
269
- * @type {module:media/EventSounds.EventSounds} */
270
- eventSounds: new EventSounds(),
271
- });
272
-
273
- export default ProjectSettings;
@@ -1,123 +0,0 @@
1
- /**
2
- * File : report/ActionReg.js
3
- * Created : 17/05/2016
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 { attrForEach, getBoolean } from '../Utils.js';
34
-
35
- /**
36
- * This class stores information about one specific action done by the current user while playing
37
- * an activity.
38
- *
39
- */
40
- export class ActionReg {
41
- /**
42
- * ActionReg constructor
43
- * @param {string} type - Type of action (`click`, `write`, `move`, `select`...)
44
- * @param {string}+ source - Description of the object on which the action is done.
45
- * @param {string}+ dest - Description of the object that acts as a target of the action (used in pairings)
46
- * @param {boolean} ok - `true` if the action was OK, `false`, `null` or `undefined` otherwise
47
- */
48
- constructor(type, source, dest, ok) {
49
- this.type = type;
50
- this.source = source || null;
51
- this.dest = dest || null;
52
- this.ok = ok || false;
53
- this.time = (new Date()).valueOf();
54
- }
55
-
56
- /**
57
- * Provides the data associated with this action in XML format suitable for a
58
- * {@link http://clic.xtec.cat/en/jclic/reports/|JClic Reports Server}.
59
- * @returns {external:jQuery}
60
- */
61
- $getXML() {
62
- const attr = { ok: this.ok, time: this.time };
63
- if (this.type)
64
- attr.type = this.type;
65
- if (this.source)
66
- attr.source = this.source;
67
- if (this.dest)
68
- attr.dest = this.dest;
69
- return $('<action/>', attr);
70
- }
71
-
72
- /**
73
- * Fills this ActionReg with data provided in XML format
74
- * @param {external:jQuery} $xml - The XML element to be processed, already wrapped as jQuery object
75
- */
76
- setProperties($xml) {
77
- attrForEach($xml.get(0).attributes, (name, value) => {
78
- switch (name) {
79
- case 'type':
80
- case 'source':
81
- case 'dest':
82
- this[name] = value;
83
- break;
84
- case 'time':
85
- this[name] = Number(value);
86
- break;
87
- case 'ok':
88
- this[name] = getBoolean(value, false);
89
- break;
90
- }
91
- });
92
- }
93
- }
94
-
95
- Object.assign(ActionReg.prototype, {
96
- /**
97
- * The type of action (`click`, `write`, `move`, `select`...)
98
- * @name module:report/ActionReg.ActionReg#type
99
- * @type {string} */
100
- type: 'unknown',
101
- /**
102
- * Description of the object on which the action was done
103
- * @name module:report/ActionReg.ActionReg#source
104
- * @type {string} */
105
- source: null,
106
- /**
107
- * Description of the object that has acted as a target of the action (used in pairings)
108
- * @name module:report/ActionReg.ActionReg#dest
109
- * @type {string} */
110
- dest: null,
111
- /**
112
- * Time stamp taken when the action was done
113
- * @name module:report/ActionReg.ActionReg#time
114
- * @type {number} */
115
- time: 0,
116
- /**
117
- * `true` if the action was OK
118
- * @name module:report/ActionReg.ActionReg#isOk
119
- * @type {boolean} */
120
- isOk: false,
121
- });
122
-
123
- export default ActionReg;
@@ -1,271 +0,0 @@
1
- /**
2
- * File : report/ActivityReg.js
3
- * Created : 17/05/2016
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 { attrForEach, getBoolean } from '../Utils.js';
34
- import ActionReg from './ActionReg.js';
35
-
36
- /**
37
- * This class stores miscellaneous data obtained by the current user playing an {@link module:Activity.Activity Activity}.
38
- */
39
- export class ActivityReg {
40
- /**
41
- * ActivityReg constructor
42
- * @param {module:Activity.Activity} act - The {@link module:Activity.Activity Activity} referenced by this object.
43
- */
44
- constructor(act) {
45
- this.name = act.name;
46
- this.code = act.code;
47
- this.actions = [];
48
- this.startTime = (new Date()).valueOf();
49
- this.minActions = act.getMinNumActions();
50
- this.reportActions = act.reportActions;
51
- }
52
-
53
- /**
54
- * Provides the data associated with the current activity in an XML format suitable for a
55
- * {@link http://clic.xtec.cat/en/jclic/reports/|JClic Reports Server}.
56
- * @returns {external:jQuery}
57
- */
58
- $getXML() {
59
- const attr = {
60
- start: this.startTime,
61
- time: this.totalTime,
62
- solved: this.solved,
63
- score: this.score,
64
- minActions: this.minActions,
65
- actions: this.numActions
66
- };
67
- if (this.name)
68
- attr.name = this.name;
69
- if (this.code)
70
- attr.code = this.code;
71
- if (!this.closed)
72
- attr.closed = false;
73
- if (this.reportActions)
74
- attr.reportActions = true;
75
-
76
- const $result = $('<activity/>', attr);
77
- this.actions.forEach(ac => {
78
- $result.append(ac.$getXML());
79
- });
80
- return $result;
81
- }
82
-
83
- /**
84
- * Builds an object with relevant data about the results obtained by the current student in this activity
85
- * @returns {object} - The results of this activity
86
- */
87
- getData() {
88
- const result = {
89
- name: this.name,
90
- time: Math.round(this.totalTime / 10) / 100,
91
- solved: this.solved,
92
- score: this.score,
93
- minActions: this.minActions,
94
- actions: this.numActions,
95
- precision: this.getPrecision(),
96
- closed: this.closed
97
- };
98
- if (this.code)
99
- result.code = this.code;
100
- return result;
101
- }
102
-
103
- /**
104
- * Fills this ActivityReg with data provided in XML format
105
- * @param {external:jQuery} $xml -The XML element to be processed, already wrapped as jQuery object
106
- */
107
- setProperties($xml) {
108
- attrForEach($xml.get(0).attributes, (name, value) => {
109
- switch (name) {
110
- case 'name':
111
- case 'code':
112
- this[name] = value;
113
- break;
114
- case 'start':
115
- case 'time':
116
- case 'score':
117
- case 'minActions':
118
- case 'actions':
119
- this[name] = Number(value);
120
- break;
121
- case 'solved':
122
- case 'closed':
123
- case 'reportActions':
124
- this[name] = getBoolean(value, false);
125
- break;
126
- }
127
- });
128
- $xml.children('action').each((_n, child) => {
129
- const action = new ActionReg();
130
- action.setProperties($(child));
131
- this.actions.push(action);
132
- });
133
- }
134
-
135
- /**
136
- * Reports a new action done by the user while playing the current activity
137
- * @param {string} type - Type of action (`click`, `write`, `move`, `select`...)
138
- * @param {string}+ source - Description of the object on which the action is done.
139
- * @param {string}+ dest - Description of the object that acts as a target of the action (used in pairings)
140
- * @param {boolean} ok - `true` if the action was OK, `false`, `null` or `undefined` otherwise
141
- */
142
- newAction(type, source, dest, ok) {
143
- if (!this.closed) {
144
- this.lastAction = new ActionReg(type, source, dest, ok);
145
- this.actions.push(this.lastAction);
146
- }
147
- }
148
-
149
- /**
150
- * Retrieves a specific {@link module:report/ActionReg.ActionReg ActionReg} element from `actions`
151
- * @param {number} index - The nth action to be retrieved
152
- * @returns {module:report/ActionReg.ActionReg}
153
- */
154
- getActionReg(index) {
155
- return index >= this.actions.length ? null : this.actions[index];
156
- }
157
-
158
- /**
159
- * Closes the current activity, adjusting total time if needed
160
- */
161
- closeActivity() {
162
- if (!this.closed) {
163
- if (this.lastAction)
164
- this.totalTime = this.lastAction.time - this.startTime;
165
- else
166
- this.totalTime = (new Date()).valueOf() - this.startTime;
167
- this.closed = true;
168
- }
169
- }
170
-
171
- /**
172
- * calculates the final score obtained by the user in this activity.
173
- * The algorithm used takes in account the minimal number of actions needed, the actions
174
- * really done by the user, and if the activity was finally solved or not.
175
- * @returns {number}
176
- */
177
- getPrecision() {
178
- let result = 0;
179
- if (this.closed && this.minActions > 0 && this.numActions > 0) {
180
- if (this.solved) {
181
- if (this.numActions < this.minActions)
182
- result = 100;
183
- else
184
- result = Math.round(this.minActions * 100 / this.numActions);
185
- } else
186
- result = Math.round(100 * (this.score * this.score) / (this.minActions * this.numActions));
187
- }
188
- return result;
189
- }
190
-
191
- /**
192
- * This method should be called when the current activity finishes. Data about user's final results
193
- * on the activity will then be saved.
194
- * @param {number} score - The final score, usually in a 0-100 scale.
195
- * @param {number} numActions - The total number of actions done by the user to solve the activity
196
- * @param {boolean} solved - `true` if the activity was finally solved, `false` otherwise.
197
- */
198
- endActivity(score, numActions, solved) {
199
- if (!this.closed) {
200
- this.solved = solved;
201
- this.numActions = numActions;
202
- this.score = score;
203
- this.closeActivity();
204
- }
205
- }
206
- }
207
-
208
- Object.assign(ActivityReg.prototype, {
209
- /**
210
- * Name of the associated activity
211
- * @name module:report/ActivityReg.ActivityReg#name
212
- * @type {string} */
213
- name: '',
214
- /**
215
- * Optional code assigned to this activity, used for later filtering
216
- * @name module:report/ActivityReg.ActivityReg#code
217
- * @type {string} */
218
- code: '',
219
- /**
220
- * Timestamp when the user starts playing the activity
221
- * @name module:report/ActivityReg.ActivityReg#startTime
222
- * @type {number} */
223
- startTime: 0,
224
- /**
225
- * Total time spent by the user in the activity, measured in milliseconds
226
- * @name module:report/ActivityReg.ActivityReg#totalTime
227
- * @type {number} */
228
- totalTime: 0,
229
- /**
230
- * Collection of actions done by the user while playing the activity
231
- * @name module:report/ActivityReg.ActivityReg#actions
232
- * @type {module:report/ActionReg.ActionReg[]} */
233
- actions: [],
234
- /**
235
- * `true` only when the user has finished and solved the activity
236
- * @name module:report/ActivityReg.ActivityReg#solved
237
- * @type {boolean} */
238
- solved: false,
239
- /**
240
- * Last {@link module:report/ActionReg.ActionReg ActionReg} performed by the user in this activity
241
- * @name module:report/ActivityReg.ActivityReg#lastAction
242
- * @type {module:report/ActionReg.ActionReg} */
243
- lastAction: null,
244
- /**
245
- * Final score obtained by the current user in this activity
246
- * @name module:report/ActivityReg.ActivityReg#score
247
- * @type {number} */
248
- score: 0,
249
- /**
250
- * Minimum number of actions needed to solve the activity
251
- * @name module:report/ActivityReg.ActivityReg#minActions
252
- * @type {number} */
253
- minActions: 0,
254
- /**
255
- * `true` when the activity has finished, `false` for the activity that is currently playing
256
- * @name module:report/ActivityReg.ActivityReg#closed
257
- * @type {boolean} */
258
- closed: false,
259
- /**
260
- * `true` when this type of activity should record specific actions done by the users
261
- * @name module:report/ActivityReg.ActivityReg#reportActions
262
- * @type {boolean} */
263
- reportActions: false,
264
- /**
265
- * Number of actions done by the user playing this activity
266
- * @name module:report/ActivityReg.ActivityReg#numActions
267
- * @type {number} */
268
- numActions: 0,
269
- });
270
-
271
- export default ActivityReg;