jspsych 6.2.0 → 7.1.0

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.
Files changed (360) hide show
  1. package/README.md +43 -29
  2. package/css/jspsych.css +39 -39
  3. package/dist/JsPsych.d.ts +112 -0
  4. package/dist/TimelineNode.d.ts +34 -0
  5. package/dist/index.browser.js +3164 -0
  6. package/dist/index.browser.js.map +1 -0
  7. package/dist/index.browser.min.js +2 -0
  8. package/dist/index.browser.min.js.map +1 -0
  9. package/dist/index.cjs +3158 -0
  10. package/dist/index.cjs.map +1 -0
  11. package/dist/index.d.ts +11 -0
  12. package/dist/index.js +3152 -0
  13. package/dist/index.js.map +1 -0
  14. package/dist/migration.d.ts +3 -0
  15. package/dist/modules/data/DataCollection.d.ts +45 -0
  16. package/dist/modules/data/DataColumn.d.ts +15 -0
  17. package/dist/modules/data/index.d.ts +25 -0
  18. package/dist/modules/data/utils.d.ts +3 -0
  19. package/dist/modules/extensions.d.ts +22 -0
  20. package/dist/modules/plugin-api/HardwareAPI.d.ts +15 -0
  21. package/dist/modules/plugin-api/KeyboardListenerAPI.d.ts +34 -0
  22. package/dist/modules/plugin-api/MediaAPI.d.ts +27 -0
  23. package/dist/modules/plugin-api/SimulationAPI.d.ts +41 -0
  24. package/dist/modules/plugin-api/TimeoutAPI.d.ts +5 -0
  25. package/dist/modules/plugin-api/index.d.ts +8 -0
  26. package/dist/modules/plugins.d.ts +129 -0
  27. package/dist/modules/randomization.d.ts +35 -0
  28. package/dist/modules/turk.d.ts +40 -0
  29. package/dist/modules/utils.d.ts +7 -0
  30. package/package.json +32 -15
  31. package/src/JsPsych.ts +884 -0
  32. package/src/TimelineNode.ts +536 -0
  33. package/src/index.ts +71 -0
  34. package/src/migration.ts +37 -0
  35. package/src/modules/data/DataCollection.ts +198 -0
  36. package/src/modules/data/DataColumn.ts +86 -0
  37. package/src/modules/data/index.ts +174 -0
  38. package/src/modules/data/utils.ts +75 -0
  39. package/src/modules/extensions.ts +23 -0
  40. package/src/modules/plugin-api/HardwareAPI.ts +32 -0
  41. package/src/modules/plugin-api/KeyboardListenerAPI.ts +165 -0
  42. package/src/modules/plugin-api/MediaAPI.ts +337 -0
  43. package/src/modules/plugin-api/SimulationAPI.ts +181 -0
  44. package/src/modules/plugin-api/TimeoutAPI.ts +16 -0
  45. package/src/modules/plugin-api/index.ts +28 -0
  46. package/src/modules/plugins.ts +158 -0
  47. package/src/modules/randomization.ts +327 -0
  48. package/src/modules/turk.ts +99 -0
  49. package/src/modules/utils.ts +30 -0
  50. package/.github/workflows/jest.yml +0 -20
  51. package/code-of-conduct.md +0 -56
  52. package/contributors.md +0 -61
  53. package/docs/CNAME +0 -1
  54. package/docs/about/about.md +0 -18
  55. package/docs/about/contributing.md +0 -43
  56. package/docs/about/license.md +0 -25
  57. package/docs/about/support.md +0 -7
  58. package/docs/core_library/jspsych-core.md +0 -661
  59. package/docs/core_library/jspsych-data.md +0 -589
  60. package/docs/core_library/jspsych-pluginAPI.md +0 -510
  61. package/docs/core_library/jspsych-randomization.md +0 -397
  62. package/docs/core_library/jspsych-turk.md +0 -102
  63. package/docs/img/blue.png +0 -0
  64. package/docs/img/folder-setup.png +0 -0
  65. package/docs/img/folder-with-html.png +0 -0
  66. package/docs/img/githubreleases.jpg +0 -0
  67. package/docs/img/jspsych-favicon.png +0 -0
  68. package/docs/img/jspsych-logo-no-text-mono.svg +0 -493
  69. package/docs/img/jspsych-logo.jpg +0 -0
  70. package/docs/img/orange.png +0 -0
  71. package/docs/img/palmer_stim.png +0 -0
  72. package/docs/img/progress_bar.png +0 -0
  73. package/docs/img/visual_search_example.jpg +0 -0
  74. package/docs/index.md +0 -9
  75. package/docs/overview/browser-device-support.md +0 -35
  76. package/docs/overview/callbacks.md +0 -140
  77. package/docs/overview/data.md +0 -281
  78. package/docs/overview/exclude-browser.md +0 -32
  79. package/docs/overview/experiment-options.md +0 -121
  80. package/docs/overview/fullscreen.md +0 -36
  81. package/docs/overview/media-preloading.md +0 -91
  82. package/docs/overview/mturk.md +0 -77
  83. package/docs/overview/progress-bar.md +0 -110
  84. package/docs/overview/record-browser-interactions.md +0 -23
  85. package/docs/overview/running-experiments.md +0 -95
  86. package/docs/overview/timeline.md +0 -387
  87. package/docs/overview/trial.md +0 -142
  88. package/docs/plugins/creating-a-plugin.md +0 -79
  89. package/docs/plugins/jspsych-animation.md +0 -40
  90. package/docs/plugins/jspsych-audio-button-response.md +0 -60
  91. package/docs/plugins/jspsych-audio-keyboard-response.md +0 -58
  92. package/docs/plugins/jspsych-audio-slider-response.md +0 -53
  93. package/docs/plugins/jspsych-call-function.md +0 -81
  94. package/docs/plugins/jspsych-canvas-button-response.md +0 -66
  95. package/docs/plugins/jspsych-canvas-keyboard-response.md +0 -68
  96. package/docs/plugins/jspsych-canvas-slider-response.md +0 -89
  97. package/docs/plugins/jspsych-categorize-animation.md +0 -60
  98. package/docs/plugins/jspsych-categorize-html.md +0 -52
  99. package/docs/plugins/jspsych-categorize-image.md +0 -53
  100. package/docs/plugins/jspsych-cloze.md +0 -45
  101. package/docs/plugins/jspsych-external-html.md +0 -70
  102. package/docs/plugins/jspsych-free-sort.md +0 -55
  103. package/docs/plugins/jspsych-fullscreen.md +0 -57
  104. package/docs/plugins/jspsych-html-button-response.md +0 -42
  105. package/docs/plugins/jspsych-html-keyboard-response.md +0 -51
  106. package/docs/plugins/jspsych-html-slider-response.md +0 -45
  107. package/docs/plugins/jspsych-iat-html.md +0 -64
  108. package/docs/plugins/jspsych-iat-image.md +0 -64
  109. package/docs/plugins/jspsych-image-button-response.md +0 -46
  110. package/docs/plugins/jspsych-image-keyboard-response.md +0 -57
  111. package/docs/plugins/jspsych-image-slider-response.md +0 -52
  112. package/docs/plugins/jspsych-instructions.md +0 -58
  113. package/docs/plugins/jspsych-maxdiff.md +0 -42
  114. package/docs/plugins/jspsych-rdk.md +0 -119
  115. package/docs/plugins/jspsych-reconstruction.md +0 -48
  116. package/docs/plugins/jspsych-resize.md +0 -39
  117. package/docs/plugins/jspsych-same-different-html.md +0 -53
  118. package/docs/plugins/jspsych-same-different-image.md +0 -66
  119. package/docs/plugins/jspsych-serial-reaction-time-mouse.md +0 -50
  120. package/docs/plugins/jspsych-serial-reaction-time.md +0 -57
  121. package/docs/plugins/jspsych-survey-html-form.md +0 -50
  122. package/docs/plugins/jspsych-survey-likert.md +0 -70
  123. package/docs/plugins/jspsych-survey-multi-choice.md +0 -48
  124. package/docs/plugins/jspsych-survey-multi-select.md +0 -53
  125. package/docs/plugins/jspsych-survey-text.md +0 -63
  126. package/docs/plugins/jspsych-video-button-response.md +0 -52
  127. package/docs/plugins/jspsych-video-keyboard-response.md +0 -48
  128. package/docs/plugins/jspsych-video-slider-response.md +0 -58
  129. package/docs/plugins/jspsych-visual-search-circle.md +0 -52
  130. package/docs/plugins/jspsych-vsl-animate-occlusion.md +0 -55
  131. package/docs/plugins/jspsych-vsl-grid-scene.md +0 -62
  132. package/docs/plugins/overview.md +0 -111
  133. package/docs/tutorials/hello-world.md +0 -144
  134. package/docs/tutorials/rt-task.md +0 -1107
  135. package/examples/add-to-end-of-timeline.html +0 -32
  136. package/examples/conditional-and-loop-functions.html +0 -63
  137. package/examples/css/jquery-ui.css +0 -1225
  138. package/examples/data-add-properties.html +0 -40
  139. package/examples/data-as-function.html +0 -36
  140. package/examples/data-from-timeline.html +0 -45
  141. package/examples/data-from-url.html +0 -21
  142. package/examples/demo-flanker.html +0 -108
  143. package/examples/demo-simple-rt-task.html +0 -104
  144. package/examples/demos/demo_1.html +0 -29
  145. package/examples/demos/demo_2.html +0 -43
  146. package/examples/demos/demo_3.html +0 -58
  147. package/examples/display-element-to-embed-experiment.html +0 -73
  148. package/examples/end-active-node.html +0 -52
  149. package/examples/end-experiment.html +0 -43
  150. package/examples/exclusions.html +0 -32
  151. package/examples/external_html/simple_consent.html +0 -4
  152. package/examples/img/1.gif +0 -0
  153. package/examples/img/10.gif +0 -0
  154. package/examples/img/11.gif +0 -0
  155. package/examples/img/12.gif +0 -0
  156. package/examples/img/2.gif +0 -0
  157. package/examples/img/3.gif +0 -0
  158. package/examples/img/4.gif +0 -0
  159. package/examples/img/5.gif +0 -0
  160. package/examples/img/6.gif +0 -0
  161. package/examples/img/7.gif +0 -0
  162. package/examples/img/8.gif +0 -0
  163. package/examples/img/9.gif +0 -0
  164. package/examples/img/age/of1.jpg +0 -0
  165. package/examples/img/age/of2.jpg +0 -0
  166. package/examples/img/age/of3.jpg +0 -0
  167. package/examples/img/age/om1.jpg +0 -0
  168. package/examples/img/age/om2.jpg +0 -0
  169. package/examples/img/age/om3.jpg +0 -0
  170. package/examples/img/age/yf1.jpg +0 -0
  171. package/examples/img/age/yf4.jpg +0 -0
  172. package/examples/img/age/yf5.jpg +0 -0
  173. package/examples/img/age/ym2.jpg +0 -0
  174. package/examples/img/age/ym3.jpg +0 -0
  175. package/examples/img/age/ym5.jpg +0 -0
  176. package/examples/img/backwardN.gif +0 -0
  177. package/examples/img/blue.png +0 -0
  178. package/examples/img/con1.png +0 -0
  179. package/examples/img/con2.png +0 -0
  180. package/examples/img/fixation.gif +0 -0
  181. package/examples/img/happy_face_1.jpg +0 -0
  182. package/examples/img/happy_face_2.jpg +0 -0
  183. package/examples/img/happy_face_3.jpg +0 -0
  184. package/examples/img/happy_face_4.jpg +0 -0
  185. package/examples/img/inc1.png +0 -0
  186. package/examples/img/inc2.png +0 -0
  187. package/examples/img/normalN.gif +0 -0
  188. package/examples/img/orange.png +0 -0
  189. package/examples/img/redX.png +0 -0
  190. package/examples/img/ribbon.jpg +0 -0
  191. package/examples/img/sad_face_1.jpg +0 -0
  192. package/examples/img/sad_face_2.jpg +0 -0
  193. package/examples/img/sad_face_3.jpg +0 -0
  194. package/examples/img/sad_face_4.jpg +0 -0
  195. package/examples/js/snap.svg-min.js +0 -21
  196. package/examples/jspsych-RDK.html +0 -58
  197. package/examples/jspsych-animation.html +0 -33
  198. package/examples/jspsych-audio-button-response.html +0 -52
  199. package/examples/jspsych-audio-keyboard-response.html +0 -62
  200. package/examples/jspsych-audio-slider-response.html +0 -55
  201. package/examples/jspsych-call-function.html +0 -32
  202. package/examples/jspsych-canvas-button-response.html +0 -95
  203. package/examples/jspsych-canvas-keyboard-response.html +0 -78
  204. package/examples/jspsych-canvas-slider-response.html +0 -67
  205. package/examples/jspsych-categorize-animation.html +0 -46
  206. package/examples/jspsych-categorize-html.html +0 -38
  207. package/examples/jspsych-categorize-image.html +0 -38
  208. package/examples/jspsych-cloze.html +0 -42
  209. package/examples/jspsych-free-sort.html +0 -97
  210. package/examples/jspsych-fullscreen.html +0 -44
  211. package/examples/jspsych-html-button-response.html +0 -46
  212. package/examples/jspsych-html-keyboard-response.html +0 -42
  213. package/examples/jspsych-html-slider-response.html +0 -53
  214. package/examples/jspsych-iat.html +0 -510
  215. package/examples/jspsych-image-button-response.html +0 -84
  216. package/examples/jspsych-image-keyboard-response.html +0 -78
  217. package/examples/jspsych-image-slider-response.html +0 -76
  218. package/examples/jspsych-instructions.html +0 -37
  219. package/examples/jspsych-maxdiff.html +0 -33
  220. package/examples/jspsych-reconstruction.html +0 -43
  221. package/examples/jspsych-resize.html +0 -34
  222. package/examples/jspsych-same-different-html.html +0 -28
  223. package/examples/jspsych-same-different-image.html +0 -33
  224. package/examples/jspsych-serial-reaction-time-mouse.html +0 -98
  225. package/examples/jspsych-serial-reaction-time.html +0 -54
  226. package/examples/jspsych-survey-html-form.html +0 -33
  227. package/examples/jspsych-survey-likert.html +0 -42
  228. package/examples/jspsych-survey-multi-choice.html +0 -40
  229. package/examples/jspsych-survey-multi-select.html +0 -42
  230. package/examples/jspsych-survey-text.html +0 -34
  231. package/examples/jspsych-video-button-response.html +0 -57
  232. package/examples/jspsych-video-keyboard-response.html +0 -53
  233. package/examples/jspsych-video-slider-response.html +0 -55
  234. package/examples/jspsych-visual-search-circle.html +0 -58
  235. package/examples/jspsych-vsl-animate-occlusion.html +0 -29
  236. package/examples/jspsych-vsl-grid-scene.html +0 -41
  237. package/examples/lexical-decision.html +0 -132
  238. package/examples/manual-preloading.html +0 -53
  239. package/examples/pause-unpause.html +0 -33
  240. package/examples/progress-bar.html +0 -62
  241. package/examples/sound/hammer.mp3 +0 -0
  242. package/examples/sound/sound.mp3 +0 -0
  243. package/examples/sound/speech_blue.mp3 +0 -0
  244. package/examples/sound/speech_green.mp3 +0 -0
  245. package/examples/sound/speech_joke.mp3 +0 -0
  246. package/examples/sound/speech_red.mp3 +0 -0
  247. package/examples/sound/tone.mp3 +0 -0
  248. package/examples/timeline-variables-sampling.html +0 -50
  249. package/examples/timeline-variables.html +0 -55
  250. package/examples/video/sample_video.mp4 +0 -0
  251. package/jspsych.js +0 -2796
  252. package/license.txt +0 -21
  253. package/mkdocs.yml +0 -104
  254. package/plugins/jspsych-animation.js +0 -189
  255. package/plugins/jspsych-audio-button-response.js +0 -247
  256. package/plugins/jspsych-audio-keyboard-response.js +0 -204
  257. package/plugins/jspsych-audio-slider-response.js +0 -262
  258. package/plugins/jspsych-call-function.js +0 -58
  259. package/plugins/jspsych-canvas-button-response.js +0 -199
  260. package/plugins/jspsych-canvas-keyboard-response.js +0 -155
  261. package/plugins/jspsych-canvas-slider-response.js +0 -207
  262. package/plugins/jspsych-categorize-animation.js +0 -266
  263. package/plugins/jspsych-categorize-html.js +0 -220
  264. package/plugins/jspsych-categorize-image.js +0 -222
  265. package/plugins/jspsych-cloze.js +0 -112
  266. package/plugins/jspsych-external-html.js +0 -112
  267. package/plugins/jspsych-free-sort.js +0 -444
  268. package/plugins/jspsych-fullscreen.js +0 -104
  269. package/plugins/jspsych-html-button-response.js +0 -188
  270. package/plugins/jspsych-html-keyboard-response.js +0 -149
  271. package/plugins/jspsych-html-slider-response.js +0 -202
  272. package/plugins/jspsych-iat-html.js +0 -284
  273. package/plugins/jspsych-iat-image.js +0 -286
  274. package/plugins/jspsych-image-button-response.js +0 -311
  275. package/plugins/jspsych-image-keyboard-response.js +0 -247
  276. package/plugins/jspsych-image-slider-response.js +0 -353
  277. package/plugins/jspsych-instructions.js +0 -237
  278. package/plugins/jspsych-maxdiff.js +0 -174
  279. package/plugins/jspsych-rdk.js +0 -1373
  280. package/plugins/jspsych-reconstruction.js +0 -134
  281. package/plugins/jspsych-resize.js +0 -166
  282. package/plugins/jspsych-same-different-html.js +0 -168
  283. package/plugins/jspsych-same-different-image.js +0 -169
  284. package/plugins/jspsych-serial-reaction-time-mouse.js +0 -213
  285. package/plugins/jspsych-serial-reaction-time.js +0 -247
  286. package/plugins/jspsych-survey-html-form.js +0 -171
  287. package/plugins/jspsych-survey-likert.js +0 -195
  288. package/plugins/jspsych-survey-multi-choice.js +0 -208
  289. package/plugins/jspsych-survey-multi-select.js +0 -232
  290. package/plugins/jspsych-survey-text.js +0 -185
  291. package/plugins/jspsych-video-button-response.js +0 -320
  292. package/plugins/jspsych-video-keyboard-response.js +0 -279
  293. package/plugins/jspsych-video-slider-response.js +0 -351
  294. package/plugins/jspsych-visual-search-circle.js +0 -259
  295. package/plugins/jspsych-vsl-animate-occlusion.js +0 -196
  296. package/plugins/jspsych-vsl-grid-scene.js +0 -103
  297. package/plugins/template/jspsych-plugin-template.js +0 -35
  298. package/tests/README.md +0 -7
  299. package/tests/jsPsych/default-iti.test.js +0 -51
  300. package/tests/jsPsych/default-parameters.test.js +0 -58
  301. package/tests/jsPsych/endexperiment.test.js +0 -49
  302. package/tests/jsPsych/events.test.js +0 -369
  303. package/tests/jsPsych/init.test.js +0 -48
  304. package/tests/jsPsych/loads.test.js +0 -7
  305. package/tests/jsPsych/min-rt.test.js +0 -58
  306. package/tests/jsPsych/progressbar.test.js +0 -202
  307. package/tests/jsPsych/timeline-variables.test.js +0 -254
  308. package/tests/jsPsych/timelines.test.js +0 -498
  309. package/tests/jsPsych.data/datacollection.test.js +0 -116
  310. package/tests/jsPsych.data/datacolumn.test.js +0 -50
  311. package/tests/jsPsych.data/datamodule.test.js +0 -152
  312. package/tests/jsPsych.data/dataparameter.test.js +0 -251
  313. package/tests/jsPsych.data/interactions.test.js +0 -109
  314. package/tests/jsPsych.pluginAPI/pluginapi.test.js +0 -144
  315. package/tests/jsPsych.randomization/randomziation.test.js +0 -27
  316. package/tests/jsPsych.utils/utils.test.js +0 -58
  317. package/tests/media/blue.png +0 -0
  318. package/tests/media/orange.png +0 -0
  319. package/tests/media/sample_video.mp4 +0 -0
  320. package/tests/media/sound.mp3 +0 -0
  321. package/tests/plugins/plugin-animation.test.js +0 -35
  322. package/tests/plugins/plugin-audio-button-response.test.js +0 -15
  323. package/tests/plugins/plugin-audio-keyboard-response.test.js +0 -15
  324. package/tests/plugins/plugin-audio-slider-response.test.js +0 -15
  325. package/tests/plugins/plugin-call-function.test.js +0 -49
  326. package/tests/plugins/plugin-categorize-animation.test.js +0 -274
  327. package/tests/plugins/plugin-categorize-html.test.js +0 -17
  328. package/tests/plugins/plugin-categorize-image.test.js +0 -17
  329. package/tests/plugins/plugin-cloze.test.js +0 -140
  330. package/tests/plugins/plugin-free-sort.test.js +0 -112
  331. package/tests/plugins/plugin-fullscreen.test.js +0 -41
  332. package/tests/plugins/plugin-html-button-response.test.js +0 -161
  333. package/tests/plugins/plugin-html-keyboard-response.test.js +0 -139
  334. package/tests/plugins/plugin-html-slider-response.test.js +0 -155
  335. package/tests/plugins/plugin-iat-html.test.js +0 -328
  336. package/tests/plugins/plugin-iat-image.test.js +0 -308
  337. package/tests/plugins/plugin-image-button-response.test.js +0 -183
  338. package/tests/plugins/plugin-image-keyboard-response.test.js +0 -154
  339. package/tests/plugins/plugin-image-slider-response.test.js +0 -183
  340. package/tests/plugins/plugin-instructions.test.js +0 -66
  341. package/tests/plugins/plugin-maxdiff.test.js +0 -39
  342. package/tests/plugins/plugin-rdk.test.js +0 -17
  343. package/tests/plugins/plugin-reconstruction.test.js +0 -16
  344. package/tests/plugins/plugin-resize.test.js +0 -16
  345. package/tests/plugins/plugin-same-different-html.test.js +0 -17
  346. package/tests/plugins/plugin-same-different-image.test.js +0 -17
  347. package/tests/plugins/plugin-serial-reaction-time-mouse.test.js +0 -42
  348. package/tests/plugins/plugin-serial-reaction-time.test.js +0 -69
  349. package/tests/plugins/plugin-survey-html-form.test.js +0 -44
  350. package/tests/plugins/plugin-survey-likert.test.js +0 -48
  351. package/tests/plugins/plugin-survey-multi-choice.test.js +0 -48
  352. package/tests/plugins/plugin-survey-multi-select.test.js +0 -72
  353. package/tests/plugins/plugin-survey-text.test.js +0 -115
  354. package/tests/plugins/plugin-video-button-response.test.js +0 -35
  355. package/tests/plugins/plugin-video-keyboard-response.test.js +0 -35
  356. package/tests/plugins/plugin-video-slider-response.test.js +0 -34
  357. package/tests/plugins/plugin-visual-search-circle.test.js +0 -16
  358. package/tests/plugins/plugin-vsl-animate-occlusion.test.js +0 -16
  359. package/tests/plugins/plugin-vsl-grid-scene.test.js +0 -16
  360. package/tests/testing-utils.js +0 -13
