1 | define(["dojo/_base/lang", "dojo/_base/config", "dojo/ready", "dojo/_base/unload", |
---|
2 | "dojo/_base/sniff", "dojo/_base/xhr", "dojo/_base/json", "dojo/io-query", "dojo/io/script" |
---|
3 | ], function(lang, config, ready, unload, has, xhr, json, ioQuery, scriptIO){ |
---|
4 | /*===== |
---|
5 | ready = dojo.ready; |
---|
6 | ioQuery = dojo/io-query; |
---|
7 | scriptIO = dojo/io/script; |
---|
8 | =====*/ |
---|
9 | |
---|
10 | var Analytics = function(){ |
---|
11 | // summary: TODOC |
---|
12 | // where we store data until we're ready to send it off. |
---|
13 | // |
---|
14 | //the data queue; |
---|
15 | this._data = []; |
---|
16 | |
---|
17 | //id of messages for this session/page |
---|
18 | this._id = 1; |
---|
19 | |
---|
20 | //some default values |
---|
21 | this.sendInterval = config["sendInterval"] || 5000; |
---|
22 | this.inTransitRetry = config["inTransitRetry"] || 200; |
---|
23 | this.dataUrl = config["analyticsUrl"] || require.toUrl("dojox/analytics/logger/dojoxAnalytics.php"); |
---|
24 | this.sendMethod = config["sendMethod"] || "xhrPost"; |
---|
25 | this.maxRequestSize = has("ie") ? 2000 : config["maxRequestSize"] || 4000; |
---|
26 | |
---|
27 | //while we can go ahead and being logging as soon as this constructor is completed |
---|
28 | //we're not going to schedule pushing data to the server until after the page |
---|
29 | //has completed loading |
---|
30 | ready(this, "schedulePusher"); |
---|
31 | unload.addOnUnload(this, "pushData", true); |
---|
32 | }; |
---|
33 | |
---|
34 | lang.extend(Analytics, { |
---|
35 | schedulePusher: function(/* Int */interval){ |
---|
36 | // summary: Schedule the data pushing routines to happen in interval ms |
---|
37 | setTimeout(lang.hitch(this, "checkData"), interval || this.sendInterval); |
---|
38 | }, |
---|
39 | |
---|
40 | addData: function(dataType, data){ |
---|
41 | // summary: |
---|
42 | // add data to the queue. Will be pusshed to the server on the next |
---|
43 | // data push |
---|
44 | |
---|
45 | if(arguments.length > 2){ |
---|
46 | // FIXME: var c = dojo._toArray(arguments) ? |
---|
47 | var c = []; |
---|
48 | for(var i = 1; i < arguments.length; i++){ |
---|
49 | c.push(arguments[i]); |
---|
50 | } |
---|
51 | data = c; |
---|
52 | } |
---|
53 | |
---|
54 | this._data.push({ plugin: dataType, data: data }); |
---|
55 | }, |
---|
56 | |
---|
57 | checkData: function(){ |
---|
58 | // summary: TODOC? |
---|
59 | if(this._inTransit){ |
---|
60 | this.schedulePusher(this.inTransitRetry); |
---|
61 | return; |
---|
62 | } |
---|
63 | |
---|
64 | if(this.pushData()){ return; } |
---|
65 | this.schedulePusher(); |
---|
66 | }, |
---|
67 | |
---|
68 | pushData: function(){ |
---|
69 | // summary: |
---|
70 | // pushes data to the server if any exists. If a push is done, return |
---|
71 | // the deferred after hooking up completion callbacks. If there is no data |
---|
72 | // to be pushed, return false; |
---|
73 | if(this._data.length){ |
---|
74 | //clear the queue |
---|
75 | this._inTransit = this._data; |
---|
76 | this._data = []; |
---|
77 | var def; |
---|
78 | switch(this.sendMethod){ |
---|
79 | case "script": |
---|
80 | def = scriptIO.get({ |
---|
81 | url: this.getQueryPacket(), |
---|
82 | preventCache: 1, |
---|
83 | callbackParamName: "callback" |
---|
84 | }); |
---|
85 | break; |
---|
86 | case "xhrPost": |
---|
87 | default: |
---|
88 | def = xhr.post({ |
---|
89 | url:this.dataUrl, |
---|
90 | content:{ |
---|
91 | id: this._id++, |
---|
92 | data: json.toJson(this._inTransit) |
---|
93 | } |
---|
94 | }); |
---|
95 | break; |
---|
96 | } |
---|
97 | def.addCallback(this, "onPushComplete"); |
---|
98 | return def; |
---|
99 | } |
---|
100 | return false; |
---|
101 | }, |
---|
102 | |
---|
103 | getQueryPacket: function(){ |
---|
104 | // summary: TODOC |
---|
105 | while(true){ |
---|
106 | var content = { |
---|
107 | id: this._id++, |
---|
108 | data: json.toJson(this._inTransit) |
---|
109 | }; |
---|
110 | |
---|
111 | //FIXME would like a much better way to get the query down to length |
---|
112 | var query = this.dataUrl + '?' + ioQuery.objectToQuery(content); |
---|
113 | if(query.length > this.maxRequestSize){ |
---|
114 | this._data.unshift(this._inTransit.pop()); |
---|
115 | this._split = 1; |
---|
116 | }else{ |
---|
117 | return query; |
---|
118 | } |
---|
119 | } |
---|
120 | }, |
---|
121 | |
---|
122 | onPushComplete: function(results){ |
---|
123 | // summary: |
---|
124 | // If our data push was successfully, remove the _inTransit data and schedule the next |
---|
125 | // parser run. |
---|
126 | if(this._inTransit){ |
---|
127 | delete this._inTransit; |
---|
128 | } |
---|
129 | |
---|
130 | if(this._data.length > 0){ |
---|
131 | this.schedulePusher(this.inTransitRetry); |
---|
132 | }else{ |
---|
133 | this.schedulePusher(); |
---|
134 | } |
---|
135 | } |
---|
136 | }); |
---|
137 | |
---|
138 | //create the analytics singleton |
---|
139 | return lang.setObject("dojox.analytics",new Analytics()); |
---|
140 | }); |
---|