jspsych 7.1.1 → 7.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/css/jspsych.css +322 -12
- package/dist/index.browser.js +147 -2
- package/dist/index.browser.js.map +1 -1
- package/dist/index.browser.min.js +1 -1
- package/dist/index.browser.min.js.map +1 -1
- package/dist/index.cjs +147 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +147 -2
- package/dist/index.js.map +1 -1
- package/dist/modules/data/DataCollection.d.ts +1 -0
- package/dist/modules/plugins.d.ts +7 -0
- package/dist/modules/randomization.d.ts +7 -0
- package/package.json +20 -7
- package/src/JsPsych.ts +3 -1
- package/src/index.scss +209 -0
- package/src/modules/data/DataCollection.ts +8 -0
- package/src/modules/plugins.ts +7 -0
- package/src/modules/randomization.ts +12 -0
|
@@ -36,6 +36,7 @@ export declare class DataCollection {
|
|
|
36
36
|
addToLast(properties: any): this;
|
|
37
37
|
filter(filters: any): DataCollection;
|
|
38
38
|
filterCustom(fn: any): DataCollection;
|
|
39
|
+
filterColumns(columns: Array<string>): DataCollection;
|
|
39
40
|
select(column: any): DataColumn;
|
|
40
41
|
ignore(columns: any): DataCollection;
|
|
41
42
|
uniqueNames(): any[];
|
|
@@ -113,6 +113,13 @@ export declare const universalPluginParameters: {
|
|
|
113
113
|
readonly pretty_name: "Custom CSS classes";
|
|
114
114
|
readonly default: any;
|
|
115
115
|
};
|
|
116
|
+
/**
|
|
117
|
+
* Options to control simulation mode for the trial.
|
|
118
|
+
*/
|
|
119
|
+
readonly simulation_options: {
|
|
120
|
+
readonly type: ParameterType.COMPLEX;
|
|
121
|
+
readonly default: any;
|
|
122
|
+
};
|
|
116
123
|
};
|
|
117
124
|
export declare type UniversalPluginParameters = InferredParameters<typeof universalPluginParameters>;
|
|
118
125
|
export interface PluginInfo {
|
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Uses the `seedrandom` package to replace Math.random() with a seedable PRNG.
|
|
3
|
+
*
|
|
4
|
+
* @param seed An optional seed. If none is given, a random seed will be generated.
|
|
5
|
+
* @returns The seed value.
|
|
6
|
+
*/
|
|
7
|
+
export declare function setSeed(seed?: string): string;
|
|
1
8
|
export declare function repeat(array: any, repetitions: any, unpack?: boolean): any;
|
|
2
9
|
export declare function shuffle(array: Array<any>): any[];
|
|
3
10
|
export declare function shuffleNoRepeats(arr: Array<any>, equalityTest: (a: any, b: any) => boolean): any[];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "jspsych",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.2.1",
|
|
4
4
|
"description": "Behavioral experiments in a browser",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.cjs",
|
|
@@ -23,8 +23,10 @@
|
|
|
23
23
|
"test": "jest",
|
|
24
24
|
"test:watch": "npm test -- --watch",
|
|
25
25
|
"tsc": "tsc",
|
|
26
|
-
"build": "rollup --config",
|
|
27
|
-
"build:
|
|
26
|
+
"build:js": "rollup --config",
|
|
27
|
+
"build:styles": "webpack-cli",
|
|
28
|
+
"build": "run-p build:js build:styles",
|
|
29
|
+
"build:watch": "run-p \"build:js -- --watch\" \"build:styles watch\"",
|
|
28
30
|
"prepack": "cp ../../README.md ."
|
|
29
31
|
},
|
|
30
32
|
"repository": {
|
|
@@ -40,11 +42,22 @@
|
|
|
40
42
|
"homepage": "https://www.jspsych.org",
|
|
41
43
|
"dependencies": {
|
|
42
44
|
"auto-bind": "^4.0.0",
|
|
43
|
-
"random-words": "^1.1.1"
|
|
45
|
+
"random-words": "^1.1.1",
|
|
46
|
+
"seedrandom": "^3.0.5"
|
|
44
47
|
},
|
|
45
48
|
"devDependencies": {
|
|
46
|
-
"@
|
|
47
|
-
"@jspsych/
|
|
48
|
-
"@types/dom-mediacapture-record": "^1.0.11"
|
|
49
|
+
"@fontsource/open-sans": "4.5.3",
|
|
50
|
+
"@jspsych/config": "^1.2.0",
|
|
51
|
+
"@types/dom-mediacapture-record": "^1.0.11",
|
|
52
|
+
"base64-inline-loader": "^2.0.1",
|
|
53
|
+
"css-loader": "^6.6.0",
|
|
54
|
+
"mini-css-extract-plugin": "^2.5.3",
|
|
55
|
+
"npm-run-all": "^4.1.5",
|
|
56
|
+
"sass": "^1.43.5",
|
|
57
|
+
"sass-loader": "^12.4.0",
|
|
58
|
+
"webpack": "^5.68.0",
|
|
59
|
+
"webpack-cli": "^4.9.2",
|
|
60
|
+
"webpack-remove-empty-scripts": "^0.7.2",
|
|
61
|
+
"replace-in-file-webpack-plugin": "^1.0.6"
|
|
49
62
|
}
|
|
50
63
|
}
|
package/src/JsPsych.ts
CHANGED
|
@@ -302,7 +302,9 @@ export class JsPsych {
|
|
|
302
302
|
this.internal.call_immediate = false;
|
|
303
303
|
|
|
304
304
|
// wait for iti
|
|
305
|
-
if (
|
|
305
|
+
if (this.simulation_mode === "data-only") {
|
|
306
|
+
this.nextTrial();
|
|
307
|
+
} else if (
|
|
306
308
|
typeof current_trial.post_trial_gap === null ||
|
|
307
309
|
typeof current_trial.post_trial_gap === "undefined"
|
|
308
310
|
) {
|
package/src/index.scss
ADDED
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* CSS for jsPsych experiments.
|
|
3
|
+
*
|
|
4
|
+
* This stylesheet provides minimal styling to make jsPsych
|
|
5
|
+
* experiments look polished without any additional styles.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
@import "@fontsource/open-sans/400-italic.css";
|
|
9
|
+
@import "@fontsource/open-sans/700-italic.css";
|
|
10
|
+
@import "@fontsource/open-sans/400.css";
|
|
11
|
+
@import "@fontsource/open-sans/700.css";
|
|
12
|
+
|
|
13
|
+
/* Container holding jsPsych content */
|
|
14
|
+
|
|
15
|
+
.jspsych-display-element {
|
|
16
|
+
display: flex;
|
|
17
|
+
flex-direction: column;
|
|
18
|
+
overflow-y: auto;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.jspsych-display-element:focus {
|
|
22
|
+
outline: none;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.jspsych-content-wrapper {
|
|
26
|
+
display: flex;
|
|
27
|
+
margin: auto;
|
|
28
|
+
flex: 1 1 100%;
|
|
29
|
+
width: 100%;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.jspsych-content {
|
|
33
|
+
max-width: 95%; /* this is mainly an IE 10-11 fix */
|
|
34
|
+
text-align: center;
|
|
35
|
+
margin: auto; /* this is for overflowing content */
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.jspsych-top {
|
|
39
|
+
align-items: flex-start;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.jspsych-middle {
|
|
43
|
+
align-items: center;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/* fonts and type */
|
|
47
|
+
|
|
48
|
+
.jspsych-display-element {
|
|
49
|
+
font-family: "Open Sans", "Arial", sans-serif;
|
|
50
|
+
font-size: 18px;
|
|
51
|
+
line-height: 1.6em;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/* Form elements like input fields and buttons */
|
|
55
|
+
|
|
56
|
+
.jspsych-display-element input[type="text"] {
|
|
57
|
+
font-family: "Open Sans", "Arial", sans-serif;
|
|
58
|
+
font-size: 14px;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/* borrowing Bootstrap style for btn elements, but combining styles a bit */
|
|
62
|
+
.jspsych-btn {
|
|
63
|
+
display: inline-block;
|
|
64
|
+
padding: 6px 12px;
|
|
65
|
+
margin: 0px;
|
|
66
|
+
font-size: 14px;
|
|
67
|
+
font-weight: 400;
|
|
68
|
+
font-family: "Open Sans", "Arial", sans-serif;
|
|
69
|
+
cursor: pointer;
|
|
70
|
+
line-height: 1.4;
|
|
71
|
+
text-align: center;
|
|
72
|
+
white-space: nowrap;
|
|
73
|
+
vertical-align: middle;
|
|
74
|
+
background-image: none;
|
|
75
|
+
border: 1px solid transparent;
|
|
76
|
+
border-radius: 4px;
|
|
77
|
+
color: #333;
|
|
78
|
+
background-color: #fff;
|
|
79
|
+
border-color: #ccc;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/* only apply the hover style on devices with a mouse/pointer that can hover - issue #977 */
|
|
83
|
+
@media (hover: hover) {
|
|
84
|
+
.jspsych-btn:hover {
|
|
85
|
+
background-color: #ddd;
|
|
86
|
+
border-color: #aaa;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
.jspsych-btn:active {
|
|
91
|
+
background-color: #ddd;
|
|
92
|
+
border-color: #000000;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
.jspsych-btn:disabled {
|
|
96
|
+
background-color: #eee;
|
|
97
|
+
color: #aaa;
|
|
98
|
+
border-color: #ccc;
|
|
99
|
+
cursor: not-allowed;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/* custom style for input[type="range] (slider) to improve alignment between positions and labels */
|
|
103
|
+
|
|
104
|
+
.jspsych-slider {
|
|
105
|
+
appearance: none;
|
|
106
|
+
-webkit-appearance: none;
|
|
107
|
+
-moz-appearance: none;
|
|
108
|
+
width: 100%;
|
|
109
|
+
background: transparent;
|
|
110
|
+
}
|
|
111
|
+
.jspsych-slider:focus {
|
|
112
|
+
outline: none;
|
|
113
|
+
}
|
|
114
|
+
/* track */
|
|
115
|
+
.jspsych-slider::-webkit-slider-runnable-track {
|
|
116
|
+
appearance: none;
|
|
117
|
+
-webkit-appearance: none;
|
|
118
|
+
width: 100%;
|
|
119
|
+
height: 8px;
|
|
120
|
+
cursor: pointer;
|
|
121
|
+
background: #eee;
|
|
122
|
+
box-shadow: 0px 0px 0px #000000, 0px 0px 0px #0d0d0d;
|
|
123
|
+
border-radius: 2px;
|
|
124
|
+
border: 1px solid #aaa;
|
|
125
|
+
}
|
|
126
|
+
.jspsych-slider::-moz-range-track {
|
|
127
|
+
appearance: none;
|
|
128
|
+
width: 100%;
|
|
129
|
+
height: 8px;
|
|
130
|
+
cursor: pointer;
|
|
131
|
+
background: #eee;
|
|
132
|
+
box-shadow: 0px 0px 0px #000000, 0px 0px 0px #0d0d0d;
|
|
133
|
+
border-radius: 2px;
|
|
134
|
+
border: 1px solid #aaa;
|
|
135
|
+
}
|
|
136
|
+
.jspsych-slider::-ms-track {
|
|
137
|
+
appearance: none;
|
|
138
|
+
width: 99%;
|
|
139
|
+
height: 14px;
|
|
140
|
+
cursor: pointer;
|
|
141
|
+
background: #eee;
|
|
142
|
+
box-shadow: 0px 0px 0px #000000, 0px 0px 0px #0d0d0d;
|
|
143
|
+
border-radius: 2px;
|
|
144
|
+
border: 1px solid #aaa;
|
|
145
|
+
}
|
|
146
|
+
/* thumb */
|
|
147
|
+
.jspsych-slider::-webkit-slider-thumb {
|
|
148
|
+
border: 1px solid #666;
|
|
149
|
+
height: 24px;
|
|
150
|
+
width: 15px;
|
|
151
|
+
border-radius: 5px;
|
|
152
|
+
background: #ffffff;
|
|
153
|
+
cursor: pointer;
|
|
154
|
+
-webkit-appearance: none;
|
|
155
|
+
margin-top: -9px;
|
|
156
|
+
}
|
|
157
|
+
.jspsych-slider::-moz-range-thumb {
|
|
158
|
+
border: 1px solid #666;
|
|
159
|
+
height: 24px;
|
|
160
|
+
width: 15px;
|
|
161
|
+
border-radius: 5px;
|
|
162
|
+
background: #ffffff;
|
|
163
|
+
cursor: pointer;
|
|
164
|
+
}
|
|
165
|
+
.jspsych-slider::-ms-thumb {
|
|
166
|
+
border: 1px solid #666;
|
|
167
|
+
height: 20px;
|
|
168
|
+
width: 15px;
|
|
169
|
+
border-radius: 5px;
|
|
170
|
+
background: #ffffff;
|
|
171
|
+
cursor: pointer;
|
|
172
|
+
margin-top: -2px;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/* jsPsych progress bar */
|
|
176
|
+
|
|
177
|
+
#jspsych-progressbar-container {
|
|
178
|
+
color: #555;
|
|
179
|
+
border-bottom: 1px solid #dedede;
|
|
180
|
+
background-color: #f9f9f9;
|
|
181
|
+
margin-bottom: 1em;
|
|
182
|
+
text-align: center;
|
|
183
|
+
padding: 8px 0px;
|
|
184
|
+
width: 100%;
|
|
185
|
+
line-height: 1em;
|
|
186
|
+
}
|
|
187
|
+
#jspsych-progressbar-container span {
|
|
188
|
+
font-size: 14px;
|
|
189
|
+
padding-right: 14px;
|
|
190
|
+
}
|
|
191
|
+
#jspsych-progressbar-outer {
|
|
192
|
+
background-color: #eee;
|
|
193
|
+
width: 50%;
|
|
194
|
+
margin: auto;
|
|
195
|
+
height: 14px;
|
|
196
|
+
display: inline-block;
|
|
197
|
+
vertical-align: middle;
|
|
198
|
+
box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
|
|
199
|
+
}
|
|
200
|
+
#jspsych-progressbar-inner {
|
|
201
|
+
background-color: #aaa;
|
|
202
|
+
width: 0%;
|
|
203
|
+
height: 100%;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/* Control appearance of jsPsych.data.displayData() */
|
|
207
|
+
#jspsych-data-display {
|
|
208
|
+
text-align: left;
|
|
209
|
+
}
|
|
@@ -134,6 +134,14 @@ export class DataCollection {
|
|
|
134
134
|
return new DataCollection(this.trials.filter(fn));
|
|
135
135
|
}
|
|
136
136
|
|
|
137
|
+
filterColumns(columns: Array<string>) {
|
|
138
|
+
return new DataCollection(
|
|
139
|
+
this.trials.map((trial) =>
|
|
140
|
+
Object.fromEntries(columns.filter((key) => key in trial).map((key) => [key, trial[key]]))
|
|
141
|
+
)
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
|
|
137
145
|
select(column) {
|
|
138
146
|
const values = [];
|
|
139
147
|
for (const trial of this.trials) {
|
package/src/modules/plugins.ts
CHANGED
|
@@ -133,6 +133,13 @@ export const universalPluginParameters = <const>{
|
|
|
133
133
|
pretty_name: "Custom CSS classes",
|
|
134
134
|
default: null,
|
|
135
135
|
},
|
|
136
|
+
/**
|
|
137
|
+
* Options to control simulation mode for the trial.
|
|
138
|
+
*/
|
|
139
|
+
simulation_options: {
|
|
140
|
+
type: ParameterType.COMPLEX,
|
|
141
|
+
default: null,
|
|
142
|
+
},
|
|
136
143
|
};
|
|
137
144
|
|
|
138
145
|
export type UniversalPluginParameters = InferredParameters<typeof universalPluginParameters>;
|
|
@@ -1,4 +1,16 @@
|
|
|
1
1
|
import rw from "random-words";
|
|
2
|
+
import seedrandom from "seedrandom/lib/alea";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Uses the `seedrandom` package to replace Math.random() with a seedable PRNG.
|
|
6
|
+
*
|
|
7
|
+
* @param seed An optional seed. If none is given, a random seed will be generated.
|
|
8
|
+
* @returns The seed value.
|
|
9
|
+
*/
|
|
10
|
+
export function setSeed(seed: string = Math.random().toString()) {
|
|
11
|
+
Math.random = seedrandom(seed);
|
|
12
|
+
return seed;
|
|
13
|
+
}
|
|
2
14
|
|
|
3
15
|
export function repeat(array, repetitions, unpack = false) {
|
|
4
16
|
const arr_isArray = Array.isArray(array);
|