@@ -1,140 +0,0 @@
1
- # Event-related callback functions
2
-
3
- jsPsych offers the ability to call arbitrary functions in response to certain events occurring, like the end of a trial or when new data is saved. This page summarizes the different opportunities for callback functions and how to specify them.
4
-
5
- ---
6
-
7
- ## on_close
8
-
9
- The `on_close` callback can be declared in the `jsPsych.init` method. The callback triggers when the user leaves the page, but before any content on the page is removed from the browser's memory. This can be used, for example, to save data as the user is leaving the page.
10
-
11
- #### Sample use
12
- ```javascript
13
- jsPsych.init({
14
- timeline: exp,
15
- on_close: function(){
16
- var data = jsPsych.data.get().json();
17
- save_data_to_server(data);
18
- }
19
- });
20
- ```
21
-
22
- ---
23
-
24
- ## on_data_update
25
-
26
- The `on_data_update` callback can be declared in the `jsPsych.init` method. The callback triggers at the end of a data update cycle. This happens after every trial, after the on_finish (trial) and on_trial_finish events execute, allowing you to modify the data in those callbacks, and then use this callback to store the data. The function will be passed a single argument, which contains the data that was written.
27
-
28
- #### Sample use
29
- ```javascript
30
- jsPsych.init({
31
- timeline: exp,
32
- on_data_update: function(data) {
33
- console.log('Just added new data. The contents of the data are: '+JSON.stringify(data));
34
- }
35
- });
36
- ```
37
- ---
38
-
39
- ## on_finish (trial)
40
-
41
- The `on_finish` callback can be added to any trial. The callback will trigger whenever the trial ends. The callback function will be passed a single argument, containing the data object from the trial. This data object is *editable*. Any changes made in the on_finish function will be stored in the internal data collection.
42
-
43
- #### Sample use
44
- ```javascript
45
- var trial = {
46
- type: 'image-keyboard-response',
47
- stimulus: 'imgA.png',
48
- on_finish: function(data) {
49
- if(data.key_press == 85){
50
- data.correct = true;
51
- } else {
52
- data.correct = false;
53
- }
54
- }
55
- };
56
- ```
57
- ---
58
-
59
- ## on_finish (experiment)
60
-
61
- The `on_finish` callback can be declared in the `jsPsych.init` method. The callback will trigger once all trials in the experiment have been run. The method will be passed a single argument, containing all of the data generated in the experiment.
62
-
63
- #### Sample use
64
- ```javascript
65
- jsPsych.init({
66
- timeline: exp,
67
- on_finish: function(data) {
68
- console.log('The experiment is over! Here is all the data: '+JSON.stringify(data));
69
- }
70
- });
71
- ```
72
- ---
73
-
74
- ## on_load
75
-
76
- The `on_load` callback can be added to any trial. The callback will trigger once the trial has completed loading. For most plugins, this will occur once the display has been initially updated but before any user interactions or timed events (e.g., animations) have occurred.
77
-
78
- #### Sample use
79
- ```javascript
80
- var trial = {
81
- type: 'image-keyboard-response',
82
- stimulus: 'imgA.png',
83
- on_load: function() {
84
- console.log('The trial just finished loading.');
85
- }
86
- };
87
- ```
88
- ---
89
-
90
- ## on_start (trial)
91
-
92
- The `on_start` callback can be added to any trial. The callback will trigger right before the trial begins. The callback function will be passed a single argument, containing the trial object. If any of the parameters of the trial are functions or timeline variables, these will be evaluated before `on_start` is called, and the trial object will contain the evaluated value. The trial object is modifiable, and any changes made will affect the trial.
93
-
94
- #### Sample use
95
- ```javascript
96
- var trial = {
97
- type: 'image-keyboard-response',
98
- stimulus: 'imgA.png',
99
- on_start: function(trial) {
100
- console.log('The trial is about to start.');
101
- trial.stimulus = 'imgB.png'; // this will change what stimulus is displayed in the trial
102
- }
103
- };
104
- ```
105
-
106
- ---
107
-
108
- ## on_trial_finish
109
-
110
- The `on_trial_finish` callback can be declared in the `jsPsych.init` method. The callback will trigger at the end of every trial in the experiment. If you want a callback to trigger only for the end of certain trials, use the [`on_finish`](#onfinishtrial) callback on the trial object. The callback function will be passed a single argument, containing the data object from the trial.
111
-
112
- #### Sample use
113
- ```javascript
114
- jsPsych.init({
115
- timeline: exp,
116
- on_trial_finish: function(data) {
117
- console.log('A trial just ended.');
118
- console.log(JSON.stringify(data));
119
- }
120
- });
121
- ```
122
- ---
123
-
124
- ## on_trial_start
125
-
126
- The `on_trial_start` callback can be declared in the `jsPsych.init` method. The callback will trigger at the start of every trial in the experiment. The function receives a single argument: a modifiable copy of the trial object that will be used to run the next trial. Changes can be made to this object to alter the parameters of the upcoming trial.
127
-
128
- #### Sample use
129
-
130
- ```javascript
131
- var current_score = 0; // a variable that is updated throughout the experiment to keep track of the current score.
132
-
133
- jsPsych.init({
134
- timeline: exp,
135
- on_trial_start: function(trial) {
136
- trial.data.score_at_start_of_trial = current_score;
137
- console.log('A trial just started.');
138
- }
139
- });
140
- ```
@@ -1,281 +0,0 @@
1
- ## Data in jsPsych: permanent and non-permanent data.
2
-
3
- There are two very different kinds of data storage: data stored in **memory** and data stored **permanently**. Data stored permanently exists even after the browser running jsPsych closes, typically in a database or in a file on a server. Data stored in memory exists only as long the browser window running jsPsych is open.
4
-
5
- jsPsych has many features for interacting with data stored in memory, but few for permanent data storage. This is a deliberate choice, as there are dozens of ways that data could be stored permanently. jsPsych does not lock you into one particular solution. However, saving data permanently is obviously a crucial component of any experiment, and the second half of this page contains a few suggestions on how to accomplish permanent data storage.
6
-
7
- ## Storing data in jsPsych's data structure
8
-
9
- jsPsych has a centralized collection of data that is built as the experiment runs. Each trial adds to the collection, and you can access the data with various functions, including `jsPsych.data.get()`, which returns the entire set of data.
10
-
11
- In most cases, data collection will be automatic and hidden. Plugins save data on their own so it is not uncommon to have the only interaction with the data be at the end of the experiment when it is time to save it in a permanent manner (see sections below about how to do this). However, there are some situations in which you may want to interact with the data; in particular, you may want to store additional data that the plugins are not recording, like a subject identifier or condition assignment. You may also want to add data on a trial by trial basis. For example, in a Stroop paradigm you would want to label which trials are congruent and which are incongruent. These scenarios are explored below.
12
-
13
- ### Adding data to all trials
14
-
15
- Often it is useful to add a piece of data to *all* of the trials in the experiment. For example, appending the subject ID to each trial. This can be done with the `jsPsych.data.addProperties()` function. Here is an example:
16
-
17
- ```javascript
18
- // generate a random subject ID with 15 characters
19
- var subject_id = jsPsych.randomization.randomID(15);
20
-
21
- // pick a random condition for the subject at the start of the experiment
22
- var condition_assignment = jsPsych.randomization.sampleWithoutReplacement(['conditionA', 'conditionB', 'conditionC'], 1)[0];
23
-
24
- // record the condition assignment in the jsPsych data
25
- // this adds a property called 'subject' and a property called 'condition' to every trial
26
- jsPsych.data.addProperties({
27
- subject: subject_id,
28
- condition: condition_assignment
29
- });
30
- ```
31
-
32
- ### Adding data to a particular trial or set of trials
33
-
34
- Data can be added to a particular trial by setting the `data` parameter for the trial. The `data` parameter is an object of key-value pairs, and each pair is added to the data for that trial.
35
-
36
- ```js
37
- var trial = {
38
- type: 'image-keyboard-response',
39
- stimulus: 'imgA.jpg',
40
- data: { image_type: 'A' }
41
- }
42
- ```
43
-
44
- Data declared in this way is also saved in the trials on any nested timelines:
45
-
46
- ```js
47
- var block = {
48
- type: 'image-keyboard-response',
49
- data: { image_type: 'A' },
50
- timeline: [
51
- {stimulus: 'imgA1.jpg'},
52
- {stimulus: 'imgA2.jpg'}
53
- ]
54
- }
55
- ```
56
-
57
- The data object for a trial can also be updated in the `on_finish` event handler. You can override properties or add new ones. This is particularly useful for cases where the value depends on something that happened during the trial.
58
-
59
- ```js
60
- var trial = {
61
- type: 'image-keyboard-response',
62
- stimulus: 'imgA.jpg',
63
- on_finish: function(data){
64
- if(data.key_press == 65){
65
- data.correct = true;
66
- } else {
67
- data.correct = false;
68
- }
69
- }
70
- }
71
- ```
72
-
73
- ## Aggregating and manipulating jsPsych data
74
-
75
- When accessing the data with `jsPsych.data.get()` the returned object is a special data collection object that exposes a number of methods for aggregating and manipulating the data. The full list of methods is detailed in the [data module documentation](../core_library/jspsych-data.md).
76
-
77
- Here are some examples of data collection manipulation.
78
-
79
- All data generated by the image-keyboard-response plugin:
80
- ```js
81
- var data = jsPsych.data.get().filter({trial_type: 'image-keyboard-response'});
82
- ```
83
-
84
- All data generated by the categorize-image plugin with a correct response:
85
- ```js
86
- var data = jsPsych.data.get().filter({trial_type: 'categorize-image', correct: true});
87
- ```
88
-
89
- All data with a response time between 100 and 500ms:
90
- ```js
91
- var data = jsPsych.data.get().filterCustom(function(x){ return x.rt >= 100 && x.rt <=500 });
92
- ```
93
-
94
- Applying filters consecutively to get all trials from a particular plugin with a response time above 100ms:
95
- ```js
96
- var data = jsPsych.data.get().filter({trial_type: 'image-keyboard-response'}).filterCustom(function(x){ return x.rt > 100; });
97
- ```
98
-
99
- Getting the data from the last n trials:
100
- ```js
101
- var n = 3;
102
- var data = jsPsych.data.get().last(n);
103
- ```
104
-
105
- Getting the data from the last n trials with a correct response:
106
- ```js
107
- var n = 3;
108
- var data = jsPsych.data.get().filter({correct: true}).last(n);
109
- ```
110
-
111
- Getting the data from the first n trials:
112
- ```js
113
- var n = 3;
114
- var data = jsPsych.data.get().first(n);
115
- ```
116
-
117
- Counting the number of trials in a data collection:
118
- ```js
119
- var count = jsPsych.data.get().filter({correct: true}).count();
120
- ```
121
-
122
- Selecting all of the response times from a data collection:
123
- ```js
124
- var response_times = jsPsych.data.get().select('rt');
125
- ```
126
-
127
- Calculating various descriptive statistics on the response times in a data collection:
128
-
129
- ```js
130
- jsPsych.data.get().select('rt').mean();
131
- jsPsych.data.get().select('rt').sum();
132
- jsPsych.data.get().select('rt').min();
133
- jsPsych.data.get().select('rt').max();
134
- jsPsych.data.get().select('rt').variance();
135
- jsPsych.data.get().select('rt').sd();
136
- jsPsych.data.get().select('rt').median();
137
- jsPsych.data.get().select('rt').count();
138
- ```
139
-
140
- ## Storing data permanently as a file
141
-
142
- This is one of the simplest methods for saving jsPsych data on the server that is running the experiment. It involves a short PHP script and a few lines of JavaScript code. This method will save each participant's data as a CSV file on the server. **This method will only work if you are running on a web server with PHP installed, or a local server with PHP (e.g., [XAMPP](https://www.apachefriends.org/index.html)).**
143
-
144
- This method uses a simple PHP script to write files to the server:
145
-
146
- ```php
147
- <?php
148
- $post_data = json_decode(file_get_contents('php://input'), true);
149
- // the directory "data" must be writable by the server
150
- $name = "data/".$post_data['filename'].".csv";
151
- $data = $post_data['filedata'];
152
- // write the file to disk
153
- file_put_contents($name, $data);
154
- ?>
155
- ```
156
-
157
- The `file_put_contents($filename, $data)` method requires permission to write new files. An easy way to solve this is to create a directory on the server that will store the data and use the chmod command to give all users write permission to that directory. In the above example, the directory `data/` is used to store files.
158
-
159
- To use the PHP script, the JavaScript that runs jsPsych needs to send the `filename` and `filedata` information. This is done through an [AJAX](http://www.w3schools.com/xml/ajax_intro.asp) call.
160
-
161
- ```javascript
162
- function saveData(name, data){
163
- var xhr = new XMLHttpRequest();
164
- xhr.open('POST', 'write_data.php'); // 'write_data.php' is the path to the php file described above.
165
- xhr.setRequestHeader('Content-Type', 'application/json');
166
- xhr.send(JSON.stringify({filename: name, filedata: data}));
167
- }
168
-
169
- // call the saveData function after the experiment is over
170
- jsPsych.init({
171
- // code to define the experiment structure would go here...
172
- on_finish: function(){ saveData("experiment_data", jsPsych.data.get().csv()); }
173
- });
174
- ```
175
-
176
- To use this in an actual experiment, it would be important to tie the filename to some unique identifier like a subject number. Otherwise the file may be overwritten by collecting new data.
177
-
178
- Note that, depending on file permissions, storing the CSV files this way may make them publicly accessible. One fix is to store the CSV files outside the web directory on the server. This requires changing the path in the PHP script above from `/data` to a non-accessible folder. You should only use this solution if you have access to more than just the web directory on your server.
179
-
180
- ## Storing data permanently in a MySQL database
181
-
182
- The ideal solution for storing data generated by jsPsych is to write it to a database.
183
-
184
- There are dozens of database options. MySQL is one of the most popular [relational databases](http://en.wikipedia.org/wiki/Relational_database), is free to use, and relatively easy [to install](https://www.google.com/search?q=how+to+install+mysql). This code will assume that you have a MySQL database installed on your server that is hosting the jsPsych experiment, and that your server is able to execute PHP code. If you are trying to run on a local machine, you'll need to install a local server environment like [XAMPP](https://www.apachefriends.org/index.html).
185
-
186
- You'll need two PHP scripts. The first is a configuration file for your database. Save it as `database_config.php` on your server. Within this file are configuration options for the database. You'll need to change these according to how you have configured your MySQL installation.
187
-
188
- ```php
189
- <?php
190
- $servername = "localhost";
191
- $port = 3306;
192
- $username = "username";
193
- $password = "password";
194
- $dbname = "database";
195
- $table = "tablename";
196
- ?>
197
- ```
198
-
199
- The second PHP file will write data to the database. This script reads the database to discover what columns are in the table, and then only allows data to be entered in that matches those columns. This is a security feature. Save this file as `write_data.php` on your server.
200
-
201
- ```php
202
- <?php
203
-
204
- // this path should point to your configuration file.
205
- include('database_config.php');
206
-
207
- $data_array = json_decode(file_get_contents('php://input'), true);
208
-
209
- try {
210
- $conn = new PDO("mysql:host=$servername;port=$port;dbname=$dbname", $username, $password);
211
- $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
212
- // First stage is to get all column names from the table and store
213
- // them in $col_names array.
214
- $stmt = $conn->prepare("SHOW COLUMNS FROM `$table`");
215
- $stmt->execute();
216
- $col_names = array();
217
- while($row = $stmt->fetchColumn()) {
218
- $col_names[] = $row;
219
- }
220
- // Second stage is to create prepared SQL statement using the column
221
- // names as a guide to what values might be in the JSON.
222
- // If a value is missing from a particular trial, then NULL is inserted
223
- $sql = "INSERT INTO $table VALUES(";
224
- for($i = 0; $i < count($col_names); $i++){
225
- $name = $col_names[$i];
226
- $sql .= ":$name";
227
- if($i != count($col_names)-1){
228
- $sql .= ", ";
229
- }
230
- }
231
- $sql .= ");";
232
- $insertstmt = $conn->prepare($sql);
233
- for($i=0; $i < count($data_array); $i++){
234
- for($j = 0; $j < count($col_names); $j++){
235
- $colname = $col_names[$j];
236
- if(!isset($data_array[$i][$colname])){
237
- $insertstmt->bindValue(":$colname", null, PDO::PARAM_NULL);
238
- } else {
239
- $insertstmt->bindValue(":$colname", $data_array[$i][$colname]);
240
- }
241
- }
242
- $insertstmt->execute();
243
- }
244
- echo '{"success": true}';
245
- } catch(PDOException $e) {
246
- echo '{"success": false, "message": ' . $e->getMessage();
247
- }
248
- $conn = null;
249
- ?>
250
- ```
251
-
252
- To send the data, we use an AJAX request in JavaScript.
253
- ```JavaScript
254
- function saveData() {
255
- var xhr = new XMLHttpRequest();
256
- xhr.open('POST', 'write_data.php'); // change 'write_data.php' to point to php script.
257
- xhr.setRequestHeader('Content-Type', 'application/json');
258
- xhr.onload = function() {
259
- if(xhr.status == 200){
260
- var response = JSON.parse(xhr.responseText);
261
- console.log(response.success);
262
- }
263
- };
264
- xhr.send(jsPsych.data.get().json());
265
- }
266
- ```
267
-
268
- You can call the `saveData()` function using the `on_finish` handler for the experiment, or by using the `call-function` plugin.
269
-
270
- ```javascript
271
- // with on_finish handler
272
- jsPsych.init({
273
- on_finish: saveData
274
- });
275
-
276
- // with call-function plugin
277
- timeline.push({
278
- type: 'call-function',
279
- func: saveData
280
- });
281
- ```
@@ -1,32 +0,0 @@
1
- # Exclude Participants Based on Browser Features
2
-
3
- Online subjects will use many different kinds of browsers. Depending on the experiment, it may be important to specify a minimum feature set of the browser. jsPsych makes this straightforward. Simply specify certain exclusion criteria in the `jsPsych.init` method call. If a subject's browser doesn't meet the criteria the experiment will not start and the subject will see a message explaining the problem. For size restrictions the subject will see a message that displays the current size of their browser window and the minimum size needed to start the experiment, giving the subject an opportunity to enlarge the browser window to continue.
4
-
5
- Current exclusion options:
6
- * Minimum browser width & height
7
- * Support for the WebAudio API
8
-
9
- ## Examples
10
-
11
- #### Exclude browsers that are not at least 800x600 pixels
12
-
13
- ```javascript
14
- jsPsych.init({
15
- timeline: exp,
16
- exclusions: {
17
- min_width: 800,
18
- min_height: 600
19
- }
20
- });
21
- ```
22
-
23
- #### Exclude browsers that do not have access to the WebAudio API
24
-
25
- ```javascript
26
- jsPsych.init({
27
- timeline: exp,
28
- exclusions: {
29
- audio: true
30
- }
31
- });
32
- ```
@@ -1,121 +0,0 @@
1
- # Experiment-wide settings
2
-
3
- There are several options that can be set when calling `jsPsych.init()` to launch the experiment.
4
-
5
- Options are specified in the object passed to `jsPsych.init`. For example, to specify a set of images to preload and the default inter-trial interval the object would contain:
6
-
7
- ```js
8
- jsPsych.init({
9
- timeline: [...],
10
- preload_images: ['img1.png', 'img2.png'],
11
- default_iti: 500
12
- });
13
- ```
14
-
15
- ## Controlling where jsPsych renders on the page
16
-
17
- By default, jsPsych will render the experiment in the `<body>` element of a page. It is possible to display the experiment in a different element (e.g., a `<div>`) by specifying the `display_element` parameter.
18
-
19
- ```html
20
- <body>
21
- <div id="jspsych-target"></div>
22
- </body>
23
- <script>
24
-
25
- // ... //
26
-
27
- jsPsych.init({
28
- timeline: [...],
29
- display_element: 'jspsych-target'
30
- })
31
- </script>
32
- ```
33
-
34
- This option is useful if the experiment needs to be rendered on a page with other content (e.g., a demo version of the experiment with annotation text), or if additional control over the display element is desired. Custom CSS rules can be applied to position, size, scale, etc. the display element.
35
-
36
- ## Experiment events
37
-
38
- Several experiment-wide events can trigger functions. This is documented in more detail on the [event-related callback functions page](callbacks.md). The events that trigger functions are:
39
-
40
- * `on_finish`: Called at the end of the experiment.
41
- * `on_trial_start`: Called at the beginning of every trial.
42
- * `on_trial_finish`: Called at the end of every trial.
43
- * `on_data_update`: Called whenever new data is added to the jsPsych data object.
44
- * `on_interaction_data_update`: Called whenever new interaction data (e.g., the subject enters or exits fullscreen mode) is added.
45
- * `on_close`: Called right before the page closes, such as when a subject closes the experiment early.
46
-
47
- ## Specify exclusion criteria
48
-
49
- Exclusion criteria can be specified based on features of the user's web browser, such as the display size and whether certain features are reported. See the page on [excluding subjects based on browser features](exclude-browser.md).
50
-
51
- ## Display a progress bar
52
-
53
- An automatic or manually updated progress bar can be displayed at the top of the screen. By default, the text next to the progress bar is "Completion Progress", but this text can be changed with the `message_progress_bar` parameter in `jsPsych.init`. See the [progress bar page](progress-bar.md) for more details.
54
-
55
- ## Preload media elements
56
-
57
- Images, audio files, and movies can be preloaded to reduce latency during the experiment. In many cases, this preloading is automatic. In certain situations, such as using a custom plugin, using [timeline variables](timeline.md#timeline-variables), or using [functions to determine which stimulus to show](trial.md#dynamic-parameters), it is necessary to provide jsPsych with a list of media elements to preload. The [media preloading](media-preloading.md) page describes this process in detail.
58
-
59
- ## Choose the method for playing audio files
60
-
61
- Specifying the `use_webaudio` parameter in `jsPsych.init()` allows you to choose whether to use the WebAudio API or HTML5 audio for playing audio files during your experiment. By default, jsPsych uses the WebAudio API to play audio files. Among other features, the WebAudio API allows for more precise measurement of response times relative to the onset of the audio.
62
-
63
- However, loading files through the WebAudio API causes errors when running an experiment offline (i.e., by double-clicking on the HTML file, rather than hosting it on a web server). This is due to the [cross-origin security policy](https://security.stackexchange.com/a/190321) implemented by web browsers. For this reason, jsPsych switches to a 'safe mode' when it detects that the webpage is running offline, and automatically uses HTML5 audio to prevent errors, even when `use_webaudio` has been explicitly set to `true`. For more information, see the section [Cross-origin requests (CORS) and safe mode](running-experiments.md#cross-origin-requests-cors-and-safe-mode) on the Running Experiments page.
64
-
65
- ```js
66
- jsPsych.init({
67
- timeline: [...],
68
- use_webaudio: false
69
- });
70
- ```
71
-
72
- ## Set the default intertrial interval
73
-
74
- By default the next trial in a timeline will begin immediately after the conclusion of the previous trial. An experiment-wide delay can be specified using the `default_iti` parameter to `jsPsych.init()`.
75
-
76
- ```js
77
- jsPsych.init({
78
- timeline: [...],
79
- default_iti: 500
80
- });
81
- ```
82
-
83
- This parameter is specified in milliseconds. A blank screen will display between each trial for the duration of the ITI.
84
-
85
- ## Specify the maximum width of the experiment
86
-
87
- The experiment will, by default, take up 100% of the display element. Usually the display element is the `<body>`, and the experiment is the full width of the screen. (This can be overridden by specifying the `display_element` parameter described above).
88
-
89
- Specifying the `experiment_width` parameter will set a maximum width for the display. The parameter is specified in pixels.
90
-
91
- ```js
92
- jsPsych.init({
93
- timeline: [...],
94
- experiment_width: 750
95
- });
96
- ```
97
-
98
- ## Specify a minimum valid response time
99
-
100
- By default, jsPsych will treat any keyboard response time as valid. However, it's possible to specify a minimum valid response time (in ms) for key presses. Any key press that is less than this value will be treated as invalid and ignored. Note that this parameter only applies to _keyboard responses_, and not to other response types such as buttons and sliders. The default value is 0.
101
-
102
- ```js
103
- // ignore any keyboard responses that are less than 100 ms
104
- jsPsych.init({
105
- timeline: [...],
106
- minimum_valid_rt: 100
107
- });
108
- ```
109
-
110
- ## Override 'safe mode' when running experiments offline
111
-
112
- By default, jsPsych switches to a 'safe mode' when it detects that the webpage is running offline (via the `file://` protocol) in order to prevent certain errors. Specifically, in safe mode, HTML5 audio is used to play audio files (even when `use_webaudio` has been explicitly set to `true`) and video preloading is disabled (both automatic and manual preloading). For more information, see the [Cross-origin requests (CORS) and safe mode](running-experiments.md#cross-origin-requests-cors-and-safe-mode) section on the Running Experiments page.
113
-
114
- It's possible to override this safe mode feature by setting the `override_safe_mode` parameter to `true` in `jsPsych.init`. This is something you might do if you've disabled certain security settings in your browser for testing purposes. This parameter has no effect when your experiment is running online (on a server), because it will be using the `http://` or `https://` protocol, which does not trigger safe mode.
115
-
116
- ```js
117
- jsPsych.init({
118
- timeline: [...],
119
- override_safe_mode: true
120
- });
121
- ```
@@ -1,36 +0,0 @@
1
- # Fullscreen Experiments
2
-
3
- You can run your experiment in fullscreen mode by using the jspsych-fullscreen plugin.
4
-
5
- ```javascript
6
- var timeline = [];
7
-
8
- timeline.push({
9
- type: 'fullscreen',
10
- fullscreen_mode: true
11
- });
12
-
13
- timeline.push({
14
- type: 'html-keyboard-response',
15
- stimulus: 'This trial will be in fullscreen mode.'
16
- });
17
-
18
- // exit fullscreen mode
19
- timeline.push({
20
- type: 'fullscreen',
21
- fullscreen_mode: false
22
- });
23
-
24
- timeline.push({
25
- type: 'html-keyboard-response',
26
- stimulus: 'This trial will NOT be in fullscreen mode.'
27
- });
28
-
29
- jsPsych.init({
30
- timeline: timeline
31
- });
32
- ```
33
-
34
- For security reasons, web browsers require that users initiate an action to launch fullscreen mode. The fullscreen plugin displays a button that the user must click to change the display to fullscreen.
35
-
36
- Safari does not support keyboard input when the browser is in fullscreen mode. Therefore, the function will not launch fullscreen mode on Safari. The experiment will ignore any trials using the fullscreen plugin in Safari.