File: app/randomizers/select.js
/**
* @module exp-player
* @submodule randomizers
*/
/**
* Randomizer to allow selection of one (or arbitrary sequence) of defined frames.
* This is intended to be used either within a {{#crossLink "Random-parameter-set"}}{{/crossLink}} randomizer with
* different `parameterSets` picking out different values for `whichFrames`) or indirectly
* via the {{#crossLink "Exp-frame-select"}}{{/crossLink}} frame (which allows setting `whichFrames` using a custom
* `generateProperties` function). Note that you cannot add a `generateProperties` function
* directly to a randomizer!
*
* To use, define a frame with "kind": "choice" and "sampler": "select",
* as shown below, in addition to the parameters described under 'properties'.
*
```json
"frames": {
"select-randomizer-test": {
"sampler": "select",
"kind": "choice",
"whichFrames": 0,
"commonFrameProperties": {
"kind": "exp-lookit-text"
},
"frameOptions": [
{
"blocks": [
{
"emph": true,
"text": "Let's think about hippos!",
"title": "FRAME 1"
},
{
"text": "Some more about hippos..."
}
]
},
{
"blocks": [
{
"emph": false,
"text": "Let's think about dolphins!",
"title": "FRAME 2"
}
]
}
]
}
}
*
* ```
* @class Select
*/
var randomizer = function(frameId, frameConfig, pastSessions, resolveFrame) {
// Data provided to randomizer (properties of frameConfig):
/**
* List of frames that can be created by this randomizer. Each frame is an
* object with any necessary frame-specific properties specified. The
* 'kind' of frame can be specified either here (per frame) or in
* commonFrameProperties. If a property is defined for a given frame both
* in this frame list and in commonFrameProperties, the value in the frame
* list will take precedence.
*
* (E.g., you could include 'kind': 'normal-frame' in
* commmonFrameProperties, but for a single frame in frameOptions, include
* 'kind': 'special-frame'.)
*
* @property {Object[]} frameOptions
*/
/**
* Object describing common parameters to use in EVERY frame created
* by this randomizer. Parameter names and values are as described in
* the documentation for the frameType used.
*
* @property {Object} commonFrameProperties
*/
/**
* Index or indices (0-indexed) within frameOptions to actually use. This can be either a number
* (e.g., 0 or 1 to use the first or second option respectively) or an array providing
* an ordered list of indices to use (e.g., [0, 1] or [1, 0] to use the first then
* second or second then first options, respectively). All indices must be integers
* in [0, frameOptions.length).
*
* If not provided or -1, the entire frameOptions list is used in order. (If empty
* list is provided, however, that is respected and no frames are inserted by this
* randomizer.)
*
* @property {Number} whichFrames
*/
var thisFrame = {};
var frames = [];
// If a single frame index is provided, convert to a single-element list
if ((typeof frameConfig.whichFrames) === 'number' && frameConfig.whichFrames != -1) {
frameConfig.whichFrames = [frameConfig.whichFrames];
} else if (!frameConfig.hasOwnProperty('whichFrames') || frameConfig.whichFrames == -1 || !frameConfig.whichFrames) {
frameConfig.whichFrames = [...frameConfig.frameOptions.keys()];
}
for (var iFrame = 0; iFrame < frameConfig.whichFrames.length; iFrame++) {
if (frameConfig.whichFrames[iFrame] < 0 || frameConfig.whichFrames[iFrame] >= frameConfig.frameOptions.length) {
throw `Frame index in whichFrames out of range in select randomizer. All frame indices must be between 0 and frameOptions.length - 1.`;
}
// Assign parameters common to all frames made by this randomizer
thisFrame = {};
Object.assign(thisFrame, frameConfig.commonFrameProperties);
// Assign parameters specific to this frame (allow to override
// common parameters assigned above)
Object.assign(thisFrame, frameConfig.frameOptions[frameConfig.whichFrames[iFrame]]);
thisFrame = resolveFrame(frameId + '-' + iFrame, thisFrame)[0];
frames.push(...thisFrame);
}
/**
* Parameters captured and sent to the server
*
* @attribute conditions
* @param {Object[]} whichFrames the index/indices of the frame(s) used
*/
return [frames, {'whichFrames': frameConfig.whichFrames}];
};
export default randomizer;