Merge pull request #317 from jodeleeuw/no-jquery

Remove all jQuery, implement testing framework
This commit is contained in:
Josh de Leeuw 2017-01-04 15:42:47 -05:00 committed by GitHub
commit a89b993efe
133 changed files with 1427 additions and 761 deletions

2
.gitignore vendored
View File

@ -1,3 +1,3 @@
node_modules/
.DS_Store .DS_Store
Thumbs.db Thumbs.db

3
.travis.yml Normal file
View File

@ -0,0 +1,3 @@
language: node_js
node_js:
- "6.6"

View File

@ -32,7 +32,7 @@ Wondering if jsPsych can be used for research that depends on accurate response
* [de Leeuw, J. R., & Motz, B. A. (2016). Psychophysics in a Web browser? Comparing response times collected with JavaScript and Psychophysics Toolbox in a visual search task. *Behavior Research Methods*, *48*(1), 1-12.](http://link.springer.com/article/10.3758%2Fs13428-015-0567-2) * [de Leeuw, J. R., & Motz, B. A. (2016). Psychophysics in a Web browser? Comparing response times collected with JavaScript and Psychophysics Toolbox in a visual search task. *Behavior Research Methods*, *48*(1), 1-12.](http://link.springer.com/article/10.3758%2Fs13428-015-0567-2)
* [Hilbig, B. E. (in press). Reaction time effects in lab- versus web-based research: Experimental evidence. *Behavior Research Methods*.](http://dx.doi.org/10.3758/s13428-015-0678-9) * [Hilbig, B. E. (in press). Reaction time effects in lab- versus web-based research: Experimental evidence. *Behavior Research Methods*.](http://dx.doi.org/10.3758/s13428-015-0678-9)
* [Pinet, S., Zielinski, C., Mathôt, S. et al. (in press). Measuring sequences of keystrokes with jsPsych: Reliability of response times and interkeystroke intervals. *Behavior Research Methods*.](http://link.springer.com/article/10.3758/s13428-016-0776-3) * [Pinet, S., Zielinski, C., Mathôt, S. et al. (in press). Measuring sequences of keystrokes with jsPsych: Reliability of response times and interkeystroke intervals. *Behavior Research Methods*.](http://link.springer.com/article/10.3758/s13428-016-0776-3)
* [Reimers, S., & Stewart, N. (2014). Presentation and response time accuracy in Adobe Flash and HTML5/JavaScript Web experiments. *Behavior Research Methods*, *47*(2), 309-327.](http://link.springer.com/article/10.3758%2Fs13428-014-0471-1) * [Reimers, S., & Stewart, N. (2015). Presentation and response time accuracy in Adobe Flash and HTML5/JavaScript Web experiments. *Behavior Research Methods*, *47*(2), 309-327.](http://link.springer.com/article/10.3758%2Fs13428-014-0471-1)
Credits Credits

View File

@ -12,11 +12,25 @@
flex-direction: column; flex-direction: column;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
height: 100%; /*height: 100%;
width: 100%; width: 100%;*/
overflow-y: scroll; overflow-y: scroll;
} }
.jspsych-content-wrapper {
display: flex;
justify-content: center;
align-items: center;
flex: 1 1 100%;
width: 100%;
}
.jspsych-content {
max-width: 95%; /* this is mainly an IE 10-11 fix */
text-align: center;
/*margin: auto;*/
}
.jspsych-top { .jspsych-top {
align-items: flex-start; align-items: flex-start;
} }
@ -25,19 +39,7 @@
align-items: center; align-items: center;
} }
.jspsych-content {
max-width: 95%; /* this is mainly an IE 10-11 fix */
text-align:center;
margin: auto;
}
.jspsych-content-wrapper {
display: flex;
justify-content: center;
align-items: center;
flex: 1 1 auto;
width: 100%;
}
/* fonts and type */ /* fonts and type */

View File

