From ac501a354f5843f28dec4092ac0ced557336b009 Mon Sep 17 00:00:00 2001 From: Paul Sharpe Date: Sun, 7 May 2017 17:27:25 +0100 Subject: [PATCH 1/3] Read pages until timeout. --- .../poldrack_plugins/jspsych-reading.js | 193 ++++++++++++++++++ 1 file changed, 193 insertions(+) create mode 100644 static/js/jspsych/poldrack_plugins/jspsych-reading.js diff --git a/static/js/jspsych/poldrack_plugins/jspsych-reading.js b/static/js/jspsych/poldrack_plugins/jspsych-reading.js new file mode 100644 index 0000000..d5d481b --- /dev/null +++ b/static/js/jspsych/poldrack_plugins/jspsych-reading.js @@ -0,0 +1,193 @@ +/* Based on jspsych-text.js + * + * Display HTML text with navigation and timeout. + * + */ + +jsPsych.plugins.reading = (function() { + + var plugin = {}; + + plugin.trial = function(display_element, trial) { + + trial.key_forward = trial.key_forward || 'rightarrow'; + trial.key_backward = trial.key_backward || 'leftarrow'; + trial.allow_backward = (typeof trial.allow_backward === 'undefined') ? true : trial.allow_backward; + trial.allow_keys = (typeof trial.allow_keys === 'undefined') ? true : trial.allow_keys; + trial.show_clickable_nav = (typeof trial.show_clickable_nav === 'undefined') ? false : trial.show_clickable_nav; + + // if any trial variables are functions + // this evaluates the function and replaces + // it with the output of the function + trial = jsPsych.pluginAPI.evaluateFunctionParameters(trial); + + var current_page = 0; + + var view_history = []; + + var start_time = (new Date()).getTime(); + + var last_page_update_time = start_time; + + function show_current_page() { + display_element.html(trial.pages[current_page]); + + if (trial.show_clickable_nav) { + + var nav_html = "
"; + if (current_page != 0 && trial.allow_backward) { + nav_html += ""; + } + nav_html += "
" + + nav_html += "" + + display_element.append(nav_html); + + if (current_page != 0 && trial.allow_backward) { + $('#jspsych-reading-back').on('click', function() { + clear_button_handlers(); + back(); + }); + } + + $('#jspsych-reading-next').on('click', function() { + clear_button_handlers(); + next(); + }); + } + } + + function clear_button_handlers() { + $('#jspsych-reading-next').off('click'); + $('#jspsych-reading-back').off('click'); + } + + function next() { + // FIXME: page count :) + + add_current_page_to_view_history() + + current_page++; + + // if done, finish up... + if (current_page >= trial.pages.length) { + endTrial(); + } else { + show_current_page(); + } + + } + + function back() { + + add_current_page_to_view_history() + + current_page--; + + show_current_page(); + } + + function add_current_page_to_view_history() { + + var current_time = (new Date()).getTime(); + + var page_view_time = current_time - last_page_update_time; + + view_history.push({ + page_index: current_page, + viewing_time: page_view_time + }); + + last_page_update_time = current_time; + } + + function endTrial() { + + if (trial.allow_keys) { + jsPsych.pluginAPI.cancelKeyboardResponse(keyboard_listener); + } + + display_element.html(''); + + var trial_data = { + "view_history": JSON.stringify(view_history), + "rt": (new Date()).getTime() - start_time + }; + + jsPsych.finishTrial(trial_data); + } + + var after_response = function(info) { + + // have to reinitialize this instead of letting it persist to prevent accidental skips of pages by holding down keys too long + keyboard_listener = jsPsych.pluginAPI.getKeyboardResponse({ + callback_function: after_response, + valid_responses: [trial.key_forward, trial.key_backward], + rt_method: 'date', + persist: false, + allow_held_key: false + }); + // check if key is forwards or backwards and update page + if (info.key === trial.key_backward || info.key === jsPsych.pluginAPI.convertKeyCharacterToKeyCode(trial.key_backward)) { + if (current_page !== 0 && trial.allow_backward) { + back(); + } + } + + if (info.key === trial.key_forward || info.key === jsPsych.pluginAPI.convertKeyCharacterToKeyCode(trial.key_forward)) { + next(); + } + + }; + + var end_trial = function(info) { + clearTimeout(t1); + display_element.html(''); // clear the display + + if (typeof keyboardListener !== 'undefined') { + jsPsych.pluginAPI.cancelKeyboardResponse(keyboardListener); + } + + var block_duration = trial.timing_response + if (info.rt != -1) { + block_duration = info.rt + } + + // FIXME: store furthest page read? + var trialdata = { + "text": trial.text, + "rt": info.rt, + "key_press": info.key, + "block_duration": block_duration, + "timing_post_trial": trial.timing_post_trial + } + + jsPsych.finishTrial(trialdata); + + }; + + show_current_page(); + + if (trial.allow_keys) { + var keyboard_listener = jsPsych.pluginAPI.getKeyboardResponse({ + callback_function: after_response, + valid_responses: [trial.key_forward, trial.key_backward], + rt_method: 'date', + persist: false + }); + } + + // end trial if time limit is set + if (trial.timing_response > 0) { + var t1 = setTimeout(function() { + end_trial({ + key: -1, + rt: -1 + }); + }, trial.timing_response); + } + }; + + return plugin; +})(); \ No newline at end of file From 718384d6bd46829fc51ef18a3bca932fe8ce576b Mon Sep 17 00:00:00 2001 From: Paul Sharpe Date: Mon, 8 May 2017 10:36:16 +0100 Subject: [PATCH 2/3] Store furthest page read. --- static/js/jspsych/poldrack_plugins/jspsych-reading.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/static/js/jspsych/poldrack_plugins/jspsych-reading.js b/static/js/jspsych/poldrack_plugins/jspsych-reading.js index d5d481b..34bd1e3 100644 --- a/static/js/jspsych/poldrack_plugins/jspsych-reading.js +++ b/static/js/jspsych/poldrack_plugins/jspsych-reading.js @@ -22,6 +22,7 @@ jsPsych.plugins.reading = (function() { trial = jsPsych.pluginAPI.evaluateFunctionParameters(trial); var current_page = 0; + var furthest_page = current_page; var view_history = []; @@ -69,6 +70,7 @@ jsPsych.plugins.reading = (function() { add_current_page_to_view_history() current_page++; + furthest_page = current_page; // if done, finish up... if (current_page >= trial.pages.length) { @@ -160,7 +162,8 @@ jsPsych.plugins.reading = (function() { "rt": info.rt, "key_press": info.key, "block_duration": block_duration, - "timing_post_trial": trial.timing_post_trial + "timing_post_trial": trial.timing_post_trial, + "furthest_page": furthest_page } jsPsych.finishTrial(trialdata); From ada8bbf9c7d45b3e7d45cbf9e4273f62a8439016 Mon Sep 17 00:00:00 2001 From: Paul Sharpe Date: Tue, 9 May 2017 10:33:30 +0100 Subject: [PATCH 3/3] FIX: Intermittent trial termination. Silly copy-paste fail which introduced a second end trial function, resulting in 2 concurrent keyboard listeners (I think). --- .../poldrack_plugins/jspsych-reading.js | 45 +++++-------------- 1 file changed, 11 insertions(+), 34 deletions(-) diff --git a/static/js/jspsych/poldrack_plugins/jspsych-reading.js b/static/js/jspsych/poldrack_plugins/jspsych-reading.js index 34bd1e3..2364667 100644 --- a/static/js/jspsych/poldrack_plugins/jspsych-reading.js +++ b/static/js/jspsych/poldrack_plugins/jspsych-reading.js @@ -70,12 +70,13 @@ jsPsych.plugins.reading = (function() { add_current_page_to_view_history() current_page++; - furthest_page = current_page; + // if done, finish up... if (current_page >= trial.pages.length) { - endTrial(); + end_trial(); } else { + furthest_page = current_page; show_current_page(); } @@ -104,22 +105,6 @@ jsPsych.plugins.reading = (function() { last_page_update_time = current_time; } - function endTrial() { - - if (trial.allow_keys) { - jsPsych.pluginAPI.cancelKeyboardResponse(keyboard_listener); - } - - display_element.html(''); - - var trial_data = { - "view_history": JSON.stringify(view_history), - "rt": (new Date()).getTime() - start_time - }; - - jsPsych.finishTrial(trial_data); - } - var after_response = function(info) { // have to reinitialize this instead of letting it persist to prevent accidental skips of pages by holding down keys too long @@ -140,34 +125,29 @@ jsPsych.plugins.reading = (function() { if (info.key === trial.key_forward || info.key === jsPsych.pluginAPI.convertKeyCharacterToKeyCode(trial.key_forward)) { next(); } - }; - var end_trial = function(info) { + function end_trial() { clearTimeout(t1); display_element.html(''); // clear the display - if (typeof keyboardListener !== 'undefined') { - jsPsych.pluginAPI.cancelKeyboardResponse(keyboardListener); + if (trial.allow_keys) { + jsPsych.pluginAPI.cancelKeyboardResponse(keyboard_listener); } + // FIXME: this is always the maximum (rather than actual) duration var block_duration = trial.timing_response - if (info.rt != -1) { - block_duration = info.rt - } - // FIXME: store furthest page read? var trialdata = { "text": trial.text, - "rt": info.rt, - "key_press": info.key, + "rt": (new Date()).getTime() - start_time, "block_duration": block_duration, "timing_post_trial": trial.timing_post_trial, - "furthest_page": furthest_page + "furthest_page": furthest_page, + "view_history": JSON.stringify(view_history) } jsPsych.finishTrial(trialdata); - }; show_current_page(); @@ -184,10 +164,7 @@ jsPsych.plugins.reading = (function() { // end trial if time limit is set if (trial.timing_response > 0) { var t1 = setTimeout(function() { - end_trial({ - key: -1, - rt: -1 - }); + end_trial(); }, trial.timing_response); } };