API

Definitions

Media

Media are the objects that we display. We currently support five types of media:

If you insert a string instead of a media object the player treats it as if it was Plain text. The folowing two media definitions have the same outcome:'Wiki', {word:'Wiki'}

Stimuli

Stimuli are responsible for how we present the media.

{
    handle:'myStim',
    size: {height:25,width:25},
    location: {left:25,top:75},
    css:{color:'red','font-size':'2em'},
    media: {word: 'Your very cool stimulus'},
    data: {myData: 'some info', myOtherData: 'some other info'}
    nolog: false
}

handle: Each trial may have multiple stimuli, and they are refered to by handle. This is how refer to this specific stimulus inside the player (i.e. if we want to hide or show it). If more than one stimulus (per trial) has the same handle, all actions targeted at that handle will affect all stimuli. You can set a stimulus handle either by setting the handle property, or by setting handle into the data object. Alternatively, if a stimulus is inherited from a set, the handle is defined by default as the set that the stimulus was inherited from.

size: The size of the stimulus in percentage of the player canvas. By default, size is set to {height:'auto',width:'auto'}.

location: The location to display the stimulus, in percentage of the player canvas. Where left:20 means that the left border of the stimulus should be 20% from the left of the canvas. You may define any of left/right/top/bottom attributes.

Instead of specifying percentages you may use the keyword center in order to center the stimulus, or the keyword auto in order to override any previous settings. By default, location is set to {left:'center', right:'center',top:'center', bottom:'center'}.

css: Accepts any jquery css object. (see the api for details)

media: Defines the media associated with this stimulus.

touchMedia: An alternative media object to display in case we are on a touch device (by default, the regular media is used).

data: In addition to the basic attributes of the stimulus you may add any attribute you like as meta deta that will be available from within the player

nolog: If this attribute is set to true, this stimulus (and its associated media) will not be logged. By default nolog is set to false.

Trial

Trials are responsible for organizing stimuli and interactions with the user.

{
    data:{my: 'arbitrary',data:'object'},
    layout: [
        stimulus1,
        stimulus2
    ],
    input: [
        {handle:'left',on:'leftTouch'},
        {handle:'right',on:'rightTouch'}
    ],
    stimuli: [
        stimulus3
    ],
    interactions: [
        {
            conditions: [{type:'begin'}],
            actions: [{type:'hideStim',handle:'myStimHandle'}]
        },
        {
            conditions: [{type:'inputEqualsStim',property:'orientation'}],
            actions: [
                {type:'showStim',handle:'myStim'},
                {type:'setInput',input:{handle:'time',on:'timeout',duration:300}}
            ]
        },
        {
            conditions: [
                {type:'inputEqualsStim',property:'orientation',negate:true},
                {type:'inputEquals',value:'time',negate:true}
            ],
            actions: [{type:'endTrial'}]
        },
        {
            conditions: [{type:'inputEquals',value:'time'}],
            actions: [{type:'hideStim',handle:'myStim'}]
        }
    ]
}

layout / stimuli

The layout and stimuli are arrays that list the stimuli associated with this trial. Stimuli in layout will be statically displayed throughout the trial. stimuli within stimuli are not displayed automatically and may be dynamically interacted with during the trial (see interactions).

Input

The input attribute lists the input objects that the player reacts to. Each input object must include both a handle and an on property.

handle: the way we refer to this input element inside the player (e.g., 'rightClick') on: what triggers this input element. for now we have several types of input:

keypressed: Takes a key property that may either be a key code, a one letter string, or an array of keys.

keyup: Takes a key property that may either be a key code, a one letter string, or an array of keys.

click: Takes either a stimulus handle (stimHandle) or an html element (element). The input is activated when the user clicks the stimulus or the html element. In case an element is defined it is presented as soon as the input is activated.

mouseup: Takes a stimulus handle (stimHandle). Triggers each time the mouse key is released over the space of the target object.

mousedown: Takes a stimulus handle (stimHandle). Triggers each time the mouse key is pressed over the space of the target object.

mouseenter: Takes a stimulus handle (stimHandle). Triggers each time the mouse enters the space of the target object. (note that this behaviour is meaningless in touch devices)

