22
33define ( [ 'jquery' , 'controllers/tableController' , 'helper/mpc' , 'alertify' , 'alertify_defaults' ] , function ( $ , tableController , mpc , alertify ) {
44
5+
56 var client = ( function ( ) {
67 var SESSION_KEY_ERROR = 'Invalid session number' ;
78 var PARTICIPATION_CODE_ERROR = 'Invalid participation code' ;
@@ -24,6 +25,74 @@ define(['jquery', 'controllers/tableController', 'helper/mpc', 'alertify', 'aler
2425 discrepancies : SEMANTIC_CELLS
2526 } ;
2627
28+
29+ let analytics = {
30+ validation_errors : { } ,
31+ mouse_positions : [ ] ,
32+ time_ms : 0 ,
33+ }
34+
35+ document . addEventListener ( 'mousemove' , handleMouseMove , false ) ;
36+ function getPos ( event ) {
37+
38+ // TODO: make sure this is consistent across browsers
39+ var height ;
40+ var width ;
41+ if ( event . pageX === null && event . clientX !== null ) {
42+ var doc = eventDoc . documentElement ;
43+ var body = eventDoc . body ;
44+
45+
46+ event . pageX = event . clientX +
47+ ( doc && doc . scrollLeft || body && body . scrollLeft || 0 ) -
48+ ( doc && doc . clientLeft || body && body . clientLeft || 0 ) ;
49+ event . pageY = event . clientY +
50+ ( doc && doc . scrollTop || body && body . scrollTop || 0 ) -
51+ ( doc && doc . clientTop || body && body . clientTop || 0 ) ;
52+ }
53+ width = window . innerWidth
54+ || document . documentElement . clientWidth
55+ || document . body . clientWidth ;
56+
57+ height = document . body . scrollHeight ;
58+ return [ event . pageX / width , event . pageY / height ] ;
59+ }
60+
61+ function handleMouseMove ( event ) {
62+ // y coord should potentially be mult. by 100
63+ // to account for difference in x, y page size
64+ var pos = getPos ( event ) ;
65+ var x = Math . floor ( pos [ 0 ] * 100 ) ;
66+ var y = Math . floor ( pos [ 1 ] * 1000 ) ;
67+ analytics [ 'mouse_positions' ] . push ( [ x , y ] ) ;
68+ }
69+
70+ let startDate = new Date ( ) ;
71+ let elapsedTime = 0 ;
72+
73+ const focus = function ( ) {
74+ startDate = new Date ( ) ;
75+ } ;
76+
77+ const blur = function ( ) {
78+ const endDate = new Date ( ) ;
79+ const spentTime = endDate . getTime ( ) - startDate . getTime ( ) ;
80+ elapsedTime += spentTime ;
81+ } ;
82+
83+ const beforeunload = function ( ) {
84+ const endDate = new Date ( ) ;
85+ const spentTime = endDate . getTime ( ) - startDate . getTime ( ) ;
86+ elapsedTime += spentTime ;
87+ analytics [ 'time_ms' ] = elapsedTime ;
88+ // elapsedTime contains the time spent on page in milliseconds
89+ } ;
90+
91+ // TODO EventListeners prolly shouldn't be in this file
92+ window . addEventListener ( 'focus' , focus ) ;
93+ window . addEventListener ( 'blur' , blur ) ;
94+ window . addEventListener ( 'beforeunload' , beforeunload ) ;
95+
2796 // TODO: create new view for alerts
2897 function error ( msg ) {
2998 alertify . alert ( '<img src="/images/cancel.png" alt="Error">Error!' , msg ) ;
@@ -170,24 +239,40 @@ define(['jquery', 'controllers/tableController', 'helper/mpc', 'alertify', 'aler
170239 var $session = $ ( '#session' ) ;
171240 if ( ! validateSessionInput ( $session , false ) ) {
172241 errors = errors . concat ( SESSION_KEY_ERROR ) ;
242+ if ( analytics [ SESSION_KEY_ERROR ] == null ) {
243+ analytics [ SESSION_KEY_ERROR ] = 0 ;
244+ }
245+ analytics [ SESSION_KEY_ERROR ] ++ ;
173246 }
174247
175248 var $participationCode = $ ( '#participation-code' ) ;
176249 if ( ! validateSessionInput ( $participationCode , false ) ) {
177250 errors = errors . concat ( PARTICIPATION_CODE_ERROR ) ;
251+ if ( analytics [ PARTICIPATION_CODE_ERROR ] == null ) {
252+ analytics [ PARTICIPATION_CODE_ERROR ] = 0 ;
253+ }
254+ analytics [ PARTICIPATION_CODE_ERROR ] ++ ;
178255 }
179256
180257 // Validate the remaining components after session and
181258 // and participation code are validated with the server.
182259 var validateRemainingComponents = function ( result ) {
183260 if ( ! result ) {
184261 errors = errors . concat ( SESSION_PARTICIPATION_CODE_SERVER_ERROR ) ;
262+ if ( analytics [ SESSION_PARTICIPATION_CODE_SERVER_ERROR ] == null ) {
263+ analytics [ SESSION_PARTICIPATION_CODE_SERVER_ERROR ] = 0 ;
264+ }
265+ analytics [ SESSION_PARTICIPATION_CODE_SERVER_ERROR ] ++ ;
185266 }
186267
187268 // Verify confirmation check box was checked
188269 var verifyChecked = $ ( '#verify' ) . is ( ':checked' ) ;
189270 if ( ! verifyChecked ) {
190271 errors = errors . concat ( UNCHECKED_ERR ) ;
272+ if ( analytics [ UNCHECKED_ERR ] == null ) {
273+ analytics [ UNCHECKED_ERR ] = 0 ;
274+ }
275+ analytics [ UNCHECKED_ERR ] ++ ;
191276 }
192277
193278 // Verify additional questions
@@ -213,6 +298,10 @@ define(['jquery', 'controllers/tableController', 'helper/mpc', 'alertify', 'aler
213298
214299 if ( ! questionsValid ) {
215300 errors = errors . concat ( ADD_QUESTIONS_ERR ) ;
301+ if ( analytics [ ADD_QUESTIONS_ERR ] == null ) {
302+ analytics [ ADD_QUESTIONS_ERR ] = 0 ;
303+ }
304+ analytics [ ADD_QUESTIONS_ERR ] ++ ;
216305 }
217306
218307 // Register semantic discrepancies validator.
@@ -321,6 +410,14 @@ define(['jquery', 'controllers/tableController', 'helper/mpc', 'alertify', 'aler
321410 var data = shares [ 'data' ] ;
322411 var mask = shares [ 'mask' ] ;
323412
413+ // For now, keeping analytic data separate from submission data
414+ // analytics is a global var, probably not that chill
415+
416+ beforeunload ( ) ; // updates time analytic
417+ var analytic_shares = mpc . secretShareValues ( analytics ) ;
418+ var analytic_data = analytic_shares [ 'data' ] ;
419+ var analytic_mask = analytic_shares [ 'mask' ] ;
420+
324421 // Correlation using modified small pairwise 'hypercubes'. (one cube for each pair of questions)
325422 // For every pair of questions, compute and encrypt the two chosen answers.
326423 var pairwise_hypercubes = { } ;
@@ -330,12 +427,12 @@ define(['jquery', 'controllers/tableController', 'helper/mpc', 'alertify', 'aler
330427 }
331428 }
332429
333- encrypt_and_send ( session , participationCode , data , mask , questions_public , pairwise_hypercubes , la ) ;
430+ encrypt_and_send ( session , participationCode , data , mask , analytic_data , analytic_mask , questions_public , pairwise_hypercubes , la ) ;
334431 }
335432
336433 var submitEntries = [ ] ;
337434
338- function encrypt_and_send ( session , participationCode , data , mask , questions_public , pairwise_hypercubes , la ) {
435+ function encrypt_and_send ( session , participationCode , data , mask , analytic_data , analytic_mask , questions_public , pairwise_hypercubes , la ) {
339436 // Get the public key to encrypt with
340437 var pkey_request = $ . ajax ( {
341438 type : 'POST' ,
0 commit comments