@ -166,7 +166,6 @@ var after_block = {
} }
jsPsych.init({ jsPsych.init({
display_element: $('#jspsych-target'),
timeline: [block, after_block], timeline: [block, after_block],
on_finish: function() { on_finish: function() {
jsPsych.data.displayData(); jsPsych.data.displayData();
@ -264,7 +263,7 @@ None.
### Return value ### Return value
Returns the jQuery-object that contains the DOM element used for displaying the experiment. Returns the HTML DOM element used for displaying the experiment.
### Description ### Description
@ -276,7 +275,7 @@ Get the DOM element that displays the experiment.
var el = jsPsych.getDisplayElement(); var el = jsPsych.getDisplayElement();
// hide the jsPsych display // hide the jsPsych display
el.hide(); el.style.visibility = 'hidden';
``` ```
--- ---
## jsPsych.init ## jsPsych.init
@ -296,7 +295,7 @@ The settings object can contain several parameters. The only *required* paramete
Parameter | Type | Description Parameter | Type | Description
--------- | ---- | ----------- --------- | ---- | -----------
timeline | array | An array containing the objects that describe the experiment timeline. See [Creating an Experiment: The Timeline](../features/timeline.md). timeline | array | An array containing the objects that describe the experiment timeline. See [Creating an Experiment: The Timeline](../features/timeline.md).
display_element | jQuery object | A jQuery-selected DOM element, e.g., `$('#target')` selects the element with the `id='target'` attribute. If left blank, then jsPsych will use the `<body>` element to display content (creating it if necessary). You can override this parameter at the trial level as well by specifying a display_element property on any timeline. display_element | string | The ID of an HTML element to display the experiment in. If left blank, then jsPsych will use the `<body>` element to display content (creating it if necessary). You can override this parameter at the trial level as well by specifying a display_element property on any timeline.
on_finish | function | Function to execute when the experiment ends. on_finish | function | Function to execute when the experiment ends.
on_trial_start | function | Function to execute when a new trial begins. on_trial_start | function | Function to execute when a new trial begins.
on_trial_finish | function | Function to execute when a trial ends. on_trial_finish | function | Function to execute when a trial ends.

View File

@ -283,7 +283,6 @@ var after_if_trial = {
} }
jsPsych.init({ jsPsych.init({
display_element: $('#jspsych-target'),
timeline: [pre_if_trial, if_node, after_if_trial], timeline: [pre_if_trial, if_node, after_if_trial],
on_finish: function(){jsPsych.data.displayData(); } on_finish: function(){jsPsych.data.displayData(); }
}); });

View File

@ -1,7 +1,7 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<script src="js/jquery.min.js"></script>
<script src="../jspsych.js"></script> <script src="../jspsych.js"></script>
<script src="../plugins/jspsych-text.js"></script> <script src="../plugins/jspsych-text.js"></script>
<script src="../plugins/jspsych-single-stim.js"></script> <script src="../plugins/jspsych-single-stim.js"></script>

View File

@ -2,7 +2,7 @@
<html> <html>
<head> <head>
<script src="js/jquery.min.js"></script>
<script src="../jspsych.js"></script> <script src="../jspsych.js"></script>
<script src="../plugins/jspsych-single-stim.js"></script> <script src="../plugins/jspsych-single-stim.js"></script>
<link rel="stylesheet" href="../css/jspsych.css"></link> <link rel="stylesheet" href="../css/jspsych.css"></link>

View File

@ -1,7 +1,7 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<script src="js/jquery.min.js"></script>
<script src="../jspsych.js"></script> <script src="../jspsych.js"></script>
<script src="../plugins/jspsych-text.js"></script> <script src="../plugins/jspsych-text.js"></script>
<link rel="stylesheet" href="../css/jspsych.css"></link> <link rel="stylesheet" href="../css/jspsych.css"></link>
@ -55,7 +55,8 @@
jsPsych.init({ jsPsych.init({
timeline: [loop_node, pre_if_trial, if_node, after_if_trial], timeline: [loop_node, pre_if_trial, if_node, after_if_trial],
on_finish: function(){jsPsych.data.displayData(); } on_finish: function(){jsPsych.data.displayData(); },
default_iti: 200
}); });
</script> </script>

View File

@ -1,7 +1,7 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<script src="js/jquery.min.js"></script>
<script src="../jspsych.js"></script> <script src="../jspsych.js"></script>
<script src="../plugins/jspsych-text.js"></script> <script src="../plugins/jspsych-text.js"></script>
<link rel="stylesheet" href="../css/jspsych.css"></link> <link rel="stylesheet" href="../css/jspsych.css"></link>

View File

@ -2,7 +2,7 @@
<html> <html>
<head> <head>
<script src="js/jquery.min.js"></script>
<script src="../jspsych.js"></script> <script src="../jspsych.js"></script>
<script src="../plugins/jspsych-single-stim.js"></script> <script src="../plugins/jspsych-single-stim.js"></script>
<link rel="stylesheet" href="../css/jspsych.css"></link> <link rel="stylesheet" href="../css/jspsych.css"></link>

View File

@ -2,7 +2,7 @@
<html> <html>
<head> <head>
<script src="js/jquery.min.js"></script>
<script src="../jspsych.js"></script> <script src="../jspsych.js"></script>
<script src="../plugins/jspsych-single-stim.js"></script> <script src="../plugins/jspsych-single-stim.js"></script>
<link rel="stylesheet" href="../css/jspsych.css"></link> <link rel="stylesheet" href="../css/jspsych.css"></link>

View File

@ -2,7 +2,7 @@
<html> <html>
<head> <head>
<script src="js/jquery.min.js"></script>
<script src="../jspsych.js"></script> <script src="../jspsych.js"></script>
<script src="../plugins/jspsych-single-stim.js"></script> <script src="../plugins/jspsych-single-stim.js"></script>
<link rel="stylesheet" href="../css/jspsych.css"></link> <link rel="stylesheet" href="../css/jspsych.css"></link>

View File

@ -2,7 +2,7 @@
<html> <html>
<head> <head>
<script src="js/jquery.min.js"></script>
<script src="../jspsych.js"></script> <script src="../jspsych.js"></script>
<script src="../plugins/jspsych-text.js"></script> <script src="../plugins/jspsych-text.js"></script>
<link rel="stylesheet" href="../css/jspsych.css"></link> <link rel="stylesheet" href="../css/jspsych.css"></link>

View File

@ -2,7 +2,7 @@
<html> <html>
<head> <head>
<script src="js/jquery.min.js"></script>
<script src="../jspsych.js"></script> <script src="../jspsych.js"></script>
<script src="../plugins/jspsych-single-stim.js"></script> <script src="../plugins/jspsych-single-stim.js"></script>
<link rel="stylesheet" href="../css/jspsych.css"></link> <link rel="stylesheet" href="../css/jspsych.css"></link>

View File

@ -1,7 +1,7 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<script src="js/jquery.min.js"></script>
<script src="../jspsych.js"></script> <script src="../jspsych.js"></script>
<link rel="stylesheet" href="../css/jspsych.css"></link> <link rel="stylesheet" href="../css/jspsych.css"></link>
<style> <style>

View File

@ -2,7 +2,7 @@
<html> <html>
<head> <head>
<script src="js/jquery.min.js"></script>
<script src="../jspsych.js"></script> <script src="../jspsych.js"></script>
<script src="../plugins/jspsych-single-stim.js"></script> <script src="../plugins/jspsych-single-stim.js"></script>
<link rel="stylesheet" href="../css/jspsych.css"></link> <link rel="stylesheet" href="../css/jspsych.css"></link>

View File

@ -2,7 +2,7 @@
<html> <html>
<head> <head>
<title>Flanker Task</title> <title>Flanker Task</title>
<script src="js/jquery.min.js"></script>
<script src="../jspsych.js"></script> <script src="../jspsych.js"></script>
<script src="../plugins/jspsych-text.js"></script> <script src="../plugins/jspsych-text.js"></script>
<script src="../plugins/jspsych-single-stim.js"></script> <script src="../plugins/jspsych-single-stim.js"></script>

View File

@ -2,7 +2,6 @@
<html> <html>
<head> <head>
<title>My experiment</title> <title>My experiment</title>
<script src="js/jquery.min.js"></script>
<script src="../jspsych.js"></script> <script src="../jspsych.js"></script>
<script src="../plugins/jspsych-text.js"></script> <script src="../plugins/jspsych-text.js"></script>
<script src="../plugins/jspsych-single-stim.js"></script> <script src="../plugins/jspsych-single-stim.js"></script>

View File

@ -2,7 +2,7 @@
<html> <html>
<head> <head>
<script src="js/jquery.min.js"></script>
<script src="../jspsych.js"></script> <script src="../jspsych.js"></script>
<script src="../plugins/jspsych-single-stim.js"></script> <script src="../plugins/jspsych-single-stim.js"></script>
<link rel="stylesheet" href="../css/jspsych.css"></link> <link rel="stylesheet" href="../css/jspsych.css"></link>

View File

@ -2,7 +2,7 @@
<html> <html>
<head> <head>
<script src="js/jquery.min.js"></script>
<script src="../jspsych.js"></script> <script src="../jspsych.js"></script>
<script src="../plugins/jspsych-single-stim.js"></script> <script src="../plugins/jspsych-single-stim.js"></script>
<link rel="stylesheet" href="../css/jspsych.css"></link> <link rel="stylesheet" href="../css/jspsych.css"></link>

View File

@ -1,7 +1,7 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<script src="js/jquery.min.js"></script>
<script src="../jspsych.js"></script> <script src="../jspsych.js"></script>
<link rel="stylesheet" href="../css/jspsych.css"></link> <link rel="stylesheet" href="../css/jspsych.css"></link>
<style> <style>

View File

@ -1,7 +1,7 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<script src="js/jquery.min.js"></script>
<script src="../jspsych.js"></script> <script src="../jspsych.js"></script>
<link rel="stylesheet" href="../css/jspsych.css"></link> <link rel="stylesheet" href="../css/jspsych.css"></link>
<style> <style>
@ -23,7 +23,6 @@
// should get error message in console about no plugin loaded // should get error message in console about no plugin loaded
jsPsych.init({ jsPsych.init({
display_element: $('#jspsych-target'),
timeline: [block_1] timeline: [block_1]
}); });

View File

@ -2,7 +2,7 @@
<html> <html>
<head> <head>
<script src="js/jquery.min.js"></script>
<script src="../jspsych.js"></script> <script src="../jspsych.js"></script>
<script src="../plugins/jspsych-single-stim.js"></script> <script src="../plugins/jspsych-single-stim.js"></script>
<link rel="stylesheet" href="../css/jspsych.css"></link> <link rel="stylesheet" href="../css/jspsych.css"></link>

View File

@ -2,15 +2,12 @@
<html> <html>
<head> <head>
<script src="js/jquery.min.js"></script>
<script src="../jspsych.js"></script> <script src="../jspsych.js"></script>
<script src="../plugins/jspsych-text.js"></script> <script src="../plugins/jspsych-text.js"></script>
<link rel="stylesheet" href="../css/jspsych.css"></link> <link rel="stylesheet" href="../css/jspsych.css"></link>
</head> </head>
<body>
<div id="jspsych-target"></div>
</body>
<script> <script>
var block_1 = { var block_1 = {
type: 'text', type: 'text',
@ -19,7 +16,6 @@
} }
jsPsych.init({ jsPsych.init({
display_element: $('#jspsych-target'),
timeline: [block_1], timeline: [block_1],
fullscreen: true, fullscreen: true,
on_finish: function() { on_finish: function() {

View File

@ -2,7 +2,7 @@
<html> <html>
<head> <head>
<script src="js/jquery.min.js"></script>
<script src="../jspsych.js"></script> <script src="../jspsych.js"></script>
<script src="../plugins/jspsych-single-stim.js"></script> <script src="../plugins/jspsych-single-stim.js"></script>
<link rel="stylesheet" href="../css/jspsych.css"></link> <link rel="stylesheet" href="../css/jspsych.css"></link>

View File

@ -1,7 +1,7 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<script src="js/jquery.min.js"></script>
<script src="../jspsych.js"></script> <script src="../jspsych.js"></script>
<script src="../plugins/jspsych-text.js"></script> <script src="../plugins/jspsych-text.js"></script>
<link rel="stylesheet" href="../css/jspsych.css"></link> <link rel="stylesheet" href="../css/jspsych.css"></link>

View File

@ -2,7 +2,7 @@
<html> <html>
<head> <head>
<script src="js/jquery.min.js"></script>
<script src="../jspsych.js"></script> <script src="../jspsych.js"></script>
<script src="../plugins/jspsych-text.js"></script> <script src="../plugins/jspsych-text.js"></script>
<script src="../plugins/jspsych-single-stim.js"></script> <script src="../plugins/jspsych-single-stim.js"></script>

View File

Before

Width:  |  Height:  |  Size: 3.7 KiB

After

Width:  |  Height:  |  Size: 3.7 KiB

View File

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 4.6 KiB

View File

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 3.9 KiB

View File

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

Before

Width:  |  Height:  |  Size: 3.7 KiB

After

Width:  |  Height:  |  Size: 3.7 KiB

View File

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

Before

Width:  |  Height:  |  Size: 5.1 KiB

After

Width:  |  Height:  |  Size: 5.1 KiB

View File

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

View File

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

View File

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 23 KiB

View File

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

View File

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

Before

Width:  |  Height:  |  Size: 5.2 KiB

After

Width:  |  Height:  |  Size: 5.2 KiB

View File

Before

Width:  |  Height:  |  Size: 234 KiB

After

Width:  |  Height:  |  Size: 234 KiB

View File

Before

Width:  |  Height:  |  Size: 231 KiB

After

Width:  |  Height:  |  Size: 231 KiB

View File

Before

Width:  |  Height:  |  Size: 339 KiB

After

Width:  |  Height:  |  Size: 339 KiB

View File

Before

Width:  |  Height:  |  Size: 177 KiB

After

Width:  |  Height:  |  Size: 177 KiB

View File

@ -2,7 +2,7 @@
<html> <html>
<head> <head>
<script src="js/jquery.min.js"></script>
<script src="../jspsych.js"></script> <script src="../jspsych.js"></script>
<script src="../plugins/jspsych-animation.js"></script> <script src="../plugins/jspsych-animation.js"></script>
<link rel="stylesheet" href="../css/jspsych.css"></link> <link rel="stylesheet" href="../css/jspsych.css"></link>

View File

@ -1,7 +1,7 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<script src="js/jquery.min.js"></script>
<script src="../jspsych.js"></script> <script src="../jspsych.js"></script>
<script src="../plugins/jspsych-button-response.js"></script> <script src="../plugins/jspsych-button-response.js"></script>
<link rel="stylesheet" href="../css/jspsych.css"></link> <link rel="stylesheet" href="../css/jspsych.css"></link>

View File

@ -1,7 +1,7 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<script src="js/jquery.min.js"></script>
<script src="../jspsych.js"></script> <script src="../jspsych.js"></script>
<script src="../plugins/jspsych-call-function.js"></script> <script src="../plugins/jspsych-call-function.js"></script>
<link rel="stylesheet" href="../css/jspsych.css"></link> <link rel="stylesheet" href="../css/jspsych.css"></link>

View File

@ -2,7 +2,7 @@
<html> <html>
<head> <head>
<script src="js/jquery.min.js"></script>
<script src="../jspsych.js"></script> <script src="../jspsych.js"></script>
<script src="../plugins/jspsych-categorize-animation.js"></script> <script src="../plugins/jspsych-categorize-animation.js"></script>
<link rel="stylesheet" href="../css/jspsych.css"></link> <link rel="stylesheet" href="../css/jspsych.css"></link>

View File

@ -2,7 +2,7 @@
<html> <html>
<head> <head>
<script src="js/jquery.min.js"></script>
<script src="../jspsych.js"></script> <script src="../jspsych.js"></script>
<script src="../plugins/jspsych-categorize.js"></script> <script src="../plugins/jspsych-categorize.js"></script>
<link rel="stylesheet" href="../css/jspsych.css"></link> <link rel="stylesheet" href="../css/jspsych.css"></link>

View File

@ -1,11 +1,8 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<script src="js/jquery.min.js"></script>
<script src="js/jquery-ui.min.js"></script>
<script src="../jspsych.js"></script> <script src="../jspsych.js"></script>
<script src="../plugins/jspsych-free-sort.js"></script> <script src="../plugins/jspsych-free-sort.js"></script>
<link rel="stylesheet" href="css/jquery-ui.css"></link>
<link rel="stylesheet" href="../css/jspsych.css"></link> <link rel="stylesheet" href="../css/jspsych.css"></link>
</head> </head>
<script> <script>

View File

@ -2,7 +2,7 @@
<html> <html>
<head> <head>
<script src="js/jquery.min.js"></script>
<script src="../jspsych.js"></script> <script src="../jspsych.js"></script>
<script src="../plugins/jspsych-html.js"></script> <script src="../plugins/jspsych-html.js"></script>
<link rel="stylesheet" href="../css/jspsych.css"></link> <link rel="stylesheet" href="../css/jspsych.css"></link>
@ -16,7 +16,7 @@
*/ */
var check_consent = function(elem) { var check_consent = function(elem) {
if ($('#consent_checkbox').is(':checked')) { if (document.getElementById('consent_checkbox').checked) {
return true; return true;
} else { } else {
alert("If you wish to participate, you must check the box next to the statement 'I agree to participate in this study.'"); alert("If you wish to participate, you must check the box next to the statement 'I agree to participate in this study.'");

View File

@ -1,7 +1,7 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<script src="js/jquery.min.js"></script>
<script src="../jspsych.js"></script> <script src="../jspsych.js"></script>
<script src="../plugins/jspsych-instructions.js"></script> <script src="../plugins/jspsych-instructions.js"></script>
<link rel="stylesheet" href="../css/jspsych.css"></link> <link rel="stylesheet" href="../css/jspsych.css"></link>

View File

@ -2,7 +2,7 @@
<html> <html>
<head> <head>
<script src="js/jquery.min.js"></script>
<script src="../jspsych.js"></script> <script src="../jspsych.js"></script>
<script src="../plugins/jspsych-multi-stim-multi-response.js"></script> <script src="../plugins/jspsych-multi-stim-multi-response.js"></script>
<link rel="stylesheet" href="../css/jspsych.css"></link> <link rel="stylesheet" href="../css/jspsych.css"></link>

View File

@ -1,7 +1,7 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<script src="js/jquery.min.js"></script>
<script src="js/snap.svg-min.js"></script> <script src="js/snap.svg-min.js"></script>
<script src="../jspsych.js"></script> <script src="../jspsych.js"></script>
<script src="../plugins/jspsych-palmer.js"></script> <script src="../plugins/jspsych-palmer.js"></script>

View File

@ -1,7 +1,7 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<script src="js/jquery.min.js"></script>
<script src="../jspsych.js"></script> <script src="../jspsych.js"></script>
<script src="../plugins/jspsych-reconstruction.js"></script> <script src="../plugins/jspsych-reconstruction.js"></script>
<link rel="stylesheet" href="../css/jspsych.css"></link> <link rel="stylesheet" href="../css/jspsych.css"></link>

View File

@ -2,7 +2,7 @@
<html> <html>
<head> <head>
<script src="js/jquery.min.js"></script>
<script src="../jspsych.js"></script> <script src="../jspsych.js"></script>
<script src="../plugins/jspsych-same-different.js"></script> <script src="../plugins/jspsych-same-different.js"></script>
<link rel="stylesheet" href="../css/jspsych.css"></link> <link rel="stylesheet" href="../css/jspsych.css"></link>

View File

@ -2,7 +2,7 @@
<html> <html>
<head> <head>
<script src="js/jquery.min.js"></script>
<script src="../jspsych.js"></script> <script src="../jspsych.js"></script>
<script src="../plugins/jspsych-serial-reaction-time.js"></script> <script src="../plugins/jspsych-serial-reaction-time.js"></script>
<script src="../plugins/jspsych-text.js"></script> <script src="../plugins/jspsych-text.js"></script>

View File

@ -2,7 +2,7 @@
<html> <html>
<head> <head>
<script src="js/jquery.min.js"></script>
<script src="js/jquery-ui.min.js"></script> <script src="js/jquery-ui.min.js"></script>
<script src="../jspsych.js"></script> <script src="../jspsych.js"></script>
<script src="../plugins/jspsych-similarity.js"></script> <script src="../plugins/jspsych-similarity.js"></script>

View File

@ -1,7 +1,7 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<script src="js/jquery.min.js"></script>
<script src="../jspsych.js"></script> <script src="../jspsych.js"></script>
<script src="../plugins/jspsych-single-audio.js"></script> <script src="../plugins/jspsych-single-audio.js"></script>
<link rel="stylesheet" href="../css/jspsych.css"></link> <link rel="stylesheet" href="../css/jspsych.css"></link>

View File

@ -2,7 +2,7 @@
<html> <html>
<head> <head>
<script src="js/jquery.min.js"></script>
<script src="../jspsych.js"></script> <script src="../jspsych.js"></script>
<script src="../plugins/jspsych-single-stim.js"></script> <script src="../plugins/jspsych-single-stim.js"></script>
<link rel="stylesheet" href="../css/jspsych.css"></link> <link rel="stylesheet" href="../css/jspsych.css"></link>

View File

@ -1,7 +1,7 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<script src="js/jquery.min.js"></script>
<script src="../jspsych.js"></script> <script src="../jspsych.js"></script>
<script src="../plugins/jspsych-survey-likert.js"></script> <script src="../plugins/jspsych-survey-likert.js"></script>
<link rel="stylesheet" href="../css/jspsych.css"></link> <link rel="stylesheet" href="../css/jspsych.css"></link>

View File

@ -1,7 +1,7 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<script src="js/jquery.min.js"></script>
<script src="../jspsych.js"></script> <script src="../jspsych.js"></script>
<script src="../plugins/jspsych-survey-multi-choice.js"></script> <script src="../plugins/jspsych-survey-multi-choice.js"></script>
<link rel="stylesheet" href="../css/jspsych.css"></link> <link rel="stylesheet" href="../css/jspsych.css"></link>

View File

@ -1,7 +1,7 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<script src="js/jquery.min.js"></script>
<script src="../jspsych.js"></script> <script src="../jspsych.js"></script>
<script src="../plugins/jspsych-survey-text.js"></script> <script src="../plugins/jspsych-survey-text.js"></script>
<link rel="stylesheet" href="../css/jspsych.css"></link> <link rel="stylesheet" href="../css/jspsych.css"></link>

View File

@ -1,7 +1,7 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<script src="js/jquery.min.js"></script>
<script src="../jspsych.js"></script> <script src="../jspsych.js"></script>
<script src="../plugins/jspsych-text.js"></script> <script src="../plugins/jspsych-text.js"></script>
<link rel="stylesheet" href="../css/jspsych.css"></link> <link rel="stylesheet" href="../css/jspsych.css"></link>

View File

@ -1,7 +1,7 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<script src="js/jquery.min.js"></script>
<script src="../jspsych.js"></script> <script src="../jspsych.js"></script>
<script src="../plugins/jspsych-video.js"></script> <script src="../plugins/jspsych-video.js"></script>
<link rel="stylesheet" href="../css/jspsych.css"></link> <link rel="stylesheet" href="../css/jspsych.css"></link>

View File

@ -2,7 +2,7 @@
<html> <html>
<head> <head>
<script src="js/jquery.min.js"></script>
<script src="js/snap.svg-min.js"></script> <script src="js/snap.svg-min.js"></script>
<script src="../jspsych.js"></script> <script src="../jspsych.js"></script>
<script src="../plugins/jspsych-text.js"></script> <script src="../plugins/jspsych-text.js"></script>

View File

@ -2,7 +2,7 @@
<html> <html>
<head> <head>
<script src="js/jquery.min.js"></script>
<script src="js/snap.svg-min.js"></script> <script src="js/snap.svg-min.js"></script>
<script src="../jspsych.js"></script> <script src="../jspsych.js"></script>
<script src="../plugins/jspsych-vsl-animate-occlusion.js"></script> <script src="../plugins/jspsych-vsl-animate-occlusion.js"></script>

View File

@ -1,7 +1,7 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<script src="js/jquery.min.js"></script>
<script src="js/snap.svg-min.js"></script> <script src="js/snap.svg-min.js"></script>
<script src="../jspsych.js"></script> <script src="../jspsych.js"></script>
<script src="../plugins/jspsych-vsl-grid-scene.js"></script> <script src="../plugins/jspsych-vsl-grid-scene.js"></script>

View File

@ -2,7 +2,7 @@
<html> <html>
<head> <head>
<script src="js/jquery.min.js"></script>
<script src="../jspsych.js"></script> <script src="../jspsych.js"></script>
<script src="../plugins/jspsych-xab.js"></script> <script src="../plugins/jspsych-xab.js"></script>
<link rel="stylesheet" href="../css/jspsych.css"></link> <link rel="stylesheet" href="../css/jspsych.css"></link>

View File

@ -2,7 +2,7 @@
<html> <html>
<head> <head>
<script src="js/jquery.min.js"></script>
<script src="../jspsych.js"></script> <script src="../jspsych.js"></script>
<script src="../plugins/jspsych-text.js"></script> <script src="../plugins/jspsych-text.js"></script>
<script src="../plugins/jspsych-single-stim.js"></script> <script src="../plugins/jspsych-single-stim.js"></script>

View File

@ -1,7 +1,7 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<script src="js/jquery.min.js"></script>
<script src="../jspsych.js"></script> <script src="../jspsych.js"></script>
<script src="../plugins/jspsych-text.js"></script> <script src="../plugins/jspsych-text.js"></script>
<link rel="stylesheet" href="../css/jspsych.css"></link> <link rel="stylesheet" href="../css/jspsych.css"></link>

View File

@ -1,8 +1,6 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<script src="js/jquery.min.js"></script>
<script src="../jspsych.js"></script> <script src="../jspsych.js"></script>
<script src="../plugins/jspsych-single-stim.js"></script> <script src="../plugins/jspsych-single-stim.js"></script>
<script src="../plugins/jspsych-text.js"></script> <script src="../plugins/jspsych-text.js"></script>
@ -12,7 +10,7 @@
width: 300px; width: 300px;
} }
</style> </style>
</head>
<script> <script>
var trial_1 = { var trial_1 = {
type: 'single-stim', type: 'single-stim',
@ -52,12 +50,12 @@
jsPsych.init({ jsPsych.init({
timeline: [trial_1, trial_2, trial_3, block_set, end_screen], timeline: [trial_1, trial_2, trial_3], //block_set, end_screen],
show_progress_bar: true, show_progress_bar: true,
on_finish: function() { on_finish: function() {
jsPsych.data.displayData(); jsPsych.data.displayData();
} }
}); });
</script> </script>
</head>
</html> </html>

View File

@ -1,7 +1,7 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<script src="js/jquery.min.js"></script>
<script src="../jspsych.js"></script> <script src="../jspsych.js"></script>
<link rel="stylesheet" href="../css/jspsych.css"></link> <link rel="stylesheet" href="../css/jspsych.css"></link>
<style> <style>

View File

@ -1,7 +1,7 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<script src="js/jquery.min.js"></script>
<script src="../jspsych.js"></script> <script src="../jspsych.js"></script>
<script src="../plugins/jspsych-text.js"></script> <script src="../plugins/jspsych-text.js"></script>
<link rel="stylesheet" href="../css/jspsych.css"></link> <link rel="stylesheet" href="../css/jspsych.css"></link>
@ -32,7 +32,6 @@
} }
jsPsych.init({ jsPsych.init({
display_element: $('#jspsych-target'),
timeline: [first,overall], timeline: [first,overall],
default_iti: 0, default_iti: 0,
on_finish: function() { jsPsych.data.displayData(); } on_finish: function() { jsPsych.data.displayData(); }

View File

@ -2,7 +2,7 @@
<html> <html>
<head> <head>
<script src="js/jquery.min.js"></script>
<script src="../jspsych.js"></script> <script src="../jspsych.js"></script>
<script src="../plugins/jspsych-single-stim.js"></script> <script src="../plugins/jspsych-single-stim.js"></script>
<link rel="stylesheet" href="../css/jspsych.css"></link> <link rel="stylesheet" href="../css/jspsych.css"></link>
@ -42,7 +42,6 @@
} }
jsPsych.init({ jsPsych.init({
display_element: $('#jspsych-target'),
timeline: [node], timeline: [node],
on_finish: function() { on_finish: function() {
jsPsych.data.displayData(); jsPsych.data.displayData();

View File

@ -2,7 +2,7 @@
<html> <html>
<head> <head>
<script src="js/jquery.min.js"></script>
<script src="../jspsych.js"></script> <script src="../jspsych.js"></script>
<script src="../plugins/jspsych-single-stim.js"></script> <script src="../plugins/jspsych-single-stim.js"></script>
<script src="../plugins/jspsych-single-audio.js"></script> <script src="../plugins/jspsych-single-audio.js"></script>
@ -47,7 +47,6 @@
jsPsych.pluginAPI.preloadAudioFiles(['sound/sound.mp3','sound/hammer.mp3'], function() { jsPsych.pluginAPI.preloadAudioFiles(['sound/sound.mp3','sound/hammer.mp3'], function() {
jsPsych.init({ jsPsych.init({
display_element: $('#jspsych-target'),
timeline: [node], timeline: [node],
on_finish: function() { on_finish: function() {
jsPsych.data.displayData(); jsPsych.data.displayData();

View File

@ -2,7 +2,7 @@
<html> <html>
<head> <head>
<script src="js/jquery.min.js"></script>
<script src="../jspsych.js"></script> <script src="../jspsych.js"></script>
<script src="../plugins/jspsych-single-stim.js"></script> <script src="../plugins/jspsych-single-stim.js"></script>
<link rel="stylesheet" href="../css/jspsych.css"></link> <link rel="stylesheet" href="../css/jspsych.css"></link>
@ -38,7 +38,6 @@
} }
jsPsych.init({ jsPsych.init({
display_element: $('#jspsych-target'),
timeline: [block_1], timeline: [block_1],
on_finish: function() { on_finish: function() {
jsPsych.data.displayData(); jsPsych.data.displayData();

View File

@ -2,7 +2,7 @@
<html> <html>
<head> <head>
<script src="js/jquery.min.js"></script>
<script src="../jspsych.js"></script> <script src="../jspsych.js"></script>
<script src="../plugins/jspsych-single-stim.js"></script> <script src="../plugins/jspsych-single-stim.js"></script>
<link rel="stylesheet" href="../css/jspsych.css"></link> <link rel="stylesheet" href="../css/jspsych.css"></link>
@ -29,7 +29,7 @@
var trial_3 = { var trial_3 = {
stimulus: '<p>:)</p>', stimulus: '<p>:)</p>',
is_html: true, is_html: true,
display_element: $('#jspsych-trial-target') display_element: 'jspsych-trial-target'
} }
var node = { var node = {
@ -44,7 +44,7 @@
jsPsych.init({ jsPsych.init({
display_element: $('#jspsych-target'), display_element: 'jspsych-target',
timeline: [node], timeline: [node],
on_finish: function() { on_finish: function() {
jsPsych.data.displayData(); jsPsych.data.displayData();

View File

@ -5,7 +5,7 @@
* documentation: docs.jspsych.org * documentation: docs.jspsych.org
* *
**/ **/
var jsPsych = (function() { window.jsPsych = (function() {
var core = {}; var core = {};
@ -49,6 +49,7 @@ var jsPsych = (function() {
paused = false; paused = false;
waiting = false; waiting = false;
loaded = false; loaded = false;
jsPsych.data.reset();
var defaults = { var defaults = {
'display_element': undefined, 'display_element': undefined,
@ -67,42 +68,50 @@ var jsPsych = (function() {
'on_interaction_data_update': function(data){ 'on_interaction_data_update': function(data){
return undefined; return undefined;
}, },
'preload_images': [],
'preload_audio': [],
'exclusions': {}, 'exclusions': {},
'show_progress_bar': false, 'show_progress_bar': false,
'auto_preload': true, 'auto_preload': true,
'max_load_time': 60000, 'max_load_time': 60000,
'fullscreen': false, 'fullscreen': false,
'default_iti': 1000 'default_iti': 0
}; };
// override default options if user specifies an option // override default options if user specifies an option
opts = $.extend({}, defaults, options); opts = Object.assign({}, defaults, options);
// set DOM element where jsPsych will render content // set DOM element where jsPsych will render content
// if undefined, then jsPsych will use the <body> tag and the entire page // if undefined, then jsPsych will use the <body> tag and the entire page
if(typeof opts.display_element == 'undefined'){ if(typeof opts.display_element == 'undefined'){
// check if there is a body element on the page // check if there is a body element on the page
var body = $('body'); var body = document.querySelector('body');
if (body.length === 0) { if (body === null) {
$(document.documentElement).append($('<body>')); document.documentElement.appendChild(document.createElement('body'));
} }
// using the full page, so we need the HTML document to // using the full page, so we need the HTML element to
// have 100% height, and body to have no margin // have 100% height, and body to be full width and height with
$('html').css('height','100%'); // no margin
$('body').css('margin', '0px'); document.querySelector('html').style.height = '100%';
opts.display_element = $('body'); document.querySelector('body').style.margin = '0px';
document.querySelector('body').style.height = '100%';
document.querySelector('body').style.width = '100%';
opts.display_element = document.querySelector('body');
} else { } else {
// make sure that the display element exists on the page // make sure that the display element exists on the page
if(opts.display_element.length == 0) { var display = document.querySelector('#'+opts.display_element);
if(display === null) {
console.error('The display_element specified in jsPsych.init() does not exist in the DOM.'); console.error('The display_element specified in jsPsych.init() does not exist in the DOM.');
} else {
opts.display_element = display;
} }
} }
opts.display_element.append('<div class="jspsych-content-wrapper"><div id="jspsych-content"></div></div>') opts.display_element.innerHTML = '<div class="jspsych-content-wrapper"><div id="jspsych-content"></div></div>';
DOM_target = $('#jspsych-content'); DOM_target = document.querySelector('#jspsych-content');
// add CSS class to DOM_target // add CSS class to DOM_target
opts.display_element.addClass('jspsych-display-element') opts.display_element.className += ' jspsych-display-element';
DOM_target.addClass('jspsych-content'); DOM_target.className += 'jspsych-content';
// create experiment timeline // create experiment timeline
timeline = new TimelineNode({ timeline = new TimelineNode({
@ -117,6 +126,21 @@ var jsPsych = (function() {
function(){ function(){
// success! user can continue... // success! user can continue...
// start experiment, with or without preloading // start experiment, with or without preloading
if(opts.preload_images.length > 0){
jsPsych.pluginAPI.preloadImages(opts.preload_images, load_audio);
} else {
load_audio();
}
function load_audio(){
if(opts.preload_audio.length > 0){
jsPsych.pluginAPI.preloadAudioFiles(opts.preload_audio, auto_preload);
} else {
auto_preload();
}
}
function auto_preload(){
if(opts.auto_preload){ if(opts.auto_preload){
jsPsych.pluginAPI.autoPreload(timeline, startExperiment); jsPsych.pluginAPI.autoPreload(timeline, startExperiment);
if(opts.max_load_time > 0){ if(opts.max_load_time > 0){
@ -129,6 +153,8 @@ var jsPsych = (function() {
} else { } else {
startExperiment(); startExperiment();
} }
}
}, },
function(){ function(){
// fail. incompatible user. // fail. incompatible user.
@ -173,7 +199,7 @@ var jsPsych = (function() {
jsPsych.data.write(data); jsPsych.data.write(data);
// get back the data with all of the defaults in // get back the data with all of the defaults in
var trial_data = jsPsych.data.getData({trial_index: global_trial_index})[0]; var trial_data = jsPsych.data.getData().filter({trial_index: global_trial_index});
// handle callback at plugin level // handle callback at plugin level
if (typeof current_trial.on_finish === 'function') { if (typeof current_trial.on_finish === 'function') {
@ -285,7 +311,7 @@ var jsPsych = (function() {
if (typeof timeline_parameters == 'undefined') { if (typeof timeline_parameters == 'undefined') {
// returns a clone of the trial_parameters to // returns a clone of the trial_parameters to
// protect functions. // protect functions.
return $.extend(true, {}, trial_parameters); return Object.assign({}, trial_parameters);
} else { } else {
if (progress.current_location >= timeline_parameters.timeline.length) { if (progress.current_location >= timeline_parameters.timeline.length) {
return null; return null;
@ -589,7 +615,7 @@ var jsPsych = (function() {
console.error('Cannot add new trials to a trial-level node.'); console.error('Cannot add new trials to a trial-level node.');
} else { } else {
timeline_parameters.timeline.push( timeline_parameters.timeline.push(
new TimelineNode($.extend(true, {}, node_trial_data, parameters), self, timeline_parameters.timeline.length) new TimelineNode(Object.assign({}, node_trial_data, parameters), self, timeline_parameters.timeline.length)
); );
} }
} }
@ -625,7 +651,7 @@ var jsPsych = (function() {
self.setTimelineVariablesOrder(); self.setTimelineVariablesOrder();
// extract all of the node level data and parameters // extract all of the node level data and parameters
var node_data = $.extend(true, {}, parameters); var node_data = Object.assign({}, parameters);
delete node_data.timeline; delete node_data.timeline;
delete node_data.conditional_function; delete node_data.conditional_function;
delete node_data.loop_function; delete node_data.loop_function;
@ -637,7 +663,7 @@ var jsPsych = (function() {
// create a TimelineNode for each element in the timeline // create a TimelineNode for each element in the timeline
for (var i = 0; i < parameters.timeline.length; i++) { for (var i = 0; i < parameters.timeline.length; i++) {
timeline_parameters.timeline.push(new TimelineNode($.extend(true, {}, node_data, parameters.timeline[i]), self, i)); timeline_parameters.timeline.push(new TimelineNode(Object.assign({}, node_data, parameters.timeline[i]), self, i));
} }
} }
@ -651,7 +677,7 @@ var jsPsych = (function() {
console.error('No plugin loaded for trials of type "' + trial_type + '"'); console.error('No plugin loaded for trials of type "' + trial_type + '"');
} }
// create a deep copy of the parameters for the trial // create a deep copy of the parameters for the trial
trial_parameters = $.extend(true, {}, parameters); trial_parameters = Object.assign({}, parameters);
} }
}(); }();
@ -670,8 +696,8 @@ var jsPsych = (function() {
if (keyboardNotAllowed) { if (keyboardNotAllowed) {
go(); go();
} else { } else {
DOM_target.append('<div style=""><p>The experiment will launch in fullscreen mode when you click the button below.</p><button id="jspsych-fullscreen-btn" class="jspsych-btn">Launch Experiment</button></div>'); DOM_target.innerHTML = '<div style=""><p>The experiment will launch in fullscreen mode when you click the button below.</p><button id="jspsych-fullscreen-btn" class="jspsych-btn">Launch Experiment</button></div>';
$('#jspsych-fullscreen-btn').on('click', function() { var listener = DOM_target.querySelector('#jspsych-fullscreen-btn').addEventListener('click', function() {
var element = document.documentElement; var element = document.documentElement;
if (element.requestFullscreen) { if (element.requestFullscreen) {
element.requestFullscreen(); element.requestFullscreen();
@ -682,8 +708,8 @@ var jsPsych = (function() {
} else if (element.msRequestFullscreen) { } else if (element.msRequestFullscreen) {
element.msRequestFullscreen(); element.msRequestFullscreen();
} }
$('#jspsych-fullscreen-btn').off('click'); DOM_target.querySelector('#jspsych-fullscreen-btn').removeEventListener('click', listener);
DOM_target.html(''); DOM_target.innerHTML = '';
setTimeout(go, 1000); setTimeout(go, 1000);
}); });
} }
@ -710,7 +736,7 @@ var jsPsych = (function() {
opts.on_finish(jsPsych.data.getData()); opts.on_finish(jsPsych.data.getData());
if(typeof timeline.end_message !== 'undefined'){ if(typeof timeline.end_message !== 'undefined'){
DOM_target.html(timeline.end_message); DOM_target.innerHTML = timeline.end_message;
} }
if (document.exitFullscreen) { if (document.exitFullscreen) {
@ -771,7 +797,7 @@ var jsPsych = (function() {
} }
function loadFail(){ function loadFail(){
DOM_target.html('<p>The experiment failed to load.</p>'); DOM_target.innerHTML = '<p>The experiment failed to load.</p>';
} }
function checkExclusions(exclusions, success, fail){ function checkExclusions(exclusions, success, fail){
@ -794,10 +820,10 @@ var jsPsych = (function() {
'you will not be able to complete this experiment.</p>'+ 'you will not be able to complete this experiment.</p>'+
'<p>The minimum width is '+mw+'px. Your current width is '+w+'px.</p>'+ '<p>The minimum width is '+mw+'px. Your current width is '+w+'px.</p>'+
'<p>The minimum height is '+mh+'px. Your current height is '+h+'px.</p>'; '<p>The minimum height is '+mh+'px. Your current height is '+h+'px.</p>';
core.getDisplayElement().html(msg); core.getDisplayElement().innerHTML = msg;
} else { } else {
clearInterval(interval); clearInterval(interval);
core.getDisplayElement().empty(); core.getDisplayElement().innerHTML = '';
checkExclusions(exclusions, success, fail); checkExclusions(exclusions, success, fail);
} }
}, 100); }, 100);
@ -814,7 +840,7 @@ var jsPsych = (function() {
var msg = '<p>Your browser does not support the WebAudio API, which means that you will not '+ var msg = '<p>Your browser does not support the WebAudio API, which means that you will not '+
'be able to complete the experiment.</p><p>Browsers that support the WebAudio API include '+ 'be able to complete the experiment.</p><p>Browsers that support the WebAudio API include '+
'Chrome, Firefox, Safari, and Edge.</p>'; 'Chrome, Firefox, Safari, and Edge.</p>';
core.getDisplayElement().html(msg); core.getDisplayElement().innerHTML = msg;
fail(); fail();
return; return;
} }
@ -825,19 +851,18 @@ var jsPsych = (function() {
} }
function drawProgressBar() { function drawProgressBar() {
$('.jspsych-display-element').prepend( document.querySelector('.jspsych-display-element').insertAdjacentHTML('afterbegin',
'<div id="jspsych-progressbar-container">'+ '<div id="jspsych-progressbar-container">'+
'<span>Completion Progress</span>'+ '<span>Completion Progress</span>'+
'<div id="jspsych-progressbar-outer">'+ '<div id="jspsych-progressbar-outer">'+
'<div id="jspsych-progressbar-inner"></div>'+ '<div id="jspsych-progressbar-inner"></div>'+
'</div></div>' '</div></div>');
);
} }
function updateProgressBar() { function updateProgressBar() {
var progress = jsPsych.progress(); var progress = jsPsych.progress();
$('#jspsych-progressbar-inner').css('width', progress.percent_complete + "%"); document.querySelector('#jspsych-progressbar-inner').style.width = progress.percent_complete + "%";
} }
return core; return core;
@ -863,43 +888,107 @@ jsPsych.data = (function() {
var module = {}; var module = {};
// data storage object // data storage object
var allData = []; var allData = DataCollection();
// browser interaction event data // browser interaction event data
var interactionData = []; var interactionData = DataCollection();
// data properties for all trials // data properties for all trials
var dataProperties = {}; var dataProperties = {};
// ignored data fields
var ignoredProperties = [];
// cache the query_string // cache the query_string
var query_string; var query_string;
module.getData = function(filters) { // DataCollection
var data_clone = $.extend(true, [], allData); // deep clone function DataCollection(data){
if(typeof filters == 'undefined'){ var data_collection = {};
return data_clone;
var trials = typeof data === 'undefined' ? [] : data;
data_collection.push = function(new_data){
trials.push(new_data);
return data_collection;
} }
data_collection.join = function(other_data_collection){
trials = trials.concat(other_data_collection.values());
return data_collection;
}
data_collection.top = function(){
if(trials.length <= 1){
return data_collection;
} else {
return DataCollection([trials[trials.length-1]]);
}
}
data_collection.first = function(n){
if(typeof n=='undefined'){ n = 1 }
var out = [];
for(var i=0; i<n; i++){
out.push(trials[i]);
}
return DataCollection(out);
}
data_collection.last = function(n){
if(typeof n=='undefined'){ n = 1 }
var out = [];
for(var i=trials.length-n; i<trials.length; i++){
out.push(trials[i]);
}
return DataCollection(out);
}
data_collection.values = function(){
return trials;
}
data_collection.count = function(){
return trials.length;
}
data_collection.readOnly = function(){
return DataCollection(deepExtend([], trials));
}
data_collection.addToAll = function(properties){
for (var i = 0; i < trials.length; i++) {
for (var key in properties) {
trials[i][key] = properties[key];
}
}
return data_collection;
}
data_collection.addToLast = function(properties){
if(trials.length != 0){
for (var key in properties) {
trials[trials.length-1][key] = properties[key];
}
}
return data_collection;
}
data_collection.filter = function(filters){
// [{p1: v1, p2:v2}, {p1:v2}] // [{p1: v1, p2:v2}, {p1:v2}]
// {p1: v1} // {p1: v1}
if(!Array.isArray(filters)){ if(!Array.isArray(filters)){
var f = $.extend(true, [], [filters]); var f = deepExtend([], [filters]);
} else { } else {
var f = $.extend(true, [], filters); var f = deepExtend([], filters);
} }
var filtered_data = []; var filtered_data = [];
for(var x=0; x < data_clone.length; x++){ for(var x=0; x < trials.length; x++){
var keep = false; var keep = false;
for(var i=0; i<f.length; i++){ for(var i=0; i<f.length; i++){
var match = true; var match = true;
var keys = Object.keys(f[i]); var keys = Object.keys(f[i]);
for(var k=0; k<keys.length; k++){ for(var k=0; k<keys.length; k++){
if(typeof data_clone[x][keys[k]] !== 'undefined' && data_clone[x][keys[k]] == f[i][keys[k]]){ if(typeof trials[x][keys[k]] !== 'undefined' && trials[x][keys[k]] == f[i][keys[k]]){
// matches on this key! // matches on this key!
} else { } else {
match = false; match = false;
@ -908,16 +997,177 @@ jsPsych.data = (function() {
if(match) { keep = true; break; } // can break because each filter is OR. if(match) { keep = true; break; } // can break because each filter is OR.
} }
if(keep){ if(keep){
filtered_data.push(data_clone[x]); filtered_data.push(trials[x]);
} }
} }
return filtered_data; var out = DataCollection(filtered_data);
return out;
}
data_collection.filterCustom = function(fn){
var included = [];
for(var i=0; i<trials.length; i++){
if(fn(trials[i])){
included.push(trials[i]);
}
}
return DataCollection(included);
}
data_collection.select = function(column){
var values = [];
for(var i=0; i<trials.length; i++){
if(typeof trials[i][column] !== 'undefined'){
values.push(trials[i][column]);
}
}
var out = DataColumn();
out.values = values;
return out;
}
data_collection.ignore = function(columns){
if(!Array.isArray(columns)){
columns = [columns];
}
var o = deepExtend([], trials);
for (var i = 0; i < o.length; i++) {
for (var j in columns) {
delete o[i][columns[j]];
}
}
return DataCollection(o);
}
data_collection.csv = function(){
return JSON2CSV(trials);
}
data_collection.json = function(){
return JSON.stringify(trials);
}
data_collection.localSave = function(format, filename){
var data_string;
if (format == 'JSON' || format == 'json') {
data_string = data_collection.json();
} else if (format == 'CSV' || format == 'csv') {
data_string = data_collection.csv();
} else {
throw new Error('Invalid format specified for localSave. Must be "JSON" or "CSV".');
}
saveTextToFile(data_string, filename);
}
return data_collection;
}
// DataColumn class
function DataColumn(){
var data_column = {};
data_column.values = [];
data_column.sum = function(){
var s = 0;
for(var i=0; i<data_column.values.length; i++){
s += data_column.values[i];
}
return s;
}
data_column.mean = function(){
return data_column.sum() / data_column.count();
}
data_column.median = function(){
if (data_column.values.length == 0) {return undefined};
var numbers = data_column.values.slice(0).sort(function(a,b){ return a - b; });
var middle = Math.floor(numbers.length / 2);
var isEven = numbers.length % 2 === 0;
return isEven ? (numbers[middle] + numbers[middle - 1]) / 2 : numbers[middle];
}
data_column.min = function(){
return Math.min.apply(null, data_column.values);
}
data_column.max = function(){
return Math.max.apply(null, data_column.values);
}
data_column.count = function(){
return data_column.values.length;
}
data_column.variance = function(){
var mean = data_column.mean();
var sum_square_error = 0;
for(var i=0; i<data_column.values.length; i++){
sum_square_error += Math.pow(data_column.values[i] - mean,2);
}
var mse = sum_square_error / data_column.values.length;
return mse;
}
data_column.sd = function(){
var mse = data_column.variance();
var rmse = Math.sqrt(mse);
return rmse;
}
data_column.frequencies = function(){
var unique = {}
for(var i=0; i<data_column.values.length; i++){
var v = data_column.values[i];
if(typeof unique[v] == 'undefined'){
unique[v] = 1;
} else {
unique[v]++;
}
}
return unique;
}
data_column.all = function(eval_fn){
for(var i=0; i<data_column.values.length; i++){
if(!eval_fn(data_column.values[i])){
return false;
}
}
return true;
}
data_column.subset = function(eval_fn){
var out = [];
for(var i=0; i<data_column.values.length; i++){
if(eval_fn(data_column.values[i])){
out.push(data_column.values[i]);
}
}
var o = DataColumn();
o.values = out;
return o;
}
return data_column;
}
module.reset = function(){
allData = DataCollection();
interactionData = DataCollection();
}
module.getData = function() {
return allData;
}; };
module.getInteractionData = function() { module.getInteractionData = function() {
return $.extend(true, [], interactionData); return interactionData;
} }
module.write = function(data_object) { module.write = function(data_object) {
@ -934,11 +1184,7 @@ jsPsych.data = (function() {
'internal_node_id': jsPsych.currentTimelineNodeID() 'internal_node_id': jsPsych.currentTimelineNodeID()
}; };
var ext_data_object = $.extend({}, data_object, trial.data, default_data, dataProperties); var ext_data_object = Object.assign({}, data_object, trial.data, default_data, dataProperties);
for(var i in ignoredProperties){
delete ext_data_object[ignoredProperties[i]];
}
allData.push(ext_data_object); allData.push(ext_data_object);
@ -949,88 +1195,34 @@ jsPsych.data = (function() {
module.addProperties = function(properties) { module.addProperties = function(properties) {
// first, add the properties to all data that's already stored // first, add the properties to all data that's already stored
for (var i = 0; i < allData.length; i++) { allData.addToAll(properties);
for (var key in properties) {
allData[i][key] = properties[key];
}
}
// now add to list so that it gets appended to all future data // now add to list so that it gets appended to all future data
dataProperties = $.extend({}, dataProperties, properties); dataProperties = Object.assign({}, dataProperties, properties);
};
module.ignore = function(properties) {
// first, remove the properties from all data that's already stored
for (var i = 0; i < allData.length; i++) {
for (var j in properties) {
delete allData[i][properties[j]];
}
}
// now add to list so that it gets appended to all future data
ignoredProperties = ignoredProperties.concat(properties);
}; };
module.addDataToLastTrial = function(data) { module.addDataToLastTrial = function(data) {
if (allData.length == 0) { allData.addToLast(data);
throw new Error("Cannot add data to last trial - no data recorded so far");
} }
allData[allData.length - 1] = $.extend({}, allData[allData.length - 1], data);
}
module.getDataAsCSV = function(filters) {
var dataObj = module.getData(filters);
return JSON2CSV(dataObj);
};
module.getDataAsJSON = function(filters) {
var dataObj = module.getData(filters);
return JSON.stringify(dataObj);
};
module.localSave = function(filename, format, filters) {
var data_string;
if (format == 'JSON' || format == 'json') {
data_string = module.getDataAsJSON(filters)
} else if (format == 'CSV' || format == 'csv') {
data_string = module.getDataAsCSV(filters);
} else {
throw new Error('invalid format specified for jsPsych.data.localSave');
}
saveTextToFile(data_string, filename);
};
module.getDataByTimelineNode = function(node_id) { module.getDataByTimelineNode = function(node_id) {
var data = module.getData(); var data = allData.filterCustom(function(x){
return x.internal_node_id.slice(0, node_id.length) === node_id;
});
data = flatten(data); return data;
var trials = [];
for (var i = 0; i < data.length; i++) {
if (data[i].internal_node_id.slice(0, node_id.length) === node_id) {
trials.push(data[i]);
}
}
return trials;
}; };
module.getLastTrialData = function() { module.getLastTrialData = function() {
if (allData.length == 0) { return allData.top();
return {};
}
return $.extend(true, {}, allData[allData.length - 1]);
}; };
module.getLastTimelineData = function() { module.getLastTimelineData = function() {
var lasttrial = module.getLastTrialData(); var lasttrial = module.getLastTrialData();
var node_id = lasttrial.internal_node_id; var node_id = lasttrial.select('internal_node_id').values[0];
if (typeof node_id === 'undefined') { if (typeof node_id === 'undefined') {
return []; return DataCollection();
} else { } else {
var parent_node_id = node_id.substr(0,node_id.lastIndexOf('-')); var parent_node_id = node_id.substr(0,node_id.lastIndexOf('-'));
var lastnodedata = module.getDataByTimelineNode(parent_node_id); var lastnodedata = module.getDataByTimelineNode(parent_node_id);
@ -1048,16 +1240,16 @@ jsPsych.data = (function() {
var data_string; var data_string;
if (format == 'json') { if (format == 'json') {
data_string = JSON.stringify(module.getData(), undefined, 1); data_string = allData.json();
} else { } else {
data_string = module.getDataAsCSV(); data_string = allData.csv();
} }
var display_element = jsPsych.getDisplayElement(); var display_element = jsPsych.getDisplayElement();
display_element.append($('<pre id="jspsych-data-display"></pre>')); display_element.innerHTML = '<pre id="jspsych-data-display"></pre>';
$('#jspsych-data-display').text(data_string); document.getElementById('jspsych-data-display').textContent = data_string;
}; };
module.urlVariables = function() { module.urlVariables = function() {
@ -1114,8 +1306,17 @@ jsPsych.data = (function() {
document.addEventListener('webkitfullscreenchange', fullscreenchange); document.addEventListener('webkitfullscreenchange', fullscreenchange);
} }
// private function to save text file on local drive // public methods for testing purposes. not recommended for use.
module._customInsert = function(data){
allData = DataCollection(data);
}
module._fullreset = function(){
module.reset();
dataProperties = {};
}
// private function to save text file on local drive
function saveTextToFile(textstr, filename) { function saveTextToFile(textstr, filename) {
var blobToSave = new Blob([textstr], { var blobToSave = new Blob([textstr], {
type: 'text/plain' type: 'text/plain'
@ -1129,16 +1330,8 @@ jsPsych.data = (function() {
var display_element = jsPsych.getDisplayElement(); var display_element = jsPsych.getDisplayElement();
display_element.append($('<a>', { display_element.insertAdjacentHTML('beforeend','<a id="jspsych-download-as-text-link" style="display:none;" download="'+filename+'" href="'+blobURL+'">click to download</a>');
id: 'jspsych-download-as-text-link', document.getElementById('jspsych-download-as-text-link').click();
href: blobURL,
css: {
display: 'none'
},
download: filename,
html: 'download file'
}));
$('#jspsych-download-as-text-link')[0].click();
} }
// //
@ -1160,7 +1353,7 @@ jsPsych.data = (function() {
for (var key in array[j]) { for (var key in array[j]) {
var keyString = key + ""; var keyString = key + "";
keyString = '"' + keyString.replace(/"/g, '""') + '",'; keyString = '"' + keyString.replace(/"/g, '""') + '",';
if ($.inArray(key, columns) == -1) { if (!columns.includes(key)) {
columns[i] = key; columns[i] = key;
line += keyString; line += keyString;
i++; i++;
@ -1325,7 +1518,7 @@ jsPsych.randomization = (function() {
if(array[i] == null || typeof array[i] != 'object'){ if(array[i] == null || typeof array[i] != 'object'){
allsamples.push(array[i]); allsamples.push(array[i]);
} else { } else {
allsamples.push($.extend(true, {}, array[i])); allsamples.push(Object.assign({}, array[i]));
} }
} }
@ -1416,7 +1609,7 @@ jsPsych.randomization = (function() {
for (var k = 0; k < toAdd.length; k++) { for (var k = 0; k < toAdd.length; k++) {
var newpiece = {}; var newpiece = {};
newpiece[factorNames[i]] = toAdd[k]; newpiece[factorNames[i]] = toAdd[k];
factor_combinations.push($.extend({}, base, newpiece)); factor_combinations.push(Object.assign({}, base, newpiece));
} }
} }
factor_combinations.splice(0, n); factor_combinations.splice(0, n);
@ -1487,7 +1680,18 @@ jsPsych.pluginAPI = (function() {
var keyboard_listeners = []; var keyboard_listeners = [];
var held_keys = []; var held_keys = {};
// keyboard events
document.addEventListener('keydown', function(e){
for(var i=0; i<keyboard_listeners.length; i++){
keyboard_listeners[i].fn(e);
}
held_keys[e.keyCode] = true;
});
document.addEventListener('keyup', function(e){
held_keys[e.keyCode] = false;
});
module.getKeyboardResponse = function(parameters) { module.getKeyboardResponse = function(parameters) {
//parameters are: callback_function, valid_responses, rt_method, persist, audio_context, audio_context_start_time, allow_held_key? //parameters are: callback_function, valid_responses, rt_method, persist, audio_context, audio_context_start_time, allow_held_key?
@ -1528,13 +1732,13 @@ jsPsych.pluginAPI = (function() {
for (var i = 0; i < parameters.valid_responses.length; i++) { for (var i = 0; i < parameters.valid_responses.length; i++) {
if (typeof parameters.valid_responses[i] == 'string') { if (typeof parameters.valid_responses[i] == 'string') {
if (typeof keylookup[parameters.valid_responses[i]] !== 'undefined') { if (typeof keylookup[parameters.valid_responses[i]] !== 'undefined') {
if (e.which == keylookup[parameters.valid_responses[i]]) { if (e.keyCode == keylookup[parameters.valid_responses[i]]) {
valid_response = true; valid_response = true;
} }
} else { } else {
throw new Error('Invalid key string specified for getKeyboardResponse'); throw new Error('Invalid key string specified for getKeyboardResponse');
} }
} else if (e.which == parameters.valid_responses[i]) { } else if (e.keyCode == parameters.valid_responses[i]) {
valid_response = true; valid_response = true;
} }
} }
@ -1543,47 +1747,28 @@ jsPsych.pluginAPI = (function() {
// check if key was already held down // check if key was already held down
if (((typeof parameters.allow_held_key == 'undefined') || !parameters.allow_held_key) && valid_response) { if (((typeof parameters.allow_held_key == 'undefined') || !parameters.allow_held_key) && valid_response) {
for (i in held_keys) { if (typeof held_keys[e.keyCode] !== 'undefined' && held_keys[e.keyCode] == true) {
if (held_keys[i] == e.which) {
valid_response = false; valid_response = false;
break;
}
} }
} }
if (valid_response) { if (valid_response) {
held_keys.push(e.which);
parameters.callback_function({ parameters.callback_function({
key: e.which, key: e.keyCode,
rt: key_time - start_time rt: key_time - start_time
}); });
if ($.inArray(listener_id, keyboard_listeners) > -1) { if (keyboard_listeners.includes(listener_id)) {
if (!parameters.persist) { if (!parameters.persist) {
// remove keyboard listener // remove keyboard listener
module.cancelKeyboardResponse(listener_id); module.cancelKeyboardResponse(listener_id);
} }
} }
var after_up = function(up) {
if (up.which == e.which) {
$(document).off('keyup', after_up);
// mark key as released
held_keys.splice($.inArray(e.which, held_keys), 1);
} }
}; };
$(document).keyup(after_up);
}
};
$(document).keydown(listener_function);
// create listener id object // create listener id object
listener_id = { listener_id = {
type: 'keydown', type: 'keydown',
@ -1598,19 +1783,13 @@ jsPsych.pluginAPI = (function() {
}; };
module.cancelKeyboardResponse = function(listener) { module.cancelKeyboardResponse = function(listener) {
// remove the listener from the doc
$(document).off(listener.type, listener.fn);
// remove the listener from the list of listeners // remove the listener from the list of listeners
if ($.inArray(listener, keyboard_listeners) > -1) { if (keyboard_listeners.includes(listener)) {
keyboard_listeners.splice($.inArray(listener, keyboard_listeners), 1); keyboard_listeners.splice(keyboard_listeners.indexOf(listener), 1);
} }
}; };
module.cancelAllKeyboardResponses = function() { module.cancelAllKeyboardResponses = function() {
for (var i = 0; i < keyboard_listeners.length; i++) {
$(document).off(keyboard_listeners[i].type, keyboard_listeners[i].fn);
}
keyboard_listeners = []; keyboard_listeners = [];
}; };
@ -1622,6 +1801,15 @@ jsPsych.pluginAPI = (function() {
return code; return code;
} }
module.convertKeyCodeToKeyCharacter = function(code){
for(var i in Object.keys(keylookup)){
if(keylookup[Object.keys(keylookup)[i]] == code){
return Object.keys(keylookup)[i];
}
}
return undefined;
}
var keylookup = { var keylookup = {
'backspace': 8, 'backspace': 8,
'tab': 9, 'tab': 9,
@ -1824,6 +2012,8 @@ jsPsych.pluginAPI = (function() {
var preloads = []; var preloads = [];
var img_cache = {};
module.preloadAudioFiles = function(files, callback_complete, callback_load) { module.preloadAudioFiles = function(files, callback_complete, callback_load) {
files = flatten(files); files = flatten(files);
@ -1837,7 +2027,7 @@ jsPsych.pluginAPI = (function() {
return; return;
} }
function load_audio_file(source){ function load_audio_file_webaudio(source){
var request = new XMLHttpRequest(); var request = new XMLHttpRequest();
request.open('GET', source, true); request.open('GET', source, true);
request.responseType = 'arraybuffer'; request.responseType = 'arraybuffer';
@ -1856,6 +2046,19 @@ jsPsych.pluginAPI = (function() {
request.send(); request.send();
} }
function load_audio_file_html5audio(source){
var audio = new Audio();
audio.addEventListener('canplaythrough', function(){
audio_buffers[source] = audio;
n_loaded++;
loadfn(n_loaded);
if(n_loaded == files.length){
finishfn();
}
});
audio.src = source;
}
for (var i = 0; i < files.length; i++) { for (var i = 0; i < files.length; i++) {
var bufferID = files[i]; var bufferID = files[i];
if (typeof audio_buffers[bufferID] !== 'undefined') { if (typeof audio_buffers[bufferID] !== 'undefined') {
@ -1864,9 +2067,14 @@ jsPsych.pluginAPI = (function() {
if(n_loaded == files.length) { if(n_loaded == files.length) {
finishfn(); finishfn();
} }
} } else {
audio_buffers[bufferID] = 'tmp'; audio_buffers[bufferID] = 'tmp';
load_audio_file(bufferID); if(module.audioContext() !== null){
load_audio_file_webaudio(bufferID);
} else {
load_audio_file_html5audio(bufferID);
}
}
} }
} }
@ -1905,6 +2113,8 @@ jsPsych.pluginAPI = (function() {
} }
img.src = images[i]; img.src = images[i];
img_cache[images[i]] = img;
} }
}; };
@ -1961,7 +2171,8 @@ jsPsych.pluginAPI = (function() {
return module; return module;
})(); })();
// methods used in multiple modules // methods used in multiple modules //
function flatten(arr, out) { function flatten(arr, out) {
out = (typeof out === 'undefined') ? [] : out; out = (typeof out === 'undefined') ? [] : out;
for (var i = 0; i < arr.length; i++) { for (var i = 0; i < arr.length; i++) {
@ -1973,3 +2184,85 @@ function flatten(arr, out) {
} }
return out; return out;
} }
function deepExtend(out) {
out = out || {};
for (var i = 1; i < arguments.length; i++) {
var obj = arguments[i];
if (!obj)
continue;
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
if (typeof obj[key] === 'object')
out[key] = deepExtend(out[key], obj[key]);
else
out[key] = obj[key];
}
}
}
return out;
};
// polyfill for Object.assign to support IE
if (typeof Object.assign != 'function') {
Object.assign = function (target, varArgs) { // .length of function is 2
'use strict';
if (target == null) { // TypeError if undefined or null
throw new TypeError('Cannot convert undefined or null to object');
}
var to = Object(target);
for (var index = 1; index < arguments.length; index++) {
var nextSource = arguments[index];
if (nextSource != null) { // Skip over if undefined or null
for (var nextKey in nextSource) {
// Avoid bugs when hasOwnProperty is shadowed
if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
to[nextKey] = nextSource[nextKey];
}
}
}
}
return to;
};
}
// polyfill for Array.includes to support IE
if (!Array.prototype.includes) {
Array.prototype.includes = function(searchElement /*, fromIndex*/) {
'use strict';
if (this == null) {
throw new TypeError('Array.prototype.includes called on null or undefined');
}
var O = Object(this);
var len = parseInt(O.length, 10) || 0;
if (len === 0) {
return false;
}
var n = parseInt(arguments[1], 10) || 0;
var k;
if (n >= 0) {
k = n;
} else {
k = len + n;
if (k < 0) {k = 0;}
}
var currentElement;
while (k < len) {
currentElement = O[k];
if (searchElement === currentElement ||
(searchElement !== searchElement && currentElement !== currentElement)) { // NaN !== NaN
return true;
}
k++;
}
return false;
};
}

View File

@ -1,6 +1,6 @@
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2015 Joshua R. de Leeuw Copyright (c) 2014-2017 Joshua R. de Leeuw
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

25
package.json Normal file
View File

@ -0,0 +1,25 @@
{
"name": "jspsych",
"version": "6.0.0",
"description": "Behavioral experiments in a browser",
"main": "jspsych.js",
"directories": {
"doc": "docs"
},
"scripts": {
"test": "jest"
},
"repository": {
"type": "git",
"url": "git+https://github.com/jodeleeuw/jsPsych.git"
},
"author": "Josh de Leeuw",
"license": "MIT",
"bugs": {
"url": "https://github.com/jodeleeuw/jsPsych/issues"
},
"homepage": "https://github.com/jodeleeuw/jsPsych#readme",
"devDependencies": {
"jest": "^17.0.3"
}
}

Some files were not shown because too many files have changed in this diff Show More