mouseleave: Takes a stimulus handle (stimHandle). Triggers each time the mouse leaves the space of the target object. (note that this behaviour is meaningless in touch devices)

timeout: Takes a duration property and fires after the duration passes

In addition, we have several shortcuts for commonly used inputs:

leftTouch, rightTouch, topTouch and bottomTouch support the property css that will allow you to change the style of the touch area, for example:

{handle:'bottom', on: 'bottomTouch', css: {background:'blue', width: '50%'}}

Protip: In addition to the preset input types you can create custom input:

    {
        handle: 'myInput',
        on: function(callback){
            // do your mojo here and then
            // where e is the raw event, and 'eventType' is the name of this event
            callback(e, 'eventType');
        },
        off: function(){
            // remove your listener (if you need to keep state you can encapsulate the whole input object in a module)
        }
    }

The input objects support an additional meta property: touch. If touch is undefined then this input will always be used. If it is set to true then the input will be used only on touch devices. If it is set to false then the input will be used only on non touch devices.

Interactions

Interactions are composed of conditions and actions. Every time an event is fired (any input including timeout or the begining of a trial) all the conditions are evaluated. Notably the begin event at the begining of each trial only evaluates interactions that have a {type:'begin'} condition.

The interactions array is composed of interaction objects, each holding an array of conditions and an array of actions. For each interaction object, if all the conditions are true, then all the actions are carried out.

{
    conditions: [
        condition1,
        condition2
    ],
    actions: [
        action1,
        action2
    ]
}

Interactions: conditions

Each condition object has a type property that defines what type of evaluation to perform.

In addition, it has a negate property (false by default) that determines whether to activate the condition when the evaluation is true or when it is false.

It is possible to create complex conditions, the following condition, for instance, is activated in case there is an input that is not equal to trial.data.customAttribute, and the input handle is not "time".

[
    {type:'inputEqualsTrial',property:'customAttribute',negate:true},
    {type:'inputEquals',value:'time',negate:true}
]

begin: Automatically activated at the beginning of the trial, and is never fired again.

inputEquals: Check if the input handle equals to a static value, value may be either a string or an array strings.

inputEqualsTrial: Check if the input handle equals to the property property of trial.data

inputEqualsStim: Check if the input handle equals to the property property of any one of the stimulus.data in this trial. The optional property handle narrows the search down to stimuli fitting the handle

trialEquals: Check if the property property of the trial.data object equals to value.

inputEqualsGlobal Check if the input handle equals to the property property of the global object.

globalEquals: Check if the property property of the global object equals to value.

globalEqualsTrial: Check if the global property globalProp equals to the trial.data property trialProp.

globalEqualsStim: Check if the global property globalProp equals to the stimProp property of any one of the stimulus.data in this trial. The optional property handle narrows the search down to stimuli fitting the handle

inputEqualsCurrent Check if the input handle equals to the property property of the current object.

currentEquals: Check if the property property of the current object equals to value.

currentEqualsTrial: Check if the current property currentProp equals to the trial.data property trialProp.

currentEqualsStim: Check if the current property currentProp equals to the stimProp property of any one of the stimulus.data in this trial. The optional property handle narrows the search down to stimuli fitting the handle

function: This options is deprecated. use custom instead.

custom: It is also possible to create a custom condition:

{type:'custom', value:function(condtion, inputData, trial){
    // do your mojo here and return true or false
}}

Interactions: actions

If all the conditions in a row of interactions are true, its actions will be executed.

showStim: Display a stimulus, takes a stimulus handle. Use 'All' for all stimuli.

hideStim: Hide a stimulus, takes a stimulus handle. Use 'All' for all stimuli.

setStimAttr: Set a stimulus.data attribute, takes a stimulus handle and a setter object or function. Any attributes in the setter object will be coppied to the stimulus.data object.

setTrialAttr: Set a trial.data attribute, takes a setter object or function. Any attributes in the setter object will be coppied to the trial.data object.

setGlobalAttr: Set a global object property, takes a setter object or function. Any attributes in the setter object will be coppied into the global object.

trigger: Activate the input handle. If duration is set, the activation happens after the duration. By default the input handle is triggered immediately.

setInput: Set input listener (useful for adding timeouts), takes an input object.

removeInput: Remove input listener, takes an input handle or an array of input handles. The special keyword All removes all listeners. Warning you must add listeners after using removeInput:All, or else the player will get stuck. This command removes triggers as well as regular input listeners.

resetTimer: Resets trial timer. The latency of any events from here on (including the current one) will be calculated back to the reset instead of the begining of the trial.

endTrial: End this trial (note that any actions that come after this is called may not work properly).

canvas: Change canvas style using any of the following properties (see settings): background, canvasBackground, borderColor, borderWidth.

log: Log this action. Pushes this action into the logging stack so that it is later sent to the server (you can set how the player logs an action using the logger settings)

custom Run a custom function. This action is intended to for use by experienced users that want to tinker with the inner workings of the player - use at your own risk! The fn property takes a custom function. The function takes two arguments: options is the action object itself, the second is the event data object.

goto: Responsible for the next trial we go to. This action will be executed only after the trial ends, you will probably want to follow it with an endTrial action.

The destination property defines what type of goto this is (default is "next").

The properties property is an object to compare to the trial data. Note that the properties will only compare to properties present in the raw sequence before inheritance!

Changing Settings

Player wide settings are set within the "settings" property of the task JSON.

settings = {
    logger: {
        url: 'your/target/url',
        logger: function(){
            // do your mojo here :)
        }
    },
    canvas: {
        maxWidth: 800,
        proportions : 1
    }
}

Logger

logger: {
    url: 'your/target/url',
    pulse: 3,
    fullpath: false,
    logger: function(){
        // do your mojo here :)
    }
}

The logger section is responsible for logging options.

url: Is the url to which we send the logged data (ask your IT team what it should be). You should set this if you want to log your data...

pulse: After how many rows should we send data to the server. In case the number of rows is reached during a trial, the player waits until the end of the trial and sends all the log rows it gathered at once. Regardless of pulse, the player sends all remaining log rows at the end of the task. This means that it is possible to get pulses holding more or less than "pulse" rows. If pulse is not set (or is set to 0) the player will send all data at the end of the task.

fullpath: When using the media path to log media elements (for images and templates), should we use the full path or just the filename (false by default)

meta: An object that is used to extend each logged row. This is useful in case you want to add some global data to the posts (such as server generated user id, or task name).

logger: Accepts a function to replace the existing logging function. (don't touch this if you don't realy know what you're doing). The logger function is called each time a log action is triggered (see interactions: actions log). It is responsible for adding a logging row to be sent to the server.

function(trialData, inputData, actionData,logStack){
    // trialData: the data object from this trial
    // inputData: the input object that triggered this action
    // actionData: the action object that was triggered (it should look like {type:'log', your:'custom property'})
    // logStack: an array with all previously logged rows

    // the context for this function ("this") is the original trial object

    // the function should return an object to be pushed into the trial stack, and later be sent to the server
}

This is what the default logger looks like:

function(trialData, inputData, actionData,logStack){
    var stimList = this._stimulus_collection.get_stimlist();
    var mediaList = this._stimulus_collection.get_medialist();

    return {
        log_serial : logStack.length,
        trial_id: this._id,
        name: this.name(),
        responseHandle: inputData.handle,
        latency: Math.floor(inputData.latency),
        stimuli: stimList,
        media: mediaList,
        data: trialData
    };
};

Canvas

The canvas section is responsible for the overall look of the player. It controls the shape and appearance of the canvas.

canvas: {
    maxWidth: 800,
    proportions : 0.8
}

width: If width is set, then the canvas size is set to a constant width (set the hight using the proportions property).

maxWidth: The maximum width (in pixels) that the canvas may reach. By default it is set to 500px (note that if width is set, then this property is ignored and the canvas size stays static).

proportions: Responsible for the shape of the canvas. You can set it either as a number or an object. By default it is set to 0.8.

textSize: Controls the default font size in the canvas. It takes a single number that represents font size in percentage of the canvas height (similar to the CSS3 vh unit). By default it is set to 3. Any fontSize within your script that uses a relative unit (percent/em) will be relative to this size. Any fontSize that uses an absolute unit (px/pt) will ignore it.

background: Controls the background color of the whole screen.

canvasBackground: Controls the background color of the player canvas.

borderWidth: Controls the width of the player canvas borders (in pixels).

borderColor: Controls the color of the player canvas borders.

css: Allows you to add any custom css to the canvas (using the jquery css API).

Base_url

The base_url section is responsible for loading images and templates. It allows the user to pick a base url from which to load all images and templates. It accepts either an object setting the base url for images and templates or a string that will be used for both images and templates:

// object notation
base_url: {
    image: "images",
    template: "templates/"
}

// string notation
base_url: "media/"

Redirect

The redirect setting decides where to redirect the player at the end of the task. By default, the player simply refreshes the current page. This option is not used if the endTask hook is set.

redirect: '//my.domain.edu'

Hooks

Hooks are functions that are to be run at predefined points throughout the player.

hooks: {
    endTask: function(){}
}

endTask: Called at the end of the task instead of the default redirect.

onEnd

Called at the end of the task instead of the default redirect. This function is a more standart complient version of hooks.endTask.

Meta data

Meta data is data that should be returned with every request to the server. Any key value pair in the meta data is added to every post the player makes to the server. In order to create a post with three keys: json, session_id and task_id - you would write something like this:

metaData: {
    session_id: 9872356,
    task_id: '43BTW78'
}

(the json field is the field that holds the player data it is created automaticaly)

API

The API is a javascript object that is used to activate the miTime. The basic format for accessing the API is as follows:

define(['app/API'], function(APIconstructor) {
    var API = new APIconstructor();

    API.addScript(script);

    return API.script;
});

The API object exposes several helper function to help you organize your script.

addScript: Allows pushing a whole script to the player:

getScript: Returns the whole player script:

addGlobal, addCurrent Allows extending the global or current objects respectively:

getGlobal, getCurrent: Returns the global or current object respectively:

addSettings: API.addSettings allows you to add settings to your script.

You may add a whole settings section:

API.addSettings({
    canvas: {},
    logger: {}
});

Alternatively you may add a specific setting:

API.addSettings('canvas',{
    maxWidth: 800,
    proportions : 0.8
});

addTrialSets, addStimulusSets and addMediaSets: There are three add set functions, one for each of the set types: addTrialSets, addStimulusSets and addMediaSets. Each of them allows adding sets to your script. You may add a complete sets object:

API.addTrialSets({
    Default: [defaultTrial],
    introduction: [intro1, intro2, intro3]
});

Or you may add a single set:

API.addTrialSets("introduction",[intro1, intro2]); // adds intro1 and intro2 to the introduction set

Or part of a set

API.addTrialSets("introduction",intro3); // adds intro3 to the introduction set

addSequence Allows adding sequence objects to your script.

Here is a single set:

API.addSequence([trial1,trial2]);

And part of a set:

API.addSequence(trial2);

getScript: Returns the script that you've built so far. Useful mainly for debugging:

getLogs: Returns the logs for this task. Useful for giving user feedback or creating staircase tasks

Logging

The player sends all the data it has gathered to the url defined in the settings logger. The data is sent as an ajax POST where the only field is "json" (unless you added something using metadata). The field includes a json array including all logs created. each log is an object including the following fields:

Field Description
log_serial the serial number for this log row (starts at 1)
trial_id a unique identifier for this trial
name the name of this trial - an alias if one is set, otherwise the set the trial inherited
block the block attribute of trial.data (it is up to the user to set this attribute, usually in the trial definitions)
responseHandle the handle for the input that triggered this log
score the score attribute of trial.data (it is up to the user to set this attribute, usually using setTrialAttr)
latency the latency of the response from the beginning of the trial
stimuli a json including the stimuli used in this trial (we use an alias if one is set, otherwise the stimulus set, otherwise the stimulus handle otherwise stim#)
media a json including the media used in this trial (we use an alias if one is set, otherwise the media set, otherwise media#)
data a json including the data property of this trial

You can control the names that the different elements get by adding an alias property to the element itslef or to its data. If the alias isn't set, then the player attempts to choose a meaningful name on its own (using the inherited set, or whatever is appropriate).


License: Apache 2. © Project Implicit. · Current version [version]