jclic 2.1.21 → 2.1.23
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.
- package/CHANGELOG.md +13 -0
- package/dist/jclic-node.js +9 -8
- package/dist/jclic-node.js.map +1 -1
- package/dist/jclic.min.js +2 -2
- package/dist/jclic.min.js.map +1 -1
- package/package.json +4 -4
- package/src/GlobalData.js +1 -1
- package/src/JClicPlayer.js +2 -2
- package/src/bags/MediaBag.js +6 -5
- package/dist/1078.jclic-node.js +0 -282
- package/dist/1078.jclic-node.js.map +0 -1
- package/dist/1196.jclic-node.js +0 -808
- package/dist/1196.jclic-node.js.map +0 -1
- package/dist/1253.jclic-node.js +0 -1432
- package/dist/1253.jclic-node.js.map +0 -1
- package/dist/13.jclic-node.js +0 -103
- package/dist/13.jclic-node.js.map +0 -1
- package/dist/1567.jclic-node.js +0 -2313
- package/dist/1567.jclic-node.js.map +0 -1
- package/dist/1588.jclic-node.js +0 -602
- package/dist/1588.jclic-node.js.map +0 -1
- package/dist/1725.jclic-node.js +0 -836
- package/dist/1725.jclic-node.js.map +0 -1
- package/dist/1731.jclic-node.js +0 -438
- package/dist/1731.jclic-node.js.map +0 -1
- package/dist/1842.jclic-node.js +0 -651
- package/dist/1842.jclic-node.js.map +0 -1
- package/dist/2160.jclic-node.js +0 -1016
- package/dist/2160.jclic-node.js.map +0 -1
- package/dist/222.jclic-node.js +0 -129
- package/dist/222.jclic-node.js.map +0 -1
- package/dist/2316.jclic-node.js +0 -949
- package/dist/2316.jclic-node.js.map +0 -1
- package/dist/2355.jclic-node.js +0 -371
- package/dist/2355.jclic-node.js.map +0 -1
- package/dist/2366.jclic-node.js +0 -431
- package/dist/2366.jclic-node.js.map +0 -1
- package/dist/2379.jclic-node.js +0 -202
- package/dist/2379.jclic-node.js.map +0 -1
- package/dist/2437.jclic-node.js +0 -450
- package/dist/2437.jclic-node.js.map +0 -1
- package/dist/2531.jclic-node.js +0 -869
- package/dist/2531.jclic-node.js.map +0 -1
- package/dist/2608.jclic-node.js +0 -160
- package/dist/2608.jclic-node.js.map +0 -1
- package/dist/2715.jclic-node.js +0 -554
- package/dist/2715.jclic-node.js.map +0 -1
- package/dist/277.jclic-node.js +0 -22
- package/dist/277.jclic-node.js.map +0 -1
- package/dist/2921.jclic-node.js +0 -660
- package/dist/2921.jclic-node.js.map +0 -1
- package/dist/2952.jclic-node.js +0 -101
- package/dist/2952.jclic-node.js.map +0 -1
- package/dist/3018.jclic-node.js +0 -421
- package/dist/3018.jclic-node.js.map +0 -1
- package/dist/3019.jclic-node.js +0 -682
- package/dist/3019.jclic-node.js.map +0 -1
- package/dist/3231.jclic-node.js +0 -274
- package/dist/3231.jclic-node.js.map +0 -1
- package/dist/331.jclic-node.js +0 -115
- package/dist/331.jclic-node.js.map +0 -1
- package/dist/3391.jclic-node.js +0 -276
- package/dist/3391.jclic-node.js.map +0 -1
- package/dist/3502.jclic-node.js +0 -671
- package/dist/3502.jclic-node.js.map +0 -1
- package/dist/3653.jclic-node.js +0 -982
- package/dist/3653.jclic-node.js.map +0 -1
- package/dist/371.jclic.min.js +0 -2
- package/dist/371.jclic.min.js.map +0 -1
- package/dist/3856.jclic-node.js +0 -575
- package/dist/3856.jclic-node.js.map +0 -1
- package/dist/4112.jclic-node.js +0 -659
- package/dist/4112.jclic-node.js.map +0 -1
- package/dist/4123.jclic-node.js +0 -910
- package/dist/4123.jclic-node.js.map +0 -1
- package/dist/427.jclic-node.js +0 -894
- package/dist/427.jclic-node.js.map +0 -1
- package/dist/4483.jclic-node.js +0 -327
- package/dist/4483.jclic-node.js.map +0 -1
- package/dist/4548.jclic-node.js +0 -1078
- package/dist/4548.jclic-node.js.map +0 -1
- package/dist/466.jclic-node.js +0 -99
- package/dist/466.jclic-node.js.map +0 -1
- package/dist/485.jclic-node.js +0 -783
- package/dist/485.jclic-node.js.map +0 -1
- package/dist/4921.jclic-node.js +0 -500
- package/dist/4921.jclic-node.js.map +0 -1
- package/dist/5091.jclic-node.js +0 -239
- package/dist/5091.jclic-node.js.map +0 -1
- package/dist/520.jclic-node.js +0 -550
- package/dist/520.jclic-node.js.map +0 -1
- package/dist/5312.jclic-node.js +0 -1126
- package/dist/5312.jclic-node.js.map +0 -1
- package/dist/5338.jclic-node.js +0 -212
- package/dist/5338.jclic-node.js.map +0 -1
- package/dist/5344.jclic-node.js +0 -229
- package/dist/5344.jclic-node.js.map +0 -1
- package/dist/5550.jclic-node.js +0 -238
- package/dist/5550.jclic-node.js.map +0 -1
- package/dist/5626.jclic-node.js +0 -614
- package/dist/5626.jclic-node.js.map +0 -1
- package/dist/5977.jclic-node.js +0 -1081
- package/dist/5977.jclic-node.js.map +0 -1
- package/dist/6148.jclic-node.js +0 -345
- package/dist/6148.jclic-node.js.map +0 -1
- package/dist/6176.jclic-node.js +0 -481
- package/dist/6176.jclic-node.js.map +0 -1
- package/dist/6221.jclic-node.js +0 -1072
- package/dist/6221.jclic-node.js.map +0 -1
- package/dist/6238.jclic-node.js +0 -718
- package/dist/6238.jclic-node.js.map +0 -1
- package/dist/6454.jclic-node.js +0 -1413
- package/dist/6454.jclic-node.js.map +0 -1
- package/dist/6565.jclic-node.js +0 -294
- package/dist/6565.jclic-node.js.map +0 -1
- package/dist/6579.jclic-node.js +0 -719
- package/dist/6579.jclic-node.js.map +0 -1
- package/dist/6715.jclic-node.js +0 -148
- package/dist/6715.jclic-node.js.map +0 -1
- package/dist/6777.jclic-node.js +0 -171
- package/dist/6777.jclic-node.js.map +0 -1
- package/dist/6782.jclic-node.js +0 -1611
- package/dist/6782.jclic-node.js.map +0 -1
- package/dist/6847.jclic-node.js +0 -601
- package/dist/6847.jclic-node.js.map +0 -1
- package/dist/6856.jclic-node.js +0 -252
- package/dist/6856.jclic-node.js.map +0 -1
- package/dist/696.jclic-node.js +0 -1821
- package/dist/696.jclic-node.js.map +0 -1
- package/dist/698.jclic-node.js +0 -583
- package/dist/698.jclic-node.js.map +0 -1
- package/dist/704.jclic-node.js +0 -80
- package/dist/704.jclic-node.js.map +0 -1
- package/dist/7046.jclic-node.js +0 -735
- package/dist/7046.jclic-node.js.map +0 -1
- package/dist/7220.jclic-node.js +0 -156
- package/dist/7220.jclic-node.js.map +0 -1
- package/dist/7257.jclic-node.js +0 -931
- package/dist/7257.jclic-node.js.map +0 -1
- package/dist/743.jclic-node.js +0 -583
- package/dist/743.jclic-node.js.map +0 -1
- package/dist/757.jclic-node.js +0 -1072
- package/dist/757.jclic-node.js.map +0 -1
- package/dist/7781.jclic-node.js +0 -202
- package/dist/7781.jclic-node.js.map +0 -1
- package/dist/7912.jclic-node.js +0 -2103
- package/dist/7912.jclic-node.js.map +0 -1
- package/dist/827.jclic-node.js +0 -708
- package/dist/827.jclic-node.js.map +0 -1
- package/dist/8276.jclic-node.js +0 -409
- package/dist/8276.jclic-node.js.map +0 -1
- package/dist/8322.jclic-node.js +0 -498
- package/dist/8322.jclic-node.js.map +0 -1
- package/dist/8641.jclic-node.js +0 -360
- package/dist/8641.jclic-node.js.map +0 -1
- package/dist/8837.jclic-node.js +0 -651
- package/dist/8837.jclic-node.js.map +0 -1
- package/dist/8895.jclic-node.js +0 -151
- package/dist/8895.jclic-node.js.map +0 -1
- package/dist/9072.jclic-node.js +0 -1285
- package/dist/9072.jclic-node.js.map +0 -1
- package/dist/9078.jclic-node.js +0 -935
- package/dist/9078.jclic-node.js.map +0 -1
- package/dist/9103.jclic-node.js +0 -718
- package/dist/9103.jclic-node.js.map +0 -1
- package/dist/9359.jclic-node.js +0 -145
- package/dist/9359.jclic-node.js.map +0 -1
- package/dist/9409.jclic-node.js +0 -921
- package/dist/9409.jclic-node.js.map +0 -1
- package/dist/9513.jclic-node.js +0 -720
- package/dist/9513.jclic-node.js.map +0 -1
- package/dist/9704.jclic-node.js +0 -81
- package/dist/9704.jclic-node.js.map +0 -1
- package/dist/9950.jclic-node.js +0 -827
- package/dist/9950.jclic-node.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"2379.jclic-node.js","mappings":";;;;;;;;;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEyC;;AAEzC;AACA;AACA;AACA;AACA;AACA;AACO;AACP;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,oCAAoC;AACpC,aAAa,iBAAiB;AAC9B,eAAe;AACf;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR,QAAQ,wDAAG,gDAAgD,UAAU;AACrE;AACA;AACA;;AAEA;AACA;AACA,aAAa,iBAAiB;AAC9B;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB;AACA;AACA;AACA,WAAW,4DAAO;AAClB;;AAEA;AACA;AACA,aAAa,QAAQ;AACrB,aAAa,UAAU;AACvB,eAAe;AACf;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,gBAAgB,qFAAqF;AACrG,aAAa,QAAQ;AACrB,aAAa,QAAQ;AACrB,aAAa,kDAAkD,gDAAgD;AAC/G;AACA,aAAa,SAAS,yCAAyC,uEAAuE;AACtI,eAAe,SAAS;AACxB;AACA;AACA;AACA;;AAEA;AACA;AACA,aAAa,2DAA2D;AACxE,eAAe,SAAS;AACxB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,aAAa,QAAQ;AACrB,aAAa,UAAU;AACvB,eAAe,2DAA2D;AAC1E;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,SAAS;AACrB;AACA,CAAC;;AAED;AACA;AACA,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,kDAAkD,gDAAgD;AAC7G;AACA,WAAW,SAAS,wCAAwC,uEAAuE;AACnI;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,oEAAoE,iDAAiD;AACrH,UAAU,QAAQ;AAClB;AACA;AACA;AACA;;AAEA;AACA;;AAEA,iEAAe,mBAAmB,EAAC","sources":["webpack://jclic/./src/automation/AutoContentProvider.js"],"sourcesContent":["/**\n * File : automation/AutoContentProvider.js\n * Created : 13/04/2015\n * By : Francesc Busquets <francesc@gmail.com>\n *\n * JClic.js\n * An HTML5 player of JClic activities\n * https://projectestac.github.io/jclic.js\n *\n * @source https://github.com/projectestac/jclic.js\n *\n * @license EUPL-1.2\n * @licstart\n * (c) 2000-2020 Educational Telematic Network of Catalonia (XTEC)\n *\n * Licensed under the EUPL, Version 1.1 or -as soon they will be approved by\n * the European Commission- subsequent versions of the EUPL (the \"Licence\");\n * You may not use this work except in compliance with the Licence.\n *\n * You may obtain a copy of the Licence at:\n * https://joinup.ec.europa.eu/software/page/eupl\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the Licence is distributed on an \"AS IS\" basis, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n * Licence for the specific language governing permissions and limitations\n * under the Licence.\n * @licend\n * @module\n */\n\nimport {log, getAttr} from '../Utils.js';\n\n/**\n * This abstract class is the base for classes that create on-time automatic content for JClic\n * activities, usually using random parameters to assure different content in each session.\n *\n * Activities with `AutoContentProvider` objects rely on them to build new content on every start.\n */\nexport class AutoContentProvider {\n /**\n * AutoContentProvider constructor\n */\n constructor() {\n }\n\n /**\n * Dynamic constructor that returns a specific type of AutoContentProvider based on the `class`\n * attribute declared on an $xml element.\n * It should be called only from {@link module:Activity.Activity#setProperties Activity.setProperties}\n * @param {external.jQuery} $xml - The XML element to parse\n * @returns {module:automation/AutoContentProvider.AutoContentProvider}\n */\n static getProvider($xml) {\n let automation = null;\n if ($xml) {\n const\n className = ($xml.attr('class') || '').replace(/^edu\\.xtec\\.jclic\\.automation\\./, '@'),\n cl = AutoContentProvider.CLASSES[className];\n if (cl) {\n automation = new cl();\n automation.setProperties($xml);\n } else\n log('error', `Unknown AutoContentProvider class: ${className}`);\n }\n return automation;\n }\n\n /**\n * Loads the object settings from a specific jQuery XML element\n * @param {external:jQuery} $xml - The XML element to parse\n */\n setProperties($xml) {\n this.className = ($xml.attr('class') || '').replace(/^edu\\.xtec\\.jclic\\.automation\\./, '@');\n return this;\n }\n\n /**\n * Gets a object with the basic attributes needed to rebuild this instance excluding functions,\n * parent references, constants and also attributes retaining the default value.\n * The resulting object is commonly usued to serialize elements in JSON format.\n * @returns {object} - The resulting object, with minimal attrributes\n */\n getAttributes() {\n // To be overrided!\n return getAttr(this, ['className']);\n }\n\n /**\n * Builds a new AutoContentProvider, based on the properties specified in a data object\n * @param {object} data - The data object to be parsed\n * @param {object[]} params - Optional parameters to be passed to `setAttributes`\n * @returns {module:shapers/Shaper.Shaper}\n */\n static factory(data, params = []) {\n const cl = AutoContentProvider.CLASSES[data.className];\n return (new cl()).setAttributes(data, ...params);\n }\n\n /**\n * Initializes the content provider\n */\n init() {\n // To be implemented in real content providers\n }\n\n /**\n * Builds an {@link module:automation/AutoContentProvider/ActiveBagContentKit ActiveBagContentKit} and generates the automatized content.\n * @param {number} nRows - Number of rows to be processed\n * @param {number} nCols - Number of columns to be processed\n * @param {module:boxes/ActiveBagContent.ActiveBagContent[]} content - Array with one or more containers of {@link module:boxes/ActiveBoxContent.ActiveBoxContent ActiveBoxContent}\n * objects to be filled with new content.\n * @param {boolean} useIds - When `true`, the `id` field of {@link module:boxes/ActiveBoxContent.ActiveBoxContent ActiveBoxContent} objects is significant\n * @returns {boolean} - `true` if the process was OK. `false` otherwise.\n */\n generateContent(nRows, nCols, content, useIds) {\n return this.process(new AutoContentProvider.ActiveBagContentKit(nRows, nCols, content, useIds));\n }\n\n /**\n * Generates the automatized content\n * @param {module:automation/AutoContentProvider.ActiveBagContentKit} _kit - The objects to be filled with content\n * @returns {boolean} - `true` if the process was OK. `false` otherwise.\n */\n process(_kit) {\n // To be implemented in subclasses\n return false;\n }\n\n /**\n * Registers a new type of AutoContentProvider\n * @param {string} providerName - The name used to identify this AutoContentProvider\n * @param {function} providerClass - The activity class, usually extending AutoContentProvider\n * @returns {module:automation/AutoContentProvider.AutoContentProvider} - The provider class\n */\n static registerClass(providerName, providerClass) {\n AutoContentProvider.CLASSES[providerName] = providerClass;\n return providerClass;\n }\n}\n\nObject.assign(AutoContentProvider.prototype, {\n /**\n * This AutoContentProvider manages numeric expressions, so text literals should be\n * converted to numbers for comparisions, taking in account the\n * number format of the current locale (dot or comma as decimal separator)\n * @name module:automation/AutoContentProvider.AutoContentProvider#numericContent\n * @type {boolean} */\n numericContent: false,\n});\n\n/**\n * Utility class used to encapsulate multiple sets of box contents\n * @param {number} nRows - Number of rows to be processed\n * @param {number} nCols - Number of columns to be processed\n * @param {module:boxes/ActiveBagContent.ActiveBagContent[]} content - Array with one or more containers of {@link module:boxes/ActiveBoxContent.ActiveBoxContent ActiveBoxContent}\n * objects to be filled with new content.\n * @param {boolean} useIds - `true` when the `id` field of {@link module:boxes/ActiveBoxContent.ActiveBoxContent ActiveBoxContent} objects is significant.\n */\nAutoContentProvider.ActiveBagContentKit = class {\n constructor(nRows, nCols, content, useIds) {\n this.nRows = nRows;\n this.nCols = nCols;\n this.content = content;\n this.useIds = useIds;\n }\n};\n\n/**\n * Contains the current list of classes derived from AutoContentProvider.\n * This object should be updated by real automation classes at declaration time.\n * Currently, only two types of \"AutoContentProvider\" are defined: {@link module:automation/arith/Arith.Arith Arith} and TagReplace.\n * @type {object} */\nAutoContentProvider.CLASSES = {\n // TODO: Implement TagReplace\n '@tagreplace.TagReplace': AutoContentProvider\n};\n\n// TODO: Implement TagReplace\nAutoContentProvider.registerClass('@tagreplace.TagReplace', AutoContentProvider);\n\nexport default AutoContentProvider;\n"],"names":[],"sourceRoot":""}
|
package/dist/2437.jclic-node.js
DELETED
|
@@ -1,450 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
exports.id = 2437;
|
|
3
|
-
exports.ids = [2437];
|
|
4
|
-
exports.modules = {
|
|
5
|
-
|
|
6
|
-
/***/ 2437:
|
|
7
|
-
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
8
|
-
|
|
9
|
-
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
10
|
-
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
|
|
11
|
-
/* harmony export */ });
|
|
12
|
-
/* unused harmony exports FillInBlanks, FillInBlanksPanel */
|
|
13
|
-
/* harmony import */ var _Activity_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1567);
|
|
14
|
-
/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(7750);
|
|
15
|
-
/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(jquery__WEBPACK_IMPORTED_MODULE_1__);
|
|
16
|
-
/* harmony import */ var _Utils_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(1253);
|
|
17
|
-
/* harmony import */ var _TextActivityBase_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(743);
|
|
18
|
-
/**
|
|
19
|
-
* File : activities/text/FillInBlanks.js
|
|
20
|
-
* Created : 20/06/2015
|
|
21
|
-
* By : Francesc Busquets <francesc@gmail.com>
|
|
22
|
-
*
|
|
23
|
-
* JClic.js
|
|
24
|
-
* An HTML5 player of JClic activities
|
|
25
|
-
* https://projectestac.github.io/jclic.js
|
|
26
|
-
*
|
|
27
|
-
* @source https://github.com/projectestac/jclic.js
|
|
28
|
-
*
|
|
29
|
-
* @license EUPL-1.2
|
|
30
|
-
* @licstart
|
|
31
|
-
* (c) 2000-2020 Catalan Educational Telematic Network (XTEC)
|
|
32
|
-
*
|
|
33
|
-
* Licensed under the EUPL, Version 1.1 or -as soon they will be approved by
|
|
34
|
-
* the European Commission- subsequent versions of the EUPL (the "Licence");
|
|
35
|
-
* You may not use this work except in compliance with the Licence.
|
|
36
|
-
*
|
|
37
|
-
* You may obtain a copy of the Licence at:
|
|
38
|
-
* https://joinup.ec.europa.eu/software/page/eupl
|
|
39
|
-
*
|
|
40
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
41
|
-
* distributed under the Licence is distributed on an "AS IS" basis, WITHOUT
|
|
42
|
-
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
43
|
-
* Licence for the specific language governing permissions and limitations
|
|
44
|
-
* under the Licence.
|
|
45
|
-
* @licend
|
|
46
|
-
* @module
|
|
47
|
-
*/
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* In this type of activity the text document has some blanks that must be filled-in. The blanks
|
|
56
|
-
* can be drop-down boxes or text fields (empty or pre-filled with an initial text). Blanks can
|
|
57
|
-
* also have associated clues, shown as "pop-ups".
|
|
58
|
-
* @extends module:activities/text/TextActivityBase.TextActivityBase
|
|
59
|
-
*/
|
|
60
|
-
class FillInBlanks extends _TextActivityBase_js__WEBPACK_IMPORTED_MODULE_3__/* .TextActivityBase */ .q {
|
|
61
|
-
/**
|
|
62
|
-
* FillInBlanks constructor
|
|
63
|
-
* @param {module:project/JClicProject.JClicProject} project - The {@link module:project/JClicProject.JClicProject JClicProject} to which this activity belongs
|
|
64
|
-
*/
|
|
65
|
-
constructor(project) {
|
|
66
|
-
super(project);
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
* This kind of activity usually makes use of the keyboard
|
|
71
|
-
* @override
|
|
72
|
-
* @returns {boolean}
|
|
73
|
-
*/
|
|
74
|
-
needsKeyboard() {
|
|
75
|
-
return true;
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
Object.assign(FillInBlanks.prototype, {
|
|
80
|
-
/**
|
|
81
|
-
* Whether to jump or not to the next target when the current one is solved.
|
|
82
|
-
* @name module:activities/text/FillInBlanks.FillInBlanks#autoJump
|
|
83
|
-
* @type {boolean} */
|
|
84
|
-
autoJump: false,
|
|
85
|
-
/**
|
|
86
|
-
* Whether to block or not the jump to other targets until the current one
|
|
87
|
-
* is resolved.
|
|
88
|
-
* @name module:activities/text/FillInBlanks.FillInBlanks#forceOkToAdvance
|
|
89
|
-
* @type {boolean} */
|
|
90
|
-
forceOkToAdvance: false,
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
/**
|
|
94
|
-
* The {@link module:activities/text/TextActivityBase.TextActivityBasePanel} where {@link module:activities/text/FillInBlanks.FillInBlanks FillInBlanks} activities are played.
|
|
95
|
-
* @extends module:activities/text/TextActivityBase.TextActivityBasePanel
|
|
96
|
-
*/
|
|
97
|
-
class FillInBlanksPanel extends _TextActivityBase_js__WEBPACK_IMPORTED_MODULE_3__/* .TextActivityBasePanel */ .c {
|
|
98
|
-
/**
|
|
99
|
-
* FillInBlanksPanel constructor
|
|
100
|
-
* @param {module:Activity.Activity} act - The {@link module:Activity.Activity Activity} to which this Panel belongs
|
|
101
|
-
* @param {module:JClicPlayer.JClicPlayer} ps - Any object implementing the methods defined in the
|
|
102
|
-
* [PlayStation](http://projectestac.github.io/jclic/apidoc/edu/xtec/jclic/PlayStation.html) Java interface.
|
|
103
|
-
* @param {external:jQuery} [$div] - The jQuery DOM element where this Panel will deploy
|
|
104
|
-
*/
|
|
105
|
-
constructor(act, ps, $div) {
|
|
106
|
-
super(act, ps, $div);
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
/**
|
|
110
|
-
* Creates a target DOM element for the provided target. This DOM element can be an editable
|
|
111
|
-
* `span` or a `select` with specific `option` elements (when the target is a drop-down list)
|
|
112
|
-
* @override
|
|
113
|
-
* @param {module:activities/text/TextActivityDocument.TextTarget} target - The target related to the DOM object to be created
|
|
114
|
-
* @param {external:jQuery} $span - - An initial DOM object (usually a `span`) that can be used
|
|
115
|
-
* to store the target, or replaced by another type of object.
|
|
116
|
-
* @returns {external:jQuery} - The jQuery DOM element loaded with the target data.
|
|
117
|
-
*/
|
|
118
|
-
$createTargetElement(target, $span) {
|
|
119
|
-
|
|
120
|
-
$span.addClass('JClicTextTarget');
|
|
121
|
-
|
|
122
|
-
const idLabel = `target${`000${this.targets.length - 1}`.slice(-3)}`;
|
|
123
|
-
if (target.isList && target.options && target.options.length > 0) {
|
|
124
|
-
// Use a `select` element
|
|
125
|
-
$span = jquery__WEBPACK_IMPORTED_MODULE_1___default()('<select/>', { id: idLabel, name: idLabel });
|
|
126
|
-
if (target.options[0].trim() !== '')
|
|
127
|
-
jquery__WEBPACK_IMPORTED_MODULE_1___default()('<option selected/>', { value: '', text: '' }).appendTo($span);
|
|
128
|
-
target.options.forEach(op => jquery__WEBPACK_IMPORTED_MODULE_1___default()('<option/>', { value: op, text: op }).appendTo($span));
|
|
129
|
-
target.$comboList = $span.bind('focus change', event => {
|
|
130
|
-
event.textTarget = target;
|
|
131
|
-
this.processEvent(event);
|
|
132
|
-
});
|
|
133
|
-
} else {
|
|
134
|
-
// Use a `span` element with the `contentEditable` attribute set `on`
|
|
135
|
-
target.currentText = target.iniText ?
|
|
136
|
-
target.iniText
|
|
137
|
-
: (0,_Utils_js__WEBPACK_IMPORTED_MODULE_2__/* .fillString */ .vD)(target.iniChar, target.numIniChars);
|
|
138
|
-
|
|
139
|
-
target.$span = $span.text(target.currentText).attr({
|
|
140
|
-
contenteditable: 'true',
|
|
141
|
-
id: idLabel,
|
|
142
|
-
autocomplete: 'off',
|
|
143
|
-
spellcheck: 'false'
|
|
144
|
-
}).bind('focus input blur', event => {
|
|
145
|
-
event.textTarget = target;
|
|
146
|
-
this.processEvent(event);
|
|
147
|
-
}).bind('keydown keyup', event => {
|
|
148
|
-
// Catch `enter` key in Firefox
|
|
149
|
-
if (event.keyCode === 13) {
|
|
150
|
-
event.preventDefault();
|
|
151
|
-
if (event.type === 'keydown') {
|
|
152
|
-
// Simulate a `blur` event
|
|
153
|
-
event.textTarget = target;
|
|
154
|
-
event.type = 'blur';
|
|
155
|
-
this.processEvent(event);
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
});
|
|
159
|
-
}
|
|
160
|
-
return $span;
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
/**
|
|
164
|
-
* Evaluates all the targets in this panel. This method is usually called from the `Check` button.
|
|
165
|
-
* @override
|
|
166
|
-
* @returns {boolean} - `true` when all targets are OK, `false` otherwise.
|
|
167
|
-
*/
|
|
168
|
-
evaluatePanel() {
|
|
169
|
-
let targetsOk = 0;
|
|
170
|
-
const numTargets = this.targets.length;
|
|
171
|
-
this.targets.forEach(target => {
|
|
172
|
-
const
|
|
173
|
-
result = this.act.ev.evalText(target.readCurrentText(), target.answers),
|
|
174
|
-
ok = this.act.ev.isOk(result);
|
|
175
|
-
target.targetStatus = ok ? 'SOLVED' : 'WITH_ERROR';
|
|
176
|
-
if (ok)
|
|
177
|
-
targetsOk++;
|
|
178
|
-
this.markTarget(target, result);
|
|
179
|
-
this.ps.reportNewAction(this.act, 'WRITE', target.currentText, target.getAnswers(), ok, targetsOk);
|
|
180
|
-
});
|
|
181
|
-
if (targetsOk === numTargets) {
|
|
182
|
-
this.finishActivity(true);
|
|
183
|
-
return true;
|
|
184
|
-
} else
|
|
185
|
-
this.playEvent('finishedError');
|
|
186
|
-
return false;
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
/**
|
|
190
|
-
* Checks if the specified TextTarget has a valid answer in its `currentText` field
|
|
191
|
-
* @param {module:activities/text/TextActivityDocument.TextTarget} target - The target to check
|
|
192
|
-
* @param {boolean} onlyCheck - When `true`, the cursor will no be re-positioned
|
|
193
|
-
* @param {number} [jumpDirection] - `1` to go forward, `-1` to go back.
|
|
194
|
-
* @returns {boolean} - `true` when the target contains a valid answer
|
|
195
|
-
*/
|
|
196
|
-
checkTarget(target, onlyCheck, jumpDirection) {
|
|
197
|
-
const
|
|
198
|
-
result = this.act.ev.evalText(target.currentText, target.answers),
|
|
199
|
-
ok = this.act.ev.isOk(result);
|
|
200
|
-
|
|
201
|
-
target.targetStatus = ok ? 'SOLVED' : 'WITH_ERROR';
|
|
202
|
-
if (onlyCheck)
|
|
203
|
-
return ok;
|
|
204
|
-
|
|
205
|
-
this.markTarget(target, result);
|
|
206
|
-
const targetsOk = this.countSolvedTargets(false, false);
|
|
207
|
-
if (target.currentText.length > 0)
|
|
208
|
-
this.ps.reportNewAction(this.act, 'WRITE', target.currentText, target.getAnswers(), ok, targetsOk);
|
|
209
|
-
if (ok && targetsOk === this.targets.length) {
|
|
210
|
-
this.finishActivity(true);
|
|
211
|
-
return ok;
|
|
212
|
-
} else if (target.currentText.length > 0)
|
|
213
|
-
this.playEvent(ok ? 'actionOk' : 'actionError');
|
|
214
|
-
|
|
215
|
-
if (jumpDirection && jumpDirection !== 0) {
|
|
216
|
-
let p = target.num + jumpDirection;
|
|
217
|
-
if (p >= this.targets.length)
|
|
218
|
-
p = 0;
|
|
219
|
-
else if (p < 0)
|
|
220
|
-
p = this.targets.length - 1;
|
|
221
|
-
|
|
222
|
-
const destTarget = this.targets[p];
|
|
223
|
-
if (destTarget.$span) {
|
|
224
|
-
destTarget.$span.focus();
|
|
225
|
-
(0,_Utils_js__WEBPACK_IMPORTED_MODULE_2__/* .setSelectionRange */ .eG)(destTarget.$span.get(-1), 0, 0);
|
|
226
|
-
} else if (destTarget.$comboList)
|
|
227
|
-
destTarget.$comboList.focus();
|
|
228
|
-
}
|
|
229
|
-
return ok;
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
/**
|
|
233
|
-
* Counts the number of targets with `SOLVED` status
|
|
234
|
-
* @param {boolean} checkNow - When `true`, all targets will be evaluated. Otherwise, only the
|
|
235
|
-
* current value of `targetStatus` will be checked.
|
|
236
|
-
* @param {boolean} [mark] - When `true`, errors in the target answer will be marked.
|
|
237
|
-
* @returns {number} - The number of targets currently solved.
|
|
238
|
-
*/
|
|
239
|
-
countSolvedTargets(checkNow, mark) {
|
|
240
|
-
return this.targets.reduce((n, target) => {
|
|
241
|
-
if (checkNow) {
|
|
242
|
-
target.readCurrentText();
|
|
243
|
-
this.checkTarget(target, !mark);
|
|
244
|
-
}
|
|
245
|
-
return target.targetStatus === 'SOLVED' ? ++n : n;
|
|
246
|
-
}, 0);
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
/**
|
|
250
|
-
* Visually marks the target as 'solved OK' or 'with errors'.
|
|
251
|
-
* @param {module:activities/text/TextActivityDocument.TextTarget} target - The text target to be marked.
|
|
252
|
-
* @param {number[]} attributes - - Array of flags indicating the status (OK or error) for each
|
|
253
|
-
* character in `target.currentText`.
|
|
254
|
-
*/
|
|
255
|
-
markTarget(target, attributes) {
|
|
256
|
-
if (target.$comboList || this.act.ev.isOk(attributes))
|
|
257
|
-
target.checkColors();
|
|
258
|
-
else if (target.$span) {
|
|
259
|
-
// Identify text fragments
|
|
260
|
-
const
|
|
261
|
-
txt = target.currentText,
|
|
262
|
-
fragments = [];
|
|
263
|
-
let
|
|
264
|
-
currentStatus = -1,
|
|
265
|
-
currentFragment = -1,
|
|
266
|
-
i = 0;
|
|
267
|
-
for (; i < attributes.length && i < txt.length; i++) {
|
|
268
|
-
if (attributes[i] !== currentStatus) {
|
|
269
|
-
fragments[++currentFragment] = '';
|
|
270
|
-
currentStatus = attributes[i];
|
|
271
|
-
}
|
|
272
|
-
fragments[currentFragment] += txt.charAt(i);
|
|
273
|
-
}
|
|
274
|
-
if (i < txt.length)
|
|
275
|
-
fragments[currentFragment] += txt.substring(i);
|
|
276
|
-
// Empty and re-fill $span
|
|
277
|
-
target.$span.empty();
|
|
278
|
-
currentStatus = attributes[0];
|
|
279
|
-
fragments.forEach(fragment => {
|
|
280
|
-
jquery__WEBPACK_IMPORTED_MODULE_1___default()('<span/>')
|
|
281
|
-
.text(fragment)
|
|
282
|
-
.css(target.doc.style[currentStatus === 0 ? 'target' : 'targetError'].css)
|
|
283
|
-
.appendTo(target.$span);
|
|
284
|
-
currentStatus ^= 1;
|
|
285
|
-
});
|
|
286
|
-
}
|
|
287
|
-
// Target has been marked, so clear the 'modified' flag
|
|
288
|
-
target.flagModified = false;
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
/**
|
|
292
|
-
* Called by {@link module:JClicPlayer.JClicPlayer JClicPlayer} when this activity panel is fully visible, just after the
|
|
293
|
-
* initialization process.
|
|
294
|
-
* @override
|
|
295
|
-
*/
|
|
296
|
-
activityReady() {
|
|
297
|
-
super.activityReady();
|
|
298
|
-
|
|
299
|
-
// Prevent strange behavior with GoogleChrome when `white-space` CSS attribute is set to
|
|
300
|
-
// `pre-wrap` (needed for tabulated texts)
|
|
301
|
-
jquery__WEBPACK_IMPORTED_MODULE_1___default()('.JClicTextTarget').css('white-space', 'normal');
|
|
302
|
-
if (this.targets.length > 0 && this.targets[0].$span)
|
|
303
|
-
this.targets[0].$span.focus();
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
/**
|
|
307
|
-
* Ordinary ending of the activity, usually called form `processEvent`
|
|
308
|
-
* @override
|
|
309
|
-
* @param {boolean} result - `true` if the activity was successfully completed, `false` otherwise
|
|
310
|
-
*/
|
|
311
|
-
finishActivity(result) {
|
|
312
|
-
this.targets.forEach(target => {
|
|
313
|
-
if (target.$span)
|
|
314
|
-
target.$span.removeAttr('contenteditable').blur();
|
|
315
|
-
else if (target.$comboList)
|
|
316
|
-
target.$comboList.attr('disabled', 'true').blur();
|
|
317
|
-
});
|
|
318
|
-
return super.finishActivity(result);
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
/**
|
|
322
|
-
* Main handler used to process mouse, touch, keyboard and edit events.
|
|
323
|
-
* @override
|
|
324
|
-
* @param {external:Event} event - The HTML event to be processed
|
|
325
|
-
* @returns {boolean} - When this event handler returns `false`, jQuery will stop its
|
|
326
|
-
* propagation through the DOM tree. See: {@link http://api.jquery.com/on}
|
|
327
|
-
*/
|
|
328
|
-
processEvent(event) {
|
|
329
|
-
if (!super.processEvent(event))
|
|
330
|
-
return false;
|
|
331
|
-
|
|
332
|
-
const target = event.textTarget;
|
|
333
|
-
let $span = null, pos = 0;
|
|
334
|
-
switch (event.type) {
|
|
335
|
-
case 'focus':
|
|
336
|
-
if (target) {
|
|
337
|
-
if (target.$span && target.$span.children().length > 0) {
|
|
338
|
-
// Clear inner spans used to mark errors
|
|
339
|
-
$span = target.$span;
|
|
340
|
-
pos = Math.min(
|
|
341
|
-
target.currentText.length,
|
|
342
|
-
(0,_Utils_js__WEBPACK_IMPORTED_MODULE_2__/* .getCaretCharacterOffsetWithin */ .Hb)($span.get(-1)));
|
|
343
|
-
$span.empty();
|
|
344
|
-
$span.text(target.currentText);
|
|
345
|
-
(0,_Utils_js__WEBPACK_IMPORTED_MODULE_2__/* .setSelectionRange */ .eG)($span.get(-1), pos, pos);
|
|
346
|
-
target.flagModified = true;
|
|
347
|
-
} else if (target.$comboList)
|
|
348
|
-
target.$comboList.css(target.doc.style['target'].css);
|
|
349
|
-
|
|
350
|
-
if (target.$popup && (target.infoMode === 'always' || target.infoMode === 'onError' && target.targetStatus === 'WITH_ERROR'))
|
|
351
|
-
this.showPopup(target.$popup, target.popupMaxTime, target.popupDelay);
|
|
352
|
-
else
|
|
353
|
-
this.showPopup(null);
|
|
354
|
-
}
|
|
355
|
-
break;
|
|
356
|
-
|
|
357
|
-
case 'blur':
|
|
358
|
-
if (target.flagModified && !this.$checkButton)
|
|
359
|
-
this.checkTarget(target, false, 1);
|
|
360
|
-
break;
|
|
361
|
-
|
|
362
|
-
case 'input':
|
|
363
|
-
if (target && target.$span) {
|
|
364
|
-
$span = target.$span;
|
|
365
|
-
let txt = $span.html();
|
|
366
|
-
// Check for `enter` key
|
|
367
|
-
if (/(<br>|\n|\r)/.test(txt)) {
|
|
368
|
-
txt = txt.replace(/(<br>|\n|\r)/g, '');
|
|
369
|
-
$span.html(txt);
|
|
370
|
-
target.currentText = $span.text();
|
|
371
|
-
return this.$checkButton ? false : this.checkTarget(target, false, 1);
|
|
372
|
-
}
|
|
373
|
-
// Check if text has changed
|
|
374
|
-
// From here, use 'text' instead of 'html' to avoid HTML entities
|
|
375
|
-
txt = $span.text();
|
|
376
|
-
if (txt !== target.currentText) {
|
|
377
|
-
// Span text has changed!
|
|
378
|
-
target.flagModified = true;
|
|
379
|
-
const added = txt.length - target.currentText.length;
|
|
380
|
-
if (added > 0) {
|
|
381
|
-
if (txt.indexOf(target.iniChar) >= 0) {
|
|
382
|
-
// Remove filling chars
|
|
383
|
-
pos = (0,_Utils_js__WEBPACK_IMPORTED_MODULE_2__/* .getCaretCharacterOffsetWithin */ .Hb)($span.get(-1));
|
|
384
|
-
for (let i = 0; i < added; i++) {
|
|
385
|
-
const p = txt.indexOf(target.iniChar);
|
|
386
|
-
if (p < 0)
|
|
387
|
-
break;
|
|
388
|
-
txt = txt.substring(0, p) + txt.substring(p + 1);
|
|
389
|
-
if (p < pos)
|
|
390
|
-
pos--;
|
|
391
|
-
}
|
|
392
|
-
$span.text(txt);
|
|
393
|
-
(0,_Utils_js__WEBPACK_IMPORTED_MODULE_2__/* .setSelectionRange */ .eG)($span.get(-1), pos, pos);
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
// Check if current text exceeds max length
|
|
397
|
-
if (txt.length > target.maxLenResp) {
|
|
398
|
-
pos = (0,_Utils_js__WEBPACK_IMPORTED_MODULE_2__/* .getCaretCharacterOffsetWithin */ .Hb)($span.get(-1));
|
|
399
|
-
txt = txt.substring(0, target.maxLenResp);
|
|
400
|
-
pos = Math.min(pos, txt.length);
|
|
401
|
-
$span.text(txt);
|
|
402
|
-
(0,_Utils_js__WEBPACK_IMPORTED_MODULE_2__/* .setSelectionRange */ .eG)($span.get(-1), pos, pos);
|
|
403
|
-
}
|
|
404
|
-
} else if (txt === '') {
|
|
405
|
-
txt = target.iniChar;
|
|
406
|
-
$span.text(txt);
|
|
407
|
-
(0,_Utils_js__WEBPACK_IMPORTED_MODULE_2__/* .setSelectionRange */ .eG)($span.get(-1), 0, 0);
|
|
408
|
-
}
|
|
409
|
-
target.currentText = txt;
|
|
410
|
-
}
|
|
411
|
-
}
|
|
412
|
-
break;
|
|
413
|
-
|
|
414
|
-
case 'change':
|
|
415
|
-
if (target && target.$comboList) {
|
|
416
|
-
target.currentText = target.$comboList.val();
|
|
417
|
-
target.flagModified = true;
|
|
418
|
-
return this.$checkButton ? false : this.checkTarget(target, false, 1);
|
|
419
|
-
}
|
|
420
|
-
break;
|
|
421
|
-
|
|
422
|
-
default:
|
|
423
|
-
break;
|
|
424
|
-
}
|
|
425
|
-
return true;
|
|
426
|
-
}
|
|
427
|
-
}
|
|
428
|
-
|
|
429
|
-
Object.assign(FillInBlanksPanel.prototype, {
|
|
430
|
-
/**
|
|
431
|
-
* Flag indicating if the activity is open or locked
|
|
432
|
-
* @name module:activities/text/FillInBlanks.FillInBlanksPanel#locked
|
|
433
|
-
* @type {boolean} */
|
|
434
|
-
locked: true,
|
|
435
|
-
});
|
|
436
|
-
|
|
437
|
-
/**
|
|
438
|
-
* Panel class associated to this type of activity: {@link module:activities/text/FillInBlanks.FillInBlanksPanel FillInBlanksPanel}
|
|
439
|
-
* @type {class} */
|
|
440
|
-
FillInBlanks.Panel = FillInBlanksPanel;
|
|
441
|
-
|
|
442
|
-
// Register activity class
|
|
443
|
-
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (_Activity_js__WEBPACK_IMPORTED_MODULE_0__["default"].registerClass('@text.FillInBlanks', FillInBlanks));
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
/***/ })
|
|
447
|
-
|
|
448
|
-
};
|
|
449
|
-
;
|
|
450
|
-
//# sourceMappingURL=2437.jclic-node.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"2437.jclic-node.js","mappings":";;;;;;;;;;;;;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEyC;AAClB;AACuE;AACd;;AAEhF;AACA;AACA;AACA;AACA;AACA;AACO,2BAA2B,2EAAgB;AAClD;AACA;AACA,aAAa,0CAA0C,eAAe,6DAA6D;AACnI;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,eAAe;AACf;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAY,SAAS;AACrB;AACA;AACA;AACA;AACA;AACA,YAAY,SAAS;AACrB;AACA,CAAC;;AAED;AACA,QAAQ,qEAAqE,OAAO,qEAAqE;AACzJ;AACA;AACO,gCAAgC,gFAAqB;AAC5D;AACA;AACA,aAAa,0BAA0B,WAAW,yCAAyC;AAC3F,aAAa,gCAAgC;AAC7C;AACA,aAAa,iBAAiB;AAC9B;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAa,wDAAwD;AACrE,aAAa,iBAAiB;AAC9B;AACA,eAAe,iBAAiB;AAChC;AACA;;AAEA;;AAEA,6BAA6B,MAAM,wBAAwB,YAAY;AACvE;AACA;AACA,cAAc,6CAAC,gBAAgB,4BAA4B;AAC3D;AACA,QAAQ,6CAAC,yBAAyB,qBAAqB;AACvD,mCAAmC,6CAAC,gBAAgB,qBAAqB;AACzE;AACA;AACA;AACA,OAAO;AACP,MAAM;AACN;AACA;AACA;AACA,UAAU,+DAAU;;AAEpB;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;;AAEA;AACA;AACA;AACA,eAAe,SAAS;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;;AAEA;AACA;AACA,aAAa,wDAAwD;AACrE,aAAa,SAAS;AACtB,aAAa,QAAQ;AACrB,eAAe,SAAS;AACxB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,QAAQ,sEAAiB;AACzB,QAAQ;AACR;AACA;AACA;AACA;;AAEA;AACA;AACA,aAAa,SAAS;AACtB;AACA,aAAa,SAAS;AACtB,eAAe,QAAQ;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;;AAEA;AACA;AACA,aAAa,wDAAwD;AACrE,aAAa,UAAU;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,yCAAyC;AACtD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,6CAAC;AACT;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;;AAEA;AACA,gBAAgB,kDAAkD;AAClE;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,IAAI,6CAAC;AACL;AACA;AACA;;AAEA;AACA;AACA;AACA,aAAa,SAAS;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;;AAEA;AACA;AACA;AACA,aAAa,gBAAgB;AAC7B,eAAe,SAAS;AACxB,6CAA6C;AAC7C;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,kFAA6B;AAC3C;AACA;AACA,YAAY,sEAAiB;AAC7B;AACA,YAAY;AACZ;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB,kFAA6B;AACnD,gCAAgC,WAAW;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,sEAAiB;AACjC;;AAEA;AACA;AACA,sBAAsB,kFAA6B;AACnD;AACA;AACA;AACA,gBAAgB,sEAAiB;AACjC;AACA,cAAc;AACd;AACA;AACA,cAAc,sEAAiB;AAC/B;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAY,SAAS;AACrB;AACA,CAAC;;AAED;AACA,qDAAqD;AACrD,UAAU,OAAO;AACjB;;AAEA;AACA,iEAAe,oDAAQ,kDAAkD,EAAC","sources":["webpack://jclic/./src/activities/text/FillInBlanks.js"],"sourcesContent":["/**\n * File : activities/text/FillInBlanks.js\n * Created : 20/06/2015\n * By : Francesc Busquets <francesc@gmail.com>\n *\n * JClic.js\n * An HTML5 player of JClic activities\n * https://projectestac.github.io/jclic.js\n *\n * @source https://github.com/projectestac/jclic.js\n *\n * @license EUPL-1.2\n * @licstart\n * (c) 2000-2020 Catalan Educational Telematic Network (XTEC)\n *\n * Licensed under the EUPL, Version 1.1 or -as soon they will be approved by\n * the European Commission- subsequent versions of the EUPL (the \"Licence\");\n * You may not use this work except in compliance with the Licence.\n *\n * You may obtain a copy of the Licence at:\n * https://joinup.ec.europa.eu/software/page/eupl\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the Licence is distributed on an \"AS IS\" basis, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n * Licence for the specific language governing permissions and limitations\n * under the Licence.\n * @licend\n * @module\n */\n\nimport Activity from '../../Activity.js';\nimport $ from 'jquery';\nimport { fillString, setSelectionRange, getCaretCharacterOffsetWithin } from '../../Utils.js';\nimport { TextActivityBase, TextActivityBasePanel } from './TextActivityBase.js';\n\n/**\n * In this type of activity the text document has some blanks that must be filled-in. The blanks\n * can be drop-down boxes or text fields (empty or pre-filled with an initial text). Blanks can\n * also have associated clues, shown as \"pop-ups\".\n * @extends module:activities/text/TextActivityBase.TextActivityBase\n */\nexport class FillInBlanks extends TextActivityBase {\n /**\n * FillInBlanks constructor\n * @param {module:project/JClicProject.JClicProject} project - The {@link module:project/JClicProject.JClicProject JClicProject} to which this activity belongs\n */\n constructor(project) {\n super(project);\n }\n\n /**\n * This kind of activity usually makes use of the keyboard\n * @override\n * @returns {boolean}\n */\n needsKeyboard() {\n return true;\n }\n}\n\nObject.assign(FillInBlanks.prototype, {\n /**\n * Whether to jump or not to the next target when the current one is solved.\n * @name module:activities/text/FillInBlanks.FillInBlanks#autoJump\n * @type {boolean} */\n autoJump: false,\n /**\n * Whether to block or not the jump to other targets until the current one\n * is resolved.\n * @name module:activities/text/FillInBlanks.FillInBlanks#forceOkToAdvance\n * @type {boolean} */\n forceOkToAdvance: false,\n});\n\n/**\n * The {@link module:activities/text/TextActivityBase.TextActivityBasePanel} where {@link module:activities/text/FillInBlanks.FillInBlanks FillInBlanks} activities are played.\n * @extends module:activities/text/TextActivityBase.TextActivityBasePanel\n */\nexport class FillInBlanksPanel extends TextActivityBasePanel {\n /**\n * FillInBlanksPanel constructor\n * @param {module:Activity.Activity} act - The {@link module:Activity.Activity Activity} to which this Panel belongs\n * @param {module:JClicPlayer.JClicPlayer} ps - Any object implementing the methods defined in the\n * [PlayStation](http://projectestac.github.io/jclic/apidoc/edu/xtec/jclic/PlayStation.html) Java interface.\n * @param {external:jQuery} [$div] - The jQuery DOM element where this Panel will deploy\n */\n constructor(act, ps, $div) {\n super(act, ps, $div);\n }\n\n /**\n * Creates a target DOM element for the provided target. This DOM element can be an editable\n * `span` or a `select` with specific `option` elements (when the target is a drop-down list)\n * @override\n * @param {module:activities/text/TextActivityDocument.TextTarget} target - The target related to the DOM object to be created\n * @param {external:jQuery} $span - - An initial DOM object (usually a `span`) that can be used\n * to store the target, or replaced by another type of object.\n * @returns {external:jQuery} - The jQuery DOM element loaded with the target data.\n */\n $createTargetElement(target, $span) {\n\n $span.addClass('JClicTextTarget');\n\n const idLabel = `target${`000${this.targets.length - 1}`.slice(-3)}`;\n if (target.isList && target.options && target.options.length > 0) {\n // Use a `select` element\n $span = $('<select/>', { id: idLabel, name: idLabel });\n if (target.options[0].trim() !== '')\n $('<option selected/>', { value: '', text: '' }).appendTo($span);\n target.options.forEach(op => $('<option/>', { value: op, text: op }).appendTo($span));\n target.$comboList = $span.bind('focus change', event => {\n event.textTarget = target;\n this.processEvent(event);\n });\n } else {\n // Use a `span` element with the `contentEditable` attribute set `on`\n target.currentText = target.iniText ?\n target.iniText\n : fillString(target.iniChar, target.numIniChars);\n\n target.$span = $span.text(target.currentText).attr({\n contenteditable: 'true',\n id: idLabel,\n autocomplete: 'off',\n spellcheck: 'false'\n }).bind('focus input blur', event => {\n event.textTarget = target;\n this.processEvent(event);\n }).bind('keydown keyup', event => {\n // Catch `enter` key in Firefox\n if (event.keyCode === 13) {\n event.preventDefault();\n if (event.type === 'keydown') {\n // Simulate a `blur` event\n event.textTarget = target;\n event.type = 'blur';\n this.processEvent(event);\n }\n }\n });\n }\n return $span;\n }\n\n /**\n * Evaluates all the targets in this panel. This method is usually called from the `Check` button.\n * @override\n * @returns {boolean} - `true` when all targets are OK, `false` otherwise.\n */\n evaluatePanel() {\n let targetsOk = 0;\n const numTargets = this.targets.length;\n this.targets.forEach(target => {\n const\n result = this.act.ev.evalText(target.readCurrentText(), target.answers),\n ok = this.act.ev.isOk(result);\n target.targetStatus = ok ? 'SOLVED' : 'WITH_ERROR';\n if (ok)\n targetsOk++;\n this.markTarget(target, result);\n this.ps.reportNewAction(this.act, 'WRITE', target.currentText, target.getAnswers(), ok, targetsOk);\n });\n if (targetsOk === numTargets) {\n this.finishActivity(true);\n return true;\n } else\n this.playEvent('finishedError');\n return false;\n }\n\n /**\n * Checks if the specified TextTarget has a valid answer in its `currentText` field\n * @param {module:activities/text/TextActivityDocument.TextTarget} target - The target to check\n * @param {boolean} onlyCheck - When `true`, the cursor will no be re-positioned\n * @param {number} [jumpDirection] - `1` to go forward, `-1` to go back.\n * @returns {boolean} - `true` when the target contains a valid answer\n */\n checkTarget(target, onlyCheck, jumpDirection) {\n const\n result = this.act.ev.evalText(target.currentText, target.answers),\n ok = this.act.ev.isOk(result);\n\n target.targetStatus = ok ? 'SOLVED' : 'WITH_ERROR';\n if (onlyCheck)\n return ok;\n\n this.markTarget(target, result);\n const targetsOk = this.countSolvedTargets(false, false);\n if (target.currentText.length > 0)\n this.ps.reportNewAction(this.act, 'WRITE', target.currentText, target.getAnswers(), ok, targetsOk);\n if (ok && targetsOk === this.targets.length) {\n this.finishActivity(true);\n return ok;\n } else if (target.currentText.length > 0)\n this.playEvent(ok ? 'actionOk' : 'actionError');\n\n if (jumpDirection && jumpDirection !== 0) {\n let p = target.num + jumpDirection;\n if (p >= this.targets.length)\n p = 0;\n else if (p < 0)\n p = this.targets.length - 1;\n\n const destTarget = this.targets[p];\n if (destTarget.$span) {\n destTarget.$span.focus();\n setSelectionRange(destTarget.$span.get(-1), 0, 0);\n } else if (destTarget.$comboList)\n destTarget.$comboList.focus();\n }\n return ok;\n }\n\n /**\n * Counts the number of targets with `SOLVED` status\n * @param {boolean} checkNow - When `true`, all targets will be evaluated. Otherwise, only the\n * current value of `targetStatus` will be checked.\n * @param {boolean} [mark] - When `true`, errors in the target answer will be marked.\n * @returns {number} - The number of targets currently solved.\n */\n countSolvedTargets(checkNow, mark) {\n return this.targets.reduce((n, target) => {\n if (checkNow) {\n target.readCurrentText();\n this.checkTarget(target, !mark);\n }\n return target.targetStatus === 'SOLVED' ? ++n : n;\n }, 0);\n }\n\n /**\n * Visually marks the target as 'solved OK' or 'with errors'.\n * @param {module:activities/text/TextActivityDocument.TextTarget} target - The text target to be marked.\n * @param {number[]} attributes - - Array of flags indicating the status (OK or error) for each\n * character in `target.currentText`.\n */\n markTarget(target, attributes) {\n if (target.$comboList || this.act.ev.isOk(attributes))\n target.checkColors();\n else if (target.$span) {\n // Identify text fragments\n const\n txt = target.currentText,\n fragments = [];\n let\n currentStatus = -1,\n currentFragment = -1,\n i = 0;\n for (; i < attributes.length && i < txt.length; i++) {\n if (attributes[i] !== currentStatus) {\n fragments[++currentFragment] = '';\n currentStatus = attributes[i];\n }\n fragments[currentFragment] += txt.charAt(i);\n }\n if (i < txt.length)\n fragments[currentFragment] += txt.substring(i);\n // Empty and re-fill $span\n target.$span.empty();\n currentStatus = attributes[0];\n fragments.forEach(fragment => {\n $('<span/>')\n .text(fragment)\n .css(target.doc.style[currentStatus === 0 ? 'target' : 'targetError'].css)\n .appendTo(target.$span);\n currentStatus ^= 1;\n });\n }\n // Target has been marked, so clear the 'modified' flag\n target.flagModified = false;\n }\n\n /**\n * Called by {@link module:JClicPlayer.JClicPlayer JClicPlayer} when this activity panel is fully visible, just after the\n * initialization process.\n * @override\n */\n activityReady() {\n super.activityReady();\n\n // Prevent strange behavior with GoogleChrome when `white-space` CSS attribute is set to\n // `pre-wrap` (needed for tabulated texts)\n $('.JClicTextTarget').css('white-space', 'normal');\n if (this.targets.length > 0 && this.targets[0].$span)\n this.targets[0].$span.focus();\n }\n\n /**\n * Ordinary ending of the activity, usually called form `processEvent`\n * @override\n * @param {boolean} result - `true` if the activity was successfully completed, `false` otherwise\n */\n finishActivity(result) {\n this.targets.forEach(target => {\n if (target.$span)\n target.$span.removeAttr('contenteditable').blur();\n else if (target.$comboList)\n target.$comboList.attr('disabled', 'true').blur();\n });\n return super.finishActivity(result);\n }\n\n /**\n * Main handler used to process mouse, touch, keyboard and edit events.\n * @override\n * @param {external:Event} event - The HTML event to be processed\n * @returns {boolean} - When this event handler returns `false`, jQuery will stop its\n * propagation through the DOM tree. See: {@link http://api.jquery.com/on}\n */\n processEvent(event) {\n if (!super.processEvent(event))\n return false;\n\n const target = event.textTarget;\n let $span = null, pos = 0;\n switch (event.type) {\n case 'focus':\n if (target) {\n if (target.$span && target.$span.children().length > 0) {\n // Clear inner spans used to mark errors\n $span = target.$span;\n pos = Math.min(\n target.currentText.length,\n getCaretCharacterOffsetWithin($span.get(-1)));\n $span.empty();\n $span.text(target.currentText);\n setSelectionRange($span.get(-1), pos, pos);\n target.flagModified = true;\n } else if (target.$comboList)\n target.$comboList.css(target.doc.style['target'].css);\n\n if (target.$popup && (target.infoMode === 'always' || target.infoMode === 'onError' && target.targetStatus === 'WITH_ERROR'))\n this.showPopup(target.$popup, target.popupMaxTime, target.popupDelay);\n else\n this.showPopup(null);\n }\n break;\n\n case 'blur':\n if (target.flagModified && !this.$checkButton)\n this.checkTarget(target, false, 1);\n break;\n\n case 'input':\n if (target && target.$span) {\n $span = target.$span;\n let txt = $span.html();\n // Check for `enter` key\n if (/(<br>|\\n|\\r)/.test(txt)) {\n txt = txt.replace(/(<br>|\\n|\\r)/g, '');\n $span.html(txt);\n target.currentText = $span.text();\n return this.$checkButton ? false : this.checkTarget(target, false, 1);\n }\n // Check if text has changed\n // From here, use 'text' instead of 'html' to avoid HTML entities\n txt = $span.text();\n if (txt !== target.currentText) {\n // Span text has changed!\n target.flagModified = true;\n const added = txt.length - target.currentText.length;\n if (added > 0) {\n if (txt.indexOf(target.iniChar) >= 0) {\n // Remove filling chars\n pos = getCaretCharacterOffsetWithin($span.get(-1));\n for (let i = 0; i < added; i++) {\n const p = txt.indexOf(target.iniChar);\n if (p < 0)\n break;\n txt = txt.substring(0, p) + txt.substring(p + 1);\n if (p < pos)\n pos--;\n }\n $span.text(txt);\n setSelectionRange($span.get(-1), pos, pos);\n }\n\n // Check if current text exceeds max length\n if (txt.length > target.maxLenResp) {\n pos = getCaretCharacterOffsetWithin($span.get(-1));\n txt = txt.substring(0, target.maxLenResp);\n pos = Math.min(pos, txt.length);\n $span.text(txt);\n setSelectionRange($span.get(-1), pos, pos);\n }\n } else if (txt === '') {\n txt = target.iniChar;\n $span.text(txt);\n setSelectionRange($span.get(-1), 0, 0);\n }\n target.currentText = txt;\n }\n }\n break;\n\n case 'change':\n if (target && target.$comboList) {\n target.currentText = target.$comboList.val();\n target.flagModified = true;\n return this.$checkButton ? false : this.checkTarget(target, false, 1);\n }\n break;\n\n default:\n break;\n }\n return true;\n }\n}\n\nObject.assign(FillInBlanksPanel.prototype, {\n /**\n * Flag indicating if the activity is open or locked\n * @name module:activities/text/FillInBlanks.FillInBlanksPanel#locked\n * @type {boolean} */\n locked: true,\n});\n\n/**\n * Panel class associated to this type of activity: {@link module:activities/text/FillInBlanks.FillInBlanksPanel FillInBlanksPanel}\n * @type {class} */\nFillInBlanks.Panel = FillInBlanksPanel;\n\n// Register activity class\nexport default Activity.registerClass('@text.FillInBlanks', FillInBlanks);\n"],"names":[],"sourceRoot":""}
|