lanalytics-rails 0.2.9
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/Rakefile +43 -0
- data/app/assets/javascripts/lanalytics.js +17 -0
- data/app/assets/javascripts/lanalytics/lanalytics.framework.js.coffee +128 -0
- data/app/assets/javascripts/lanalytics/model/lanalytics.model.exp_api_statement.js.coffee +41 -0
- data/app/assets/javascripts/lanalytics/model/lanalytics.model.stmt_component.js.coffee +8 -0
- data/app/assets/javascripts/lanalytics/model/lanalytics.model.stmt_resource.js.coffee +16 -0
- data/app/assets/javascripts/lanalytics/model/lanalytics.model.stmt_user.js.coffee +14 -0
- data/app/assets/javascripts/lanalytics/model/lanalytics.model.stmt_verb.js.coffee +12 -0
- data/app/assets/javascripts/lanalytics/plugins/lanalytics.plugins.example.html5videoplayer.js.coffee +25 -0
- data/app/assets/javascripts/lanalytics/plugins/lanalytics.plugins.newplugintemplate.js.coffee +23 -0
- data/app/assets/javascripts/lanalytics/plugins/lanalytics.plugins.pageviewplugin.js.coffee +42 -0
- data/app/assets/javascripts/lanalytics/plugins/lanalytics.plugins.statichtmlevent.js.coffee +31 -0
- data/app/controllers/lanalytics/tracking_controller.rb +28 -0
- data/config/routes.rb +17 -0
- data/lib/lanalytics-rails.rb +10 -0
- data/lib/lanalytics/engine.rb +11 -0
- data/lib/lanalytics/lanalytics_controller_filter.rb +24 -0
- data/lib/lanalytics/version.rb +3 -0
- data/lib/tasks/lanalytics_tasks.rake +4 -0
- data/spec/controllers/tracking_controller_spec.rb +45 -0
- data/spec/dummy/README.rdoc +28 -0
- data/spec/dummy/Rakefile +6 -0
- data/spec/dummy/app/assets/javascripts/application.js +14 -0
- data/spec/dummy/app/assets/stylesheets/application.css +15 -0
- data/spec/dummy/app/controllers/application_controller.rb +9 -0
- data/spec/dummy/app/controllers/welcome_controller.rb +10 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/helpers/welcome_helper.rb +2 -0
- data/spec/dummy/app/views/layouts/application.html.erb +15 -0
- data/spec/dummy/app/views/welcome/index.html.erb +5 -0
- data/spec/dummy/bin/bundle +3 -0
- data/spec/dummy/bin/rails +4 -0
- data/spec/dummy/bin/rake +4 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +24 -0
- data/spec/dummy/config/boot.rb +5 -0
- data/spec/dummy/config/database.yml +25 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +37 -0
- data/spec/dummy/config/environments/production.rb +82 -0
- data/spec/dummy/config/environments/test.rb +39 -0
- data/spec/dummy/config/initializers/assets.rb +8 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/cookies_serializer.rb +3 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/dummy/config/initializers/inflections.rb +16 -0
- data/spec/dummy/config/initializers/mime_types.rb +4 -0
- data/spec/dummy/config/initializers/session_store.rb +3 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +23 -0
- data/spec/dummy/config/routes.rb +59 -0
- data/spec/dummy/config/secrets.yml +22 -0
- data/spec/dummy/public/404.html +67 -0
- data/spec/dummy/public/422.html +67 -0
- data/spec/dummy/public/500.html +66 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/spec/controllers/welcome_controller_spec.rb +12 -0
- data/spec/dummy/spec/helpers/welcome_helper_spec.rb +15 -0
- data/spec/dummy/spec/javascripts/support/jasmine.yml +50 -0
- data/spec/dummy/spec/views/welcome/index.html.erb_spec.rb +5 -0
- data/spec/factories/exp_api_statement_factory.rb +7 -0
- data/spec/javascripts/foo.js.coffee +8 -0
- data/spec/javascripts/lanlaytics/model/exp_api_statement_spec.js.coffee +157 -0
- data/spec/javascripts/support/jasmine.yml +50 -0
- data/spec/rails_helper.rb +50 -0
- data/spec/spec_helper.rb +98 -0
- metadata +298 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: bccfc3e4db4ed376314e8f978c475749316f58dc
|
4
|
+
data.tar.gz: 5e311be19936df67cf1028f9ed4b15694d8fa90a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: c5cde7057286068c228fd7bc03ebdb5a0ee09ab9672aab058fdadbe32b50c613820439fdaadfbd257f1bfce84ce9cff182d16fcacf4b91957cf80c61ceae10db
|
7
|
+
data.tar.gz: 218af978189ca12381fdc77a3f5d813aef704dd65a48a303f4df51e9d74d014e8a366c5ba1d5d2f8c45ffacd325e0f1a2c9e8861bf3a0c0c7cf4e2ebdbe268ff
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2014 YOURNAME
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
begin
|
2
|
+
require 'bundler/setup'
|
3
|
+
rescue LoadError
|
4
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'geminabox/rake'
|
8
|
+
Geminabox::Rake.install host: 'https://gemuser:K6c1mcRWtrTQepS6aI8HRXc7DPoRYXbG@dev.xikolo.de/gems/',
|
9
|
+
dir: '.',
|
10
|
+
namespace: 'lanalytics-rails'
|
11
|
+
|
12
|
+
require 'rdoc/task'
|
13
|
+
|
14
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
15
|
+
rdoc.rdoc_dir = 'rdoc'
|
16
|
+
rdoc.title = 'Lanalytics'
|
17
|
+
rdoc.options << '--line-numbers'
|
18
|
+
rdoc.rdoc_files.include('README.rdoc')
|
19
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
20
|
+
end
|
21
|
+
|
22
|
+
APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__)
|
23
|
+
load 'rails/tasks/engine.rake'
|
24
|
+
|
25
|
+
Bundler::GemHelper.install_tasks
|
26
|
+
|
27
|
+
require 'rspec/core'
|
28
|
+
require 'rspec/core/rake_task'
|
29
|
+
|
30
|
+
desc "Run all specs in spec directory (excluding plugin specs)"
|
31
|
+
RSpec::Core::RakeTask.new(:spec => 'app:db:test:prepare')
|
32
|
+
|
33
|
+
# require 'jasmine'
|
34
|
+
# load 'jasmine/tasks/jasmine.rake'
|
35
|
+
|
36
|
+
begin
|
37
|
+
require 'jasmine'
|
38
|
+
load 'jasmine/tasks/jasmine.rake'
|
39
|
+
rescue LoadError
|
40
|
+
task :jasmine do
|
41
|
+
abort "Jasmine is not available. In order to run jasmine, you must: (sudo) gem install jasmine"
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
// Including the files necessary for the Lanalytics service
|
2
|
+
|
3
|
+
//= require jquery
|
4
|
+
|
5
|
+
//= require ./lanalytics/model/lanalytics.model.stmt_component.js.coffee
|
6
|
+
//= require ./lanalytics/model/lanalytics.model.stmt_resource.js.coffee
|
7
|
+
//= require ./lanalytics/model/lanalytics.model.stmt_verb.js.coffee
|
8
|
+
//= require ./lanalytics/model/lanalytics.model.stmt_user.js.coffee
|
9
|
+
//= require ./lanalytics/model/lanalytics.model.exp_api_statement.js.coffee
|
10
|
+
//= require ./lanalytics/lanalytics.framework.js.coffee
|
11
|
+
//= require_directory ./lanalytics/plugins
|
12
|
+
|
13
|
+
// Files that we do not want to release
|
14
|
+
//= stub ./lanalytics/plugins/lanalytics.plugins.newplugintemplate.js.coffee
|
15
|
+
//= stub ./lanalytics/plugins/lanalytics.plugins.example.html5videoplayer.js.coffee
|
16
|
+
|
17
|
+
lanalytics = new Lanalytics.Framework();
|
@@ -0,0 +1,128 @@
|
|
1
|
+
# Turning on debug mode for development
|
2
|
+
# DEBUG = true if typeof DEBUG is "undefined"
|
3
|
+
# Turning off debug mode for development
|
4
|
+
DEBUG = false if typeof DEBUG is "undefined"
|
5
|
+
|
6
|
+
window.Lanalytics or= {};
|
7
|
+
|
8
|
+
class window.Lanalytics.Framework
|
9
|
+
|
10
|
+
constructor: ->
|
11
|
+
@eventQueue = [];
|
12
|
+
@plugins = []
|
13
|
+
|
14
|
+
addPlugin: (plugin) ->
|
15
|
+
# if plugin instanceof throw "Plugin is not a Lanalytics.Plugin
|
16
|
+
@plugins.push(plugin)
|
17
|
+
|
18
|
+
currentUser: ->
|
19
|
+
if gon?.lanalytics?.current_user?
|
20
|
+
return new Lanalytics.Model.StmtUser(gon.lanalytics.current_user.id)
|
21
|
+
else
|
22
|
+
return new Lanalytics.Model.AnonymousUser()
|
23
|
+
|
24
|
+
track: (user, verb, resource, withResult = {}, inContext = {}) ->
|
25
|
+
|
26
|
+
# If a verb is key, we will replace it with the verb that we need to transmit
|
27
|
+
verb = Lanalytics.VerbDictionary.getVerb(verb) if typeof verb is "string"
|
28
|
+
now = new Date()
|
29
|
+
|
30
|
+
experienceStmt = new Lanalytics.Model.ExpApiStatement(user, verb, resource, now, withResult, inContext)
|
31
|
+
|
32
|
+
@eventQueue.push(experienceStmt)
|
33
|
+
|
34
|
+
@processEventQueue()
|
35
|
+
|
36
|
+
console.debug("New event was tracked:", experienceStmt) if (DEBUG)
|
37
|
+
|
38
|
+
# Verb can a key or an js object
|
39
|
+
# Resource should be an object that contains the resource type and the resource key
|
40
|
+
trackCurrentUserDoing: (verb, resource, withResult = {}, inContext = {}) ->
|
41
|
+
|
42
|
+
user = @currentUser()
|
43
|
+
@track(user, verb, resource, withResult, inContext)
|
44
|
+
|
45
|
+
processEventQueue: ->
|
46
|
+
|
47
|
+
# if eventQueue < 10
|
48
|
+
|
49
|
+
experienceStatement = @eventQueue.shift()
|
50
|
+
|
51
|
+
$.ajax("/lanalytics/log", {
|
52
|
+
type: 'POST',
|
53
|
+
cache: false,
|
54
|
+
dataType: 'JSON',
|
55
|
+
data: experienceStatement.params() ,
|
56
|
+
success: (response_data, text_status, jqXHR) ->
|
57
|
+
# Do nothing for now
|
58
|
+
error: (jqXHR, textStatus, errorThrown) =>
|
59
|
+
@eventQueue.push(experienceStatement)
|
60
|
+
})
|
61
|
+
|
62
|
+
|
63
|
+
class window.Lanalytics.VerbDictionary
|
64
|
+
|
65
|
+
@_verbDict = {
|
66
|
+
"video-play": {
|
67
|
+
verb_key: "video_play",
|
68
|
+
verb_id: "http://lanalytics.open.hpi.de/expapi/verbs/video-play"
|
69
|
+
},
|
70
|
+
"video-pause": {
|
71
|
+
verb_key: "video_pause",
|
72
|
+
verb_id: "http://lanalytics.open.hpi.de/expapi/verbs/video-stop"
|
73
|
+
},
|
74
|
+
"video-seek": {
|
75
|
+
verb_key: "video_seek",
|
76
|
+
verb_id: 'http://lanalytics.open.hpi.de/expapi/verbs/quiz-submitted'
|
77
|
+
},
|
78
|
+
"video-change-speed": {
|
79
|
+
verb_key: "video_change_speed",
|
80
|
+
verb_id: 'http://lanalytics.open.hpi.de/expapi/verbs/video-change-speed'
|
81
|
+
},
|
82
|
+
"quiz-submitted": {
|
83
|
+
verb_key: "quiz_submitted",
|
84
|
+
verb_id: 'http://lanalytics.open.hpi.de/expapi/verbs/quiz-submitted'
|
85
|
+
},
|
86
|
+
"video-change-size": {
|
87
|
+
verb_key: "video_change_size",
|
88
|
+
verb_id: 'http://lanalytics.open.hpi.de/expapi/verbs/video-change-size'
|
89
|
+
},
|
90
|
+
"video-fullscreen": {
|
91
|
+
verb_key: "video_fullscreen",
|
92
|
+
verb_id: 'http://lanalytics.open.hpi.de/expapi/verbs/video-fullscreen'
|
93
|
+
}
|
94
|
+
|
95
|
+
}
|
96
|
+
|
97
|
+
@_undefinedVerbTemplate = {
|
98
|
+
verb_key: "undefined",
|
99
|
+
id: "http://lanalytics.open.hpi.de/expapi/verbs/undefined"
|
100
|
+
}
|
101
|
+
|
102
|
+
@getVerb: (id) ->
|
103
|
+
|
104
|
+
if VerbDictionary._verbDict[id]?
|
105
|
+
return new Lanalytics.Model.StmtVerb(VerbDictionary._verbDict[id].verb_key)
|
106
|
+
else
|
107
|
+
return new Lanalytics.Model.StmtVerb(id)
|
108
|
+
|
109
|
+
|
110
|
+
|
111
|
+
class window.Lanalytics.Plugin
|
112
|
+
constructor: (@lanalytics) ->
|
113
|
+
|
114
|
+
@newInstance: (lanalyticsTracker) ->
|
115
|
+
throw "This function has to be implemented in the subclass."
|
116
|
+
|
117
|
+
# The plugin are supposed to be defined under this namesspace
|
118
|
+
window.Lanalytics.Plugins or= {};
|
119
|
+
|
120
|
+
$ ->
|
121
|
+
for pluginClassName in Object.keys(Lanalytics.Plugins)
|
122
|
+
try
|
123
|
+
plugin = Lanalytics.Plugins[pluginClassName].newInstance(lanalytics)
|
124
|
+
lanalytics.addPlugin(plugin)
|
125
|
+
console.log("Lanalytics.Plugins.#{pluginClassName} found, created and added") if (DEBUG)
|
126
|
+
catch error
|
127
|
+
console.log("Lanalytics.Plugins.#{pluginClassName} found, but could not be instantiated") if (DEBUG)
|
128
|
+
console.log(error.stack) if (DEBUG)
|
@@ -0,0 +1,41 @@
|
|
1
|
+
window.Lanalytics or= {};
|
2
|
+
window.Lanalytics.Model or= {};
|
3
|
+
|
4
|
+
class window.Lanalytics.Model.ExpApiStatement
|
5
|
+
|
6
|
+
constructor: (user, verb, resource, timestamp = new Date(), @with_result = {}, @in_context = {}) ->
|
7
|
+
# ::TODO Some assertions to ensure the datamodel
|
8
|
+
throw "'user' argument cannot be nil and should be Lanalytics::Model::StmtUser" unless user instanceof Lanalytics.Model.StmtUser
|
9
|
+
@user = user
|
10
|
+
|
11
|
+
throw "'verb' argument cannot be nil and should be Lanalytics::Model::StmtVerb" unless verb instanceof Lanalytics.Model.StmtVerb
|
12
|
+
@verb = verb
|
13
|
+
|
14
|
+
throw "'resource' argument cannot be nil and should be Lanalytics::Model::StmtResource" unless resource instanceof Lanalytics.Model.StmtResource
|
15
|
+
@resource = resource
|
16
|
+
|
17
|
+
timestamp ||= DateTime.now
|
18
|
+
throw "'timestamp' argument should be DateTime or String" unless timestamp instanceof Date or timestamp instanceof String
|
19
|
+
timestamp = new Date(timestamp) if timestamp instanceof String
|
20
|
+
@timestamp = timestamp
|
21
|
+
|
22
|
+
|
23
|
+
# This is the serialization
|
24
|
+
serialize: ->
|
25
|
+
return JSON.stringify(@params)
|
26
|
+
|
27
|
+
params: ->
|
28
|
+
return {
|
29
|
+
user: @user.params(),
|
30
|
+
verb: @verb.params(),
|
31
|
+
resource: @resource.params(),
|
32
|
+
timestamp: @timestamp,
|
33
|
+
with_result: @with_result,
|
34
|
+
in_context: @in_context
|
35
|
+
}
|
36
|
+
|
37
|
+
|
38
|
+
|
39
|
+
|
40
|
+
|
41
|
+
|
@@ -0,0 +1,16 @@
|
|
1
|
+
window.Lanalytics or= {};
|
2
|
+
window.Lanalytics.Model or= {};
|
3
|
+
|
4
|
+
class window.Lanalytics.Model.StmtResource extends Lanalytics.Model.StmtComponent
|
5
|
+
|
6
|
+
constructor: (type, uuid) ->
|
7
|
+
super(type)
|
8
|
+
|
9
|
+
throw "'uuid' argument cannot be nil or empty" if !uuid? || !uuid.trim().length
|
10
|
+
@uuid = uuid.toString()
|
11
|
+
|
12
|
+
params: ->
|
13
|
+
return {
|
14
|
+
type: @type,
|
15
|
+
uuid: @uuid
|
16
|
+
}
|
@@ -0,0 +1,14 @@
|
|
1
|
+
window.Lanalytics or= {};
|
2
|
+
window.Lanalytics.Model or= {};
|
3
|
+
|
4
|
+
class window.Lanalytics.Model.StmtUser extends window.Lanalytics.Model.StmtResource
|
5
|
+
|
6
|
+
constructor: (uuid) ->
|
7
|
+
super("User", uuid)
|
8
|
+
|
9
|
+
|
10
|
+
|
11
|
+
class window.Lanalytics.Model.AnonymousUser extends window.Lanalytics.Model.StmtUser
|
12
|
+
|
13
|
+
constructor: ->
|
14
|
+
super("User", "ANONYMOUS")
|
data/app/assets/javascripts/lanalytics/plugins/lanalytics.plugins.example.html5videoplayer.js.coffee
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# This plugin was created for the xikolo-web application in order to track the events from the (custom) video player
|
2
|
+
# This is exactly the situation for which a olugin is designed for ...
|
3
|
+
class window.Lanalytics.Plugins.Html5VideoPlayerTracker extends Lanalytics.Plugin
|
4
|
+
|
5
|
+
# This is the interface method expected by Lanalytics
|
6
|
+
# Should return a valid instance of the plugin
|
7
|
+
@newInstance: (lanalytics) ->
|
8
|
+
return new Lanalytics.Plugins.Html5VideoPlayerTracker(lanalytics)
|
9
|
+
|
10
|
+
constructor: (lanalytics) ->
|
11
|
+
super(lanalytics)
|
12
|
+
this._init()
|
13
|
+
|
14
|
+
_init: ->
|
15
|
+
$(document).on("video-play", @trackVideoPlay)
|
16
|
+
$(document).on("video-pause", @trackVideoPause)
|
17
|
+
|
18
|
+
# It is important to use '=>' because then 'this' will be binded to StaticHtmlEventTracker instance (in order to access lanalytics)
|
19
|
+
trackVideoPlay: (event, videoPlayerData) =>
|
20
|
+
stmtResource = new Lanalytics.Model.StmtResource("Item", videoPlayerData.resource)
|
21
|
+
@lanalytics.track("video-play", stmtResource)
|
22
|
+
|
23
|
+
trackVideoPause: (event, videoPlayerData) =>
|
24
|
+
stmtResource = new Lanalytics.Model.StmtResource("Item", videoPlayerData.resource)
|
25
|
+
@lanalytics.trackCurrentUserDoing("video-pause", stmtResource)
|
@@ -0,0 +1,23 @@
|
|
1
|
+
|
2
|
+
class window.Lanalytics.Plugins.NewLanalyticsPlugin extends Lanalytics.Plugin
|
3
|
+
|
4
|
+
# This is the interface method expected by Lanalytics
|
5
|
+
# Should return a valid instance of the plugin
|
6
|
+
@newInstance: (lanalytics) ->
|
7
|
+
return new Lanalytics.Plugins.NewLanalyticsPlugin(lanalytics)
|
8
|
+
|
9
|
+
constructor: (lanalytics) ->
|
10
|
+
super(lanalytics)
|
11
|
+
this._init()
|
12
|
+
|
13
|
+
_init: ->
|
14
|
+
# Do something
|
15
|
+
# Register to some events in the DOM, e.g. $(document).on("video-play", @trackVideoPlay)
|
16
|
+
$(document).on("video-pause", @trackVideoPause)
|
17
|
+
|
18
|
+
# Handler for the event in the DOM
|
19
|
+
# It is important to use '=>' because then 'this' will be binded to NewLanalyticsPlugin instance (in order to access lanalytics)
|
20
|
+
# trackVideoPlay: (event, videoPlayerData) =>
|
21
|
+
# @lanalytics.trackCurrentUserDoing("video-play", {
|
22
|
+
# resource_id: videoPlayerData.resource
|
23
|
+
# })
|
@@ -0,0 +1,42 @@
|
|
1
|
+
|
2
|
+
class window.Lanalytics.Plugins.PageViewPlugin extends Lanalytics.Plugin
|
3
|
+
|
4
|
+
# This is the interface method expected by Lanalytics
|
5
|
+
# Should return a valid instance of the plugin
|
6
|
+
@newInstance: (lanalytics) ->
|
7
|
+
return new Lanalytics.Plugins.PageViewPlugin(lanalytics)
|
8
|
+
|
9
|
+
constructor: (lanalytics) ->
|
10
|
+
super(lanalytics)
|
11
|
+
this._init()
|
12
|
+
@windowLoadTimestamp = undefined
|
13
|
+
|
14
|
+
_init: ->
|
15
|
+
$(window).load(@enterPage);
|
16
|
+
|
17
|
+
# $(window).unload(@leavePage);
|
18
|
+
|
19
|
+
enterPage: (event, data) =>
|
20
|
+
@windowLoadTimestamp = @currentTime()
|
21
|
+
|
22
|
+
# Do nothing if there is no user logged in
|
23
|
+
return if @lanalytics.currentUser() instanceof Lanalytics.Model.AnonymousUser
|
24
|
+
|
25
|
+
inContext =
|
26
|
+
user_os: navigator?.platform
|
27
|
+
user_agent: navigator?.userAgent
|
28
|
+
user_app_version: navigator?.appVersion
|
29
|
+
|
30
|
+
urlPathLocation = window?.location?.pathname
|
31
|
+
stmtResource = new Lanalytics.Model.StmtResource("PAGE", urlPathLocation)
|
32
|
+
@lanalytics.trackCurrentUserDoing("viewed_page", stmtResource, {}, inContext)
|
33
|
+
|
34
|
+
|
35
|
+
# leavePage: (event, videoPlayerData) =>
|
36
|
+
# @windowLoadTimestamp
|
37
|
+
# timeOnPage = @currentTime() - @windowLoadTimestamp
|
38
|
+
# console.log(data)
|
39
|
+
# @lanalytics.trackCurrentUserDoing("observed", stmtResource)
|
40
|
+
|
41
|
+
currentTime: ->
|
42
|
+
return new Date().getTime()
|
@@ -0,0 +1,31 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
class window.Lanalytics.Plugins.StaticHtmlEventTracker extends Lanalytics.Plugin
|
4
|
+
|
5
|
+
# This is the interface method expected by Lanalytics
|
6
|
+
# Should return a valid instance of the plugin
|
7
|
+
@newInstance: (lanalytics) ->
|
8
|
+
return new Lanalytics.Plugins.StaticHtmlEventTracker(lanalytics)
|
9
|
+
|
10
|
+
constructor: (lanalytics) ->
|
11
|
+
super(lanalytics)
|
12
|
+
this._init()
|
13
|
+
|
14
|
+
_init: ->
|
15
|
+
$("*[data-lanalytics-event]").on("click", @processStaticHtmlEvent)
|
16
|
+
|
17
|
+
# It is important to use '=>' because then 'this' will be binded to StaticHtmlEventTracker instance (in order to access lanalytics)
|
18
|
+
processStaticHtmlEvent: (event) =>
|
19
|
+
|
20
|
+
clickedElement = event.target
|
21
|
+
lanalyticsParentsOfElement = $(clickedElement).parents("[data-lanalytics-resource]")
|
22
|
+
if lanalyticsParentsOfElement.length == 0
|
23
|
+
throw "No 'data-lanalytics-resource' field could be found in the parents of #{$(clickedElement).html().trim()}."
|
24
|
+
|
25
|
+
eventData = $(clickedElement).data("lanalytics-event")
|
26
|
+
stmtVerb = new Lanalytics.Model.StmtVerb(eventData['verb'])
|
27
|
+
|
28
|
+
eventResourceData = lanalyticsParentsOfElement.first().data("lanalytics-resource");
|
29
|
+
stmtResource = new Lanalytics.Model.StmtResource(eventResourceData['type'], eventResourceData['uuid'])
|
30
|
+
|
31
|
+
@lanalytics.trackCurrentUserDoing(stmtVerb, stmtResource)
|