mirror of
https://github.com/reddit-archive/reddit.git
synced 2026-01-24 06:18:08 -05:00
Fire a pixel for UI flow tracking of sub/unsubscribe.
This will allow us to collect information about how users found subreddits that they subscribe to. We can use this information to test the effectiveness of new ways of discovering and subscribing to subreddits. Specifically, when the subscribe button is clicked, for the current page and previous page: the URL, referrer URL, and the type of UI element clicked are sent. We'll use this to answer questions like: * "did clicking on gizmo A lead to users subscribing to subreddit B?" * "why did we see a spike in subscriptions to subreddit X today?"
This commit is contained in:
@@ -172,6 +172,8 @@ adtracker_url = /static/pixel.png
|
||||
adframetracker_url = /static/pixel.png
|
||||
# open redirector to bounce clicks off of on sponsored links for tracking
|
||||
clicktracker_url = /static/pixel.png
|
||||
# url to request to track interaction statistics
|
||||
uitracker_url = /static/pixel.png
|
||||
# new pixel
|
||||
newtracker_url =
|
||||
|
||||
|
||||
@@ -145,6 +145,7 @@ def js_config():
|
||||
"tracking_domain": g.tracking_domain,
|
||||
"adtracker_url": g.adtracker_url,
|
||||
"clicktracker_url": g.clicktracker_url,
|
||||
"uitracker_url": g.uitracker_url,
|
||||
"static_root": static(''),
|
||||
}
|
||||
return config
|
||||
|
||||
@@ -95,5 +95,97 @@ r.analytics = {
|
||||
thumb.attr('href', click_url)
|
||||
|
||||
thing.data('trackerFired', true)
|
||||
},
|
||||
|
||||
fireUITrackingPixel: function(action, srname) {
|
||||
var pixel = new Image()
|
||||
pixel.src = r.config.uitracker_url + '?' + $.param(
|
||||
_.extend(
|
||||
{
|
||||
'act': action,
|
||||
'sr': srname,
|
||||
'r': Math.round(Math.random() * 2147483647) // cachebuster
|
||||
},
|
||||
r.analytics.breadcrumbs.toParams()
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
r.analytics.breadcrumbs = {
|
||||
hasSessionStorage: 'sessionStorage' in window,
|
||||
selector: '.thing, .side, .sr-list, .srdrop, .tagline, .md, .organic-listing, .gadget, a, button, input',
|
||||
|
||||
init: function() {
|
||||
this.data = this._load()
|
||||
|
||||
var refreshed = this.data[0] && this.data[0]['url'] == window.location
|
||||
if (!refreshed) {
|
||||
this._storeBreadcrumb()
|
||||
}
|
||||
|
||||
$(document).delegate('a, button', 'click', $.proxy(function(ev) {
|
||||
this.storeLastClick($(ev.target))
|
||||
}, this))
|
||||
},
|
||||
|
||||
_load: function() {
|
||||
if (!this.hasSessionStorage) {
|
||||
return [{stored: false}]
|
||||
}
|
||||
|
||||
var data
|
||||
try {
|
||||
data = JSON.parse(sessionStorage['breadcrumbs'])
|
||||
} catch (e) {
|
||||
data = []
|
||||
}
|
||||
|
||||
if (!_.isArray(data)) {
|
||||
data = []
|
||||
}
|
||||
|
||||
return data
|
||||
},
|
||||
|
||||
store: function(data) {
|
||||
if (this.hasSessionStorage) {
|
||||
sessionStorage['breadcrumbs'] = JSON.stringify(this.data)
|
||||
}
|
||||
},
|
||||
|
||||
_storeBreadcrumb: function() {
|
||||
var cur = {
|
||||
'url': location.toString()
|
||||
}
|
||||
|
||||
if ('referrer' in document) {
|
||||
var referrerExternal = !document.referrer.match('^' + r.config.currentOrigin),
|
||||
referrerUnexpected = this.data[0] && document.referrer != this.data[0]['url']
|
||||
|
||||
if (referrerExternal || referrerUnexpected) {
|
||||
cur['ref'] = document.referrer
|
||||
}
|
||||
}
|
||||
|
||||
this.data.unshift(cur)
|
||||
this.data = this.data.slice(0, 2)
|
||||
this.store()
|
||||
},
|
||||
|
||||
storeLastClick: function(el) {
|
||||
this.data[0]['click'] =
|
||||
r.utils.querySelectorFromEl(el, this.selector)
|
||||
this.store()
|
||||
},
|
||||
|
||||
toParams: function() {
|
||||
params = []
|
||||
for (var i = 0; i < this.data.length; i++) {
|
||||
_.each(this.data[i], function(v, k) {
|
||||
params['c'+i+'_'+k] = v
|
||||
})
|
||||
}
|
||||
return params
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,9 @@ r.setup = function(config) {
|
||||
r.config = config
|
||||
// Set the legacy config global
|
||||
reddit = config
|
||||
|
||||
r.config.currentOrigin = location.protocol+'//'+location.host
|
||||
r.analytics.breadcrumbs.init()
|
||||
}
|
||||
|
||||
$(function() {
|
||||
|
||||
@@ -12,7 +12,7 @@ r.login = {
|
||||
endpoint = r.config.https_endpoint || ('http://'+r.config.ajax_domain),
|
||||
apiTarget = endpoint+'/api/'+action+'/'+username
|
||||
|
||||
if (this.currentOrigin == endpoint || $.support.cors) {
|
||||
if (r.config.currentOrigin == endpoint || $.support.cors) {
|
||||
var params = form.serialize()
|
||||
params.push({name:'api_type', value:'json'})
|
||||
$.ajax({
|
||||
@@ -192,7 +192,7 @@ r.ui.LoginForm.prototype = $.extend(new r.ui.Form(), {
|
||||
|
||||
_handleNetError: function(result, err, xhr) {
|
||||
r.ui.Form.prototype._handleNetError.apply(this, arguments)
|
||||
if (xhr.status == 0 && r.login.currentOrigin != r.config.https_endpoint) {
|
||||
if (xhr.status == 0 && r.config.currentOrigin != r.config.https_endpoint) {
|
||||
$('<p>').append(
|
||||
$('<a>')
|
||||
.text(r.strings.login_fallback_msg)
|
||||
|
||||
@@ -230,6 +230,8 @@ function toggle_label (elem, callback, cancelback) {
|
||||
}
|
||||
|
||||
function toggle(elem, callback, cancelback) {
|
||||
r.analytics.breadcrumbs.storeLastClick(elem)
|
||||
|
||||
var self = $(elem).parent().andSelf().filter(".option");
|
||||
var sibling = self.removeClass("active")
|
||||
.siblings().addClass("active").get(0);
|
||||
@@ -332,6 +334,7 @@ function subscribe(reddit_name) {
|
||||
}
|
||||
$.things(reddit_name).find(".entry").addClass("likes");
|
||||
$.request("subscribe", {sr: reddit_name, action: "sub"});
|
||||
r.analytics.fireUITrackingPixel("sub", reddit_name)
|
||||
}
|
||||
};
|
||||
};
|
||||
@@ -344,6 +347,7 @@ function unsubscribe(reddit_name) {
|
||||
}
|
||||
$.things(reddit_name).find(".entry").removeClass("likes");
|
||||
$.request("subscribe", {sr: reddit_name, action: "unsub"});
|
||||
r.analytics.fireUITrackingPixel("unsub", reddit_name)
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,5 +1,32 @@
|
||||
r.utils = {
|
||||
staticURL: function (item) {
|
||||
return r.config.static_root + '/' + item
|
||||
},
|
||||
|
||||
querySelectorFromEl: function(targetEl, selector) {
|
||||
return $(targetEl).parents().andSelf()
|
||||
.filter(selector || '*')
|
||||
.map(function(idx, el) {
|
||||
var parts = [],
|
||||
$el = $(el),
|
||||
elFullname = $el.data('fullname'),
|
||||
elId = $el.attr('id'),
|
||||
elClass = $el.attr('class')
|
||||
|
||||
parts.push(el.nodeName.toLowerCase())
|
||||
|
||||
if (elFullname) {
|
||||
parts.push('[data-fullname="' + elFullname + '"]')
|
||||
} else {
|
||||
if (elId) {
|
||||
parts.push('#' + elId)
|
||||
} else if (elClass) {
|
||||
parts.push('.' + _.compact(elClass.split(/\s+/)).join('.'))
|
||||
}
|
||||
}
|
||||
|
||||
return parts.join('')
|
||||
})
|
||||
.toArray().join(' ')
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user