diff --git a/r2/r2/public/static/css/reddit.less b/r2/r2/public/static/css/reddit.less
index 752e6b60f..b61707965 100755
--- a/r2/r2/public/static/css/reddit.less
+++ b/r2/r2/public/static/css/reddit.less
@@ -974,6 +974,7 @@ a.author { margin-right: 0.5em; }
right: 0px;
top: 0px;
vertical-align: top;
+ z-index: 1;
}
.organic-listing .nextprev .arrow {
@@ -1006,6 +1007,7 @@ a.author { margin-right: 0.5em; }
position: absolute;
right: -1px;
bottom: 0px;
+ z-index: 1;
}
.link.promotedlink {
diff --git a/r2/r2/public/static/js/spotlight.js b/r2/r2/public/static/js/spotlight.js
index 4dd39684c..d62ecfc40 100644
--- a/r2/r2/public/static/js/spotlight.js
+++ b/r2/r2/public/static/js/spotlight.js
@@ -9,40 +9,20 @@ r.spotlight.init = function() {
$('.organic-listing .arrow.prev').on('click', $.proxy(this, 'prev'))
$('.organic-listing .arrow.next').on('click', $.proxy(this, 'next'))
- _.each(this.link_by_camp, function(fullname, campaign) {
- if (!listing.find('[data-cid="' + campaign + '"]').length) {
- this.createStub(fullname, campaign)
- }
- }, this)
-
var selectedThing,
lastClickFullname = r.analytics.breadcrumbs.lastClickFullname(),
lastClickThing = $(lastClickFullname ? '.id-' + lastClickFullname : null)
if (lastClickThing.length && listing.has(lastClickThing).length) {
r.debug('restoring spotlight selection to last click')
- selectedThing = lastClickThing
+ selectedThing = {fullname: lastClickFullname}
} else {
selectedThing = this.chooseRandom()
}
- this.lineup = _.chain(listing.find('.thing'))
- .reject(function(el) { return selectedThing.is(el) })
+ this.lineup = _.chain(this.lineup)
+ .reject(function(el) { return _.isEqual(selectedThing, el) })
.shuffle()
.unshift(selectedThing)
- .map(function(el) {
- var fullname = $(el).data('fullname'),
- campaign = $(el).data('cid')
- if (fullname) {
- // convert things with ids to queries to handle stub replacement
- if (campaign) {
- return '[data-cid="' + campaign + '"]'
- } else {
- return '.id-' + fullname
- }
- } else {
- return el
- }
- })
.value()
this.lineup.pos = 0
@@ -53,6 +33,7 @@ r.spotlight.setup = function(links, interest_prob, promotion_prob) {
this.link_by_camp = {},
this.weights = {},
this.organics = []
+ this.lineup = []
for (var index in links) {
var link = links[index][0],
@@ -63,73 +44,101 @@ r.spotlight.setup = function(links, interest_prob, promotion_prob) {
if (is_promo) {
this.link_by_camp[campaign] = link
this.weights[campaign] = weight
+ this.lineup.push({fullname: link, campaign: campaign})
} else {
this.organics.push(link)
+ this.lineup.push({fullname: link})
}
}
+ this.lineup.push('.interestbar')
this.interest_prob = interest_prob
this.promotion_prob = promotion_prob
}
-r.spotlight.createStub = function(fullname, campaign) {
- var stub = $('
')
- .addClass('thing stub')
- .addClass('id-'+fullname)
- .attr('data-fullname', fullname)
- .attr('data-cid', campaign)
- .prependTo('.organic-listing')
-}
-
r.spotlight.chooseRandom = function() {
var listing = $('.organic-listing')
if (!_.isEmpty(this.weights)
&& Math.random() < this.promotion_prob) {
var campaign_name = this.weighted_lottery(this.weights),
link_name = this.link_by_camp[campaign_name]
- return listing.find('[data-cid="' + campaign_name + '"]')
+ return {fullname: link_name, campaign: campaign_name}
} else if (Math.random() < this.interest_prob) {
- return listing.find('.interestbar')
+ return '.interestbar'
} else {
var name = this.organics[Math.floor(Math.random() * this.organics.length)]
- return listing.find('.id-' + name)
+ return {fullname: name}
}
}
+r.spotlight._materialize = function(item) {
+ if (!item || item instanceof $ || item.promise) {
+ return item
+ }
+
+ var listing = $('.organic-listing'),
+ itemSel
+
+ if (_.isString(item)) {
+ itemSel = item
+ } else {
+ itemSel = '[data-fullname="' + item.fullname + '"]'
+ if (item.campaign) {
+ itemSel += '[data-cid="' + item.campaign + '"]'
+ }
+ }
+ var $item = listing.find(itemSel)
+
+ if ($item.length) {
+ return $item
+ } else if (item.campaign) {
+ r.debug('fetching promo %s from campaign %s', item.fullname, item.campaign)
+
+ return $.get('/api/fetch_promo', {
+ link: item.fullname,
+ campaign: item.campaign
+ }).pipe(function (data) {
+ $item = $(data)
+ $item.hide().appendTo(listing)
+ return $item
+ })
+ } else {
+ r.error('unable to locate spotlight item', itemSel, item)
+ }
+}
+
+r.spotlight._advancePos = function(dir) {
+ return (this.lineup.pos + dir + this.lineup.length) % this.lineup.length
+}
+
+r.spotlight._materializePos = function(pos) {
+ return this.lineup[pos] = this._materialize(this.lineup[pos])
+}
+
r.spotlight._advance = function(dir) {
var listing = $('.organic-listing'),
visible = listing.find('.thing:visible'),
- nextPos = (this.lineup.pos + dir + this.lineup.length) % this.lineup.length,
- next = listing.find(this.lineup[nextPos])
+ nextPos = this._advancePos(dir),
+ $next = this._materializePos(nextPos)
- if (next.hasClass('stub')) {
- var fullname = next.data('fullname'),
- campaign = next.data('cid')
- r.debug('fetching promo %s from campaign %s', fullname, campaign)
+ this.lineup.pos = nextPos
+ $.when($next).done(_.bind(function($next) {
+ if (this.lineup.pos != nextPos) {
+ // we've been passed!
+ return
+ }
- next = $.get('/api/fetch_promo', {
- link: fullname,
- campaign: campaign
- }).pipe(function (data) {
- var oldNext = $('[data-cid="' + campaign + '"]'),
- newNext = $(data)
- oldNext.replaceWith(newNext)
- return newNext
- })
- }
-
- $.when(next).done(_.bind(function(next) {
// size the rank element so that spotlight box
// items line up with the main page listing
- next.find('.rank')
+ $next
+ .find('.rank')
.width($('#siteTable .rank').width())
.end()
visible.hide()
- next.show()
+ $next.show()
- this.lineup.pos = nextPos
- this.help(next)
+ this.help($next)
}, this